Line data Source code
1 : // Copyright 2019 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/api-inl.h"
6 : #include "test/cctest/wasm/wasm-atomics-utils.h"
7 : #include "test/common/wasm/test-signatures.h"
8 : #include "test/common/wasm/wasm-macro-gen.h"
9 :
10 : namespace v8 {
11 : namespace internal {
12 : namespace wasm {
13 : namespace test_run_wasm_exceptions {
14 :
15 25899 : WASM_EXEC_TEST(TryCatchThrow) {
16 12 : TestSignatures sigs;
17 : EXPERIMENTAL_FLAG_SCOPE(eh);
18 24 : WasmRunner<uint32_t, uint32_t> r(execution_tier);
19 12 : uint32_t except = r.builder().AddException(sigs.v_v());
20 : constexpr uint32_t kResult0 = 23;
21 : constexpr uint32_t kResult1 = 42;
22 :
23 : // Build the main test function.
24 12 : BUILD(r, WASM_TRY_CATCH_T(kWasmI32,
25 : WASM_STMTS(WASM_I32V(kResult1),
26 : WASM_IF(WASM_I32_EQZ(WASM_GET_LOCAL(0)),
27 : WASM_THROW(except))),
28 : WASM_STMTS(WASM_DROP, WASM_I32V(kResult0))));
29 :
30 : // Need to call through JS to allow for creation of stack traces.
31 12 : r.CheckCallViaJS(kResult0, 0);
32 12 : r.CheckCallViaJS(kResult1, 1);
33 12 : }
34 :
35 25899 : WASM_EXEC_TEST(TryCatchCallDirect) {
36 12 : TestSignatures sigs;
37 : EXPERIMENTAL_FLAG_SCOPE(eh);
38 24 : WasmRunner<uint32_t, uint32_t> r(execution_tier);
39 12 : uint32_t except = r.builder().AddException(sigs.v_v());
40 : constexpr uint32_t kResult0 = 23;
41 : constexpr uint32_t kResult1 = 42;
42 :
43 : // Build a throwing helper function.
44 24 : WasmFunctionCompiler& throw_func = r.NewFunction(sigs.i_ii());
45 12 : BUILD(throw_func, WASM_THROW(except));
46 :
47 : // Build the main test function.
48 24 : BUILD(r, WASM_TRY_CATCH_T(
49 : kWasmI32,
50 : WASM_STMTS(WASM_I32V(kResult1),
51 : WASM_IF(WASM_I32_EQZ(WASM_GET_LOCAL(0)),
52 : WASM_STMTS(WASM_CALL_FUNCTION(
53 : throw_func.function_index(),
54 : WASM_I32V(7), WASM_I32V(9)),
55 : WASM_DROP))),
56 : WASM_STMTS(WASM_DROP, WASM_I32V(kResult0))));
57 :
58 : // Need to call through JS to allow for creation of stack traces.
59 12 : r.CheckCallViaJS(kResult0, 0);
60 12 : r.CheckCallViaJS(kResult1, 1);
61 12 : }
62 :
63 25899 : WASM_EXEC_TEST(TryCatchCallIndirect) {
64 12 : TestSignatures sigs;
65 : EXPERIMENTAL_FLAG_SCOPE(eh);
66 24 : WasmRunner<uint32_t, uint32_t> r(execution_tier);
67 12 : uint32_t except = r.builder().AddException(sigs.v_v());
68 : constexpr uint32_t kResult0 = 23;
69 : constexpr uint32_t kResult1 = 42;
70 :
71 : // Build a throwing helper function.
72 36 : WasmFunctionCompiler& throw_func = r.NewFunction(sigs.i_ii());
73 12 : BUILD(throw_func, WASM_THROW(except));
74 12 : r.builder().AddSignature(sigs.i_ii());
75 : throw_func.SetSigIndex(0);
76 :
77 : // Add an indirect function table.
78 : uint16_t indirect_function_table[] = {
79 12 : static_cast<uint16_t>(throw_func.function_index())};
80 : r.builder().AddIndirectFunctionTable(indirect_function_table,
81 12 : arraysize(indirect_function_table));
82 12 : r.builder().PopulateIndirectFunctionTable();
83 :
84 : // Build the main test function.
85 12 : BUILD(r, WASM_TRY_CATCH_T(
86 : kWasmI32,
87 : WASM_STMTS(WASM_I32V(kResult1),
88 : WASM_IF(WASM_I32_EQZ(WASM_GET_LOCAL(0)),
89 : WASM_STMTS(WASM_CALL_INDIRECT2(
90 : 0, WASM_GET_LOCAL(0),
91 : WASM_I32V(7), WASM_I32V(9)),
92 : WASM_DROP))),
93 : WASM_STMTS(WASM_DROP, WASM_I32V(kResult0))));
94 :
95 : // Need to call through JS to allow for creation of stack traces.
96 12 : r.CheckCallViaJS(kResult0, 0);
97 12 : r.CheckCallViaJS(kResult1, 1);
98 12 : }
99 :
100 25899 : WASM_EXEC_TEST(TryCatchCallExternal) {
101 12 : TestSignatures sigs;
102 : EXPERIMENTAL_FLAG_SCOPE(eh);
103 12 : HandleScope scope(CcTest::InitIsolateOnce());
104 : const char* source = "(function() { throw 'ball'; })";
105 : Handle<JSFunction> js_function =
106 : Handle<JSFunction>::cast(v8::Utils::OpenHandle(
107 12 : *v8::Local<v8::Function>::Cast(CompileRun(source))));
108 12 : ManuallyImportedJSFunction import = {sigs.i_ii(), js_function};
109 24 : WasmRunner<uint32_t, uint32_t> r(execution_tier, &import);
110 : constexpr uint32_t kResult0 = 23;
111 : constexpr uint32_t kResult1 = 42;
112 : constexpr uint32_t kJSFunc = 0;
113 :
114 : // Build the main test function.
115 12 : BUILD(r, WASM_TRY_CATCH_T(
116 : kWasmI32,
117 : WASM_STMTS(
118 : WASM_I32V(kResult1),
119 : WASM_IF(WASM_I32_EQZ(WASM_GET_LOCAL(0)),
120 : WASM_STMTS(WASM_CALL_FUNCTION(kJSFunc, WASM_I32V(7),
121 : WASM_I32V(9)),
122 : WASM_DROP))),
123 : WASM_STMTS(WASM_DROP, WASM_I32V(kResult0))));
124 :
125 : // Need to call through JS to allow for creation of stack traces.
126 12 : r.CheckCallViaJS(kResult0, 0);
127 12 : r.CheckCallViaJS(kResult1, 1);
128 12 : }
129 :
130 25899 : WASM_EXEC_TEST(TryCatchTrapTypeError) {
131 12 : TestSignatures sigs;
132 : EXPERIMENTAL_FLAG_SCOPE(eh);
133 12 : HandleScope scope(CcTest::InitIsolateOnce());
134 : const char* source = "(function() { return 0; })";
135 : Handle<JSFunction> js_function =
136 : Handle<JSFunction>::cast(v8::Utils::OpenHandle(
137 12 : *v8::Local<v8::Function>::Cast(CompileRun(source))));
138 : // Make sure to use a signature incompatible with JS below.
139 12 : ManuallyImportedJSFunction import = {sigs.i_ll(), js_function};
140 24 : WasmRunner<uint32_t, uint32_t> r(execution_tier, &import);
141 : constexpr uint32_t kResult0 = 23;
142 : constexpr uint32_t kResult1 = 42;
143 : constexpr uint32_t kJSFunc = 0;
144 :
145 : // Build the main test function.
146 12 : BUILD(r, WASM_TRY_CATCH_T(
147 : kWasmI32,
148 : WASM_STMTS(
149 : WASM_I32V(kResult1),
150 : WASM_IF(WASM_I32_EQZ(WASM_GET_LOCAL(0)),
151 : WASM_STMTS(WASM_CALL_FUNCTION(kJSFunc, WASM_I64V(7),
152 : WASM_I64V(9)),
153 : WASM_DROP))),
154 : WASM_STMTS(WASM_DROP, WASM_I32V(kResult0))));
155 :
156 : // Need to call through JS to allow for creation of stack traces.
157 12 : r.CheckCallViaJS(kResult0, 0);
158 12 : r.CheckCallViaJS(kResult1, 1);
159 12 : }
160 :
161 : namespace {
162 :
163 : // TODO(8729): The semantics of this are not yet specified and might change,
164 : // this test aims at keeping semantics of various execution tiers consistent.
165 48 : void TestTryCatchTrap(byte* code, size_t code_size,
166 : ExecutionTier execution_tier) {
167 48 : TestSignatures sigs;
168 : EXPERIMENTAL_FLAG_SCOPE(eh);
169 : WasmRunner<uint32_t, uint32_t> r(execution_tier, nullptr, "main",
170 96 : kRuntimeExceptionSupport);
171 48 : r.builder().AddMemory(kWasmPageSize);
172 : constexpr uint32_t kResult0 = 23;
173 : constexpr uint32_t kResult1 = 42;
174 :
175 : // Build a trapping helper function.
176 96 : WasmFunctionCompiler& trap_func = r.NewFunction(sigs.i_ii());
177 48 : trap_func.Build(code, code + code_size);
178 :
179 : // Build the main test function.
180 96 : BUILD(r, WASM_TRY_CATCH_T(
181 : kWasmI32,
182 : WASM_STMTS(WASM_I32V(kResult1),
183 : WASM_IF(WASM_I32_EQZ(WASM_GET_LOCAL(0)),
184 : WASM_STMTS(WASM_CALL_FUNCTION(
185 : trap_func.function_index(),
186 : WASM_I32V(7), WASM_I32V(9)),
187 : WASM_DROP))),
188 : WASM_STMTS(WASM_DROP, WASM_I32V(kResult0))));
189 :
190 : // Need to call through JS to allow for creation of stack traces.
191 48 : r.CheckCallViaJS(kResult0, 0);
192 48 : r.CheckCallViaJS(kResult1, 1);
193 48 : }
194 :
195 : } // namespace
196 :
197 25899 : WASM_EXEC_TEST(TryCatchTrapUnreachable) {
198 12 : byte code[] = {WASM_UNREACHABLE};
199 12 : TestTryCatchTrap(code, arraysize(code), execution_tier);
200 0 : }
201 :
202 25899 : WASM_EXEC_TEST(TryCatchTrapMemOutOfBounds) {
203 12 : byte code[] = {WASM_LOAD_MEM(MachineType::Int32(), WASM_I32V_1(-1))};
204 12 : TestTryCatchTrap(code, arraysize(code), execution_tier);
205 12 : }
206 :
207 25899 : WASM_EXEC_TEST(TryCatchTrapDivByZero) {
208 12 : byte code[] = {WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_I32V_1(0))};
209 12 : TestTryCatchTrap(code, arraysize(code), execution_tier);
210 12 : }
211 :
212 25899 : WASM_EXEC_TEST(TryCatchTrapRemByZero) {
213 12 : byte code[] = {WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_I32V_1(0))};
214 12 : TestTryCatchTrap(code, arraysize(code), execution_tier);
215 12 : }
216 :
217 : } // namespace test_run_wasm_exceptions
218 : } // namespace wasm
219 : } // namespace internal
220 77625 : } // namespace v8
|