2019-01-28 13:59:04 +00:00
|
|
|
// Copyright 2019 the V8 project authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
2019-05-17 12:13:44 +00:00
|
|
|
#include "src/api/api-inl.h"
|
2019-01-28 13:59:04 +00:00
|
|
|
#include "test/cctest/wasm/wasm-atomics-utils.h"
|
|
|
|
#include "test/common/wasm/test-signatures.h"
|
|
|
|
#include "test/common/wasm/wasm-macro-gen.h"
|
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
|
|
|
namespace wasm {
|
|
|
|
namespace test_run_wasm_exceptions {
|
|
|
|
|
2020-05-05 10:23:41 +00:00
|
|
|
WASM_COMPILED_EXEC_TEST(TryCatchThrow) {
|
2019-01-28 13:59:04 +00:00
|
|
|
TestSignatures sigs;
|
|
|
|
EXPERIMENTAL_FLAG_SCOPE(eh);
|
|
|
|
WasmRunner<uint32_t, uint32_t> r(execution_tier);
|
|
|
|
uint32_t except = r.builder().AddException(sigs.v_v());
|
|
|
|
constexpr uint32_t kResult0 = 23;
|
|
|
|
constexpr uint32_t kResult1 = 42;
|
|
|
|
|
2019-01-30 11:38:56 +00:00
|
|
|
// Build the main test function.
|
2019-01-28 13:59:04 +00:00
|
|
|
BUILD(r, WASM_TRY_CATCH_T(kWasmI32,
|
|
|
|
WASM_STMTS(WASM_I32V(kResult1),
|
|
|
|
WASM_IF(WASM_I32_EQZ(WASM_GET_LOCAL(0)),
|
|
|
|
WASM_THROW(except))),
|
|
|
|
WASM_STMTS(WASM_DROP, WASM_I32V(kResult0))));
|
|
|
|
|
|
|
|
// Need to call through JS to allow for creation of stack traces.
|
2019-01-28 16:09:28 +00:00
|
|
|
r.CheckCallViaJS(kResult0, 0);
|
|
|
|
r.CheckCallViaJS(kResult1, 1);
|
2019-01-28 13:59:04 +00:00
|
|
|
}
|
|
|
|
|
2020-05-05 10:23:41 +00:00
|
|
|
WASM_COMPILED_EXEC_TEST(TryCatchCallDirect) {
|
2019-01-30 11:38:56 +00:00
|
|
|
TestSignatures sigs;
|
|
|
|
EXPERIMENTAL_FLAG_SCOPE(eh);
|
|
|
|
WasmRunner<uint32_t, uint32_t> r(execution_tier);
|
|
|
|
uint32_t except = r.builder().AddException(sigs.v_v());
|
|
|
|
constexpr uint32_t kResult0 = 23;
|
|
|
|
constexpr uint32_t kResult1 = 42;
|
|
|
|
|
|
|
|
// Build a throwing helper function.
|
2019-01-30 15:06:42 +00:00
|
|
|
WasmFunctionCompiler& throw_func = r.NewFunction(sigs.i_ii());
|
2019-01-30 11:38:56 +00:00
|
|
|
BUILD(throw_func, WASM_THROW(except));
|
|
|
|
|
|
|
|
// Build the main test function.
|
|
|
|
BUILD(r, WASM_TRY_CATCH_T(
|
|
|
|
kWasmI32,
|
2019-01-30 15:06:42 +00:00
|
|
|
WASM_STMTS(WASM_I32V(kResult1),
|
|
|
|
WASM_IF(WASM_I32_EQZ(WASM_GET_LOCAL(0)),
|
|
|
|
WASM_STMTS(WASM_CALL_FUNCTION(
|
|
|
|
throw_func.function_index(),
|
|
|
|
WASM_I32V(7), WASM_I32V(9)),
|
|
|
|
WASM_DROP))),
|
2019-01-30 11:38:56 +00:00
|
|
|
WASM_STMTS(WASM_DROP, WASM_I32V(kResult0))));
|
|
|
|
|
|
|
|
// Need to call through JS to allow for creation of stack traces.
|
2019-01-30 15:17:20 +00:00
|
|
|
r.CheckCallViaJS(kResult0, 0);
|
2019-01-30 11:38:56 +00:00
|
|
|
r.CheckCallViaJS(kResult1, 1);
|
|
|
|
}
|
|
|
|
|
2020-05-05 10:23:41 +00:00
|
|
|
WASM_COMPILED_EXEC_TEST(TryCatchCallIndirect) {
|
2019-01-30 11:38:56 +00:00
|
|
|
TestSignatures sigs;
|
|
|
|
EXPERIMENTAL_FLAG_SCOPE(eh);
|
|
|
|
WasmRunner<uint32_t, uint32_t> r(execution_tier);
|
|
|
|
uint32_t except = r.builder().AddException(sigs.v_v());
|
|
|
|
constexpr uint32_t kResult0 = 23;
|
|
|
|
constexpr uint32_t kResult1 = 42;
|
|
|
|
|
|
|
|
// Build a throwing helper function.
|
2019-01-30 15:06:42 +00:00
|
|
|
WasmFunctionCompiler& throw_func = r.NewFunction(sigs.i_ii());
|
2019-01-30 11:38:56 +00:00
|
|
|
BUILD(throw_func, WASM_THROW(except));
|
2019-05-22 14:04:36 +00:00
|
|
|
byte sig_index = r.builder().AddSignature(sigs.i_ii());
|
2019-01-30 11:38:56 +00:00
|
|
|
throw_func.SetSigIndex(0);
|
|
|
|
|
|
|
|
// Add an indirect function table.
|
|
|
|
uint16_t indirect_function_table[] = {
|
|
|
|
static_cast<uint16_t>(throw_func.function_index())};
|
|
|
|
r.builder().AddIndirectFunctionTable(indirect_function_table,
|
|
|
|
arraysize(indirect_function_table));
|
|
|
|
|
|
|
|
// Build the main test function.
|
2019-11-28 13:55:59 +00:00
|
|
|
BUILD(r,
|
|
|
|
WASM_TRY_CATCH_T(
|
|
|
|
kWasmI32,
|
|
|
|
WASM_STMTS(WASM_I32V(kResult1),
|
|
|
|
WASM_IF(WASM_I32_EQZ(WASM_GET_LOCAL(0)),
|
|
|
|
WASM_STMTS(WASM_CALL_INDIRECT(
|
|
|
|
sig_index, WASM_I32V(7),
|
|
|
|
WASM_I32V(9), WASM_GET_LOCAL(0)),
|
|
|
|
WASM_DROP))),
|
|
|
|
WASM_STMTS(WASM_DROP, WASM_I32V(kResult0))));
|
2019-01-30 11:38:56 +00:00
|
|
|
|
|
|
|
// Need to call through JS to allow for creation of stack traces.
|
2019-01-30 15:17:20 +00:00
|
|
|
r.CheckCallViaJS(kResult0, 0);
|
2019-01-30 11:38:56 +00:00
|
|
|
r.CheckCallViaJS(kResult1, 1);
|
|
|
|
}
|
|
|
|
|
2020-05-05 10:23:41 +00:00
|
|
|
WASM_COMPILED_EXEC_TEST(TryCatchCallExternal) {
|
2019-01-30 11:38:56 +00:00
|
|
|
TestSignatures sigs;
|
|
|
|
EXPERIMENTAL_FLAG_SCOPE(eh);
|
|
|
|
HandleScope scope(CcTest::InitIsolateOnce());
|
|
|
|
const char* source = "(function() { throw 'ball'; })";
|
|
|
|
Handle<JSFunction> js_function =
|
|
|
|
Handle<JSFunction>::cast(v8::Utils::OpenHandle(
|
|
|
|
*v8::Local<v8::Function>::Cast(CompileRun(source))));
|
2019-01-30 15:06:42 +00:00
|
|
|
ManuallyImportedJSFunction import = {sigs.i_ii(), js_function};
|
2019-01-30 11:38:56 +00:00
|
|
|
WasmRunner<uint32_t, uint32_t> r(execution_tier, &import);
|
|
|
|
constexpr uint32_t kResult0 = 23;
|
|
|
|
constexpr uint32_t kResult1 = 42;
|
|
|
|
constexpr uint32_t kJSFunc = 0;
|
|
|
|
|
|
|
|
// Build the main test function.
|
2019-01-30 15:06:42 +00:00
|
|
|
BUILD(r, WASM_TRY_CATCH_T(
|
|
|
|
kWasmI32,
|
|
|
|
WASM_STMTS(
|
|
|
|
WASM_I32V(kResult1),
|
|
|
|
WASM_IF(WASM_I32_EQZ(WASM_GET_LOCAL(0)),
|
|
|
|
WASM_STMTS(WASM_CALL_FUNCTION(kJSFunc, WASM_I32V(7),
|
|
|
|
WASM_I32V(9)),
|
|
|
|
WASM_DROP))),
|
|
|
|
WASM_STMTS(WASM_DROP, WASM_I32V(kResult0))));
|
2019-01-31 13:35:57 +00:00
|
|
|
|
|
|
|
// Need to call through JS to allow for creation of stack traces.
|
|
|
|
r.CheckCallViaJS(kResult0, 0);
|
|
|
|
r.CheckCallViaJS(kResult1, 1);
|
|
|
|
}
|
|
|
|
|
2019-02-19 14:54:45 +00:00
|
|
|
namespace {
|
|
|
|
|
2020-03-23 12:56:45 +00:00
|
|
|
void TestTrapNotCaught(byte* code, size_t code_size,
|
|
|
|
ExecutionTier execution_tier) {
|
2019-02-07 10:02:06 +00:00
|
|
|
TestSignatures sigs;
|
|
|
|
EXPERIMENTAL_FLAG_SCOPE(eh);
|
2020-03-23 12:56:45 +00:00
|
|
|
WasmRunner<uint32_t> r(execution_tier, nullptr, "main",
|
|
|
|
kRuntimeExceptionSupport);
|
2019-02-19 14:54:45 +00:00
|
|
|
r.builder().AddMemory(kWasmPageSize);
|
2020-03-23 12:56:45 +00:00
|
|
|
constexpr uint32_t kResultSuccess = 23;
|
|
|
|
constexpr uint32_t kResultCaught = 47;
|
2019-02-07 10:02:06 +00:00
|
|
|
|
|
|
|
// Build a trapping helper function.
|
|
|
|
WasmFunctionCompiler& trap_func = r.NewFunction(sigs.i_ii());
|
2019-02-19 14:54:45 +00:00
|
|
|
trap_func.Build(code, code + code_size);
|
2019-02-07 10:02:06 +00:00
|
|
|
|
|
|
|
// Build the main test function.
|
|
|
|
BUILD(r, WASM_TRY_CATCH_T(
|
|
|
|
kWasmI32,
|
2020-03-23 12:56:45 +00:00
|
|
|
WASM_STMTS(WASM_I32V(kResultSuccess),
|
|
|
|
WASM_CALL_FUNCTION(trap_func.function_index(),
|
|
|
|
WASM_I32V(7), WASM_I32V(9)),
|
|
|
|
WASM_DROP),
|
|
|
|
WASM_STMTS(WASM_DROP, WASM_I32V(kResultCaught))));
|
2019-02-07 10:02:06 +00:00
|
|
|
|
|
|
|
// Need to call through JS to allow for creation of stack traces.
|
2020-03-23 12:56:45 +00:00
|
|
|
r.CheckCallViaJSTraps();
|
2019-02-07 10:02:06 +00:00
|
|
|
}
|
|
|
|
|
2019-02-19 14:54:45 +00:00
|
|
|
} // namespace
|
|
|
|
|
2020-05-05 10:23:41 +00:00
|
|
|
WASM_COMPILED_EXEC_TEST(TryCatchTrapUnreachable) {
|
2019-02-19 14:54:45 +00:00
|
|
|
byte code[] = {WASM_UNREACHABLE};
|
2020-03-23 12:56:45 +00:00
|
|
|
TestTrapNotCaught(code, arraysize(code), execution_tier);
|
2019-02-19 14:54:45 +00:00
|
|
|
}
|
|
|
|
|
2020-05-05 10:23:41 +00:00
|
|
|
WASM_COMPILED_EXEC_TEST(TryCatchTrapMemOutOfBounds) {
|
2019-02-19 14:54:45 +00:00
|
|
|
byte code[] = {WASM_LOAD_MEM(MachineType::Int32(), WASM_I32V_1(-1))};
|
2020-03-23 12:56:45 +00:00
|
|
|
TestTrapNotCaught(code, arraysize(code), execution_tier);
|
2019-02-19 14:54:45 +00:00
|
|
|
}
|
|
|
|
|
2020-05-05 10:23:41 +00:00
|
|
|
WASM_COMPILED_EXEC_TEST(TryCatchTrapDivByZero) {
|
2019-02-19 14:54:45 +00:00
|
|
|
byte code[] = {WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_I32V_1(0))};
|
2020-03-23 12:56:45 +00:00
|
|
|
TestTrapNotCaught(code, arraysize(code), execution_tier);
|
2019-02-19 14:54:45 +00:00
|
|
|
}
|
|
|
|
|
2020-05-05 10:23:41 +00:00
|
|
|
WASM_COMPILED_EXEC_TEST(TryCatchTrapRemByZero) {
|
2019-02-19 14:54:45 +00:00
|
|
|
byte code[] = {WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_I32V_1(0))};
|
2020-03-23 12:56:45 +00:00
|
|
|
TestTrapNotCaught(code, arraysize(code), execution_tier);
|
2019-02-19 14:54:45 +00:00
|
|
|
}
|
|
|
|
|
2019-01-28 13:59:04 +00:00
|
|
|
} // namespace test_run_wasm_exceptions
|
|
|
|
} // namespace wasm
|
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|