Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(578)

Side by Side Diff: test/mjsunit/wasm/exceptions.js

Issue 2378773013: [WASM] Implements catch for the wasm low level exception mechanism. (Closed)
Patch Set: updates effect dependencies. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Flags: --expose-wasm --wasm-eh-prototype 5 // Flags: --expose-wasm --wasm-eh-prototype
6 6
7 load("test/mjsunit/wasm/wasm-constants.js"); 7 load("test/mjsunit/wasm/wasm-constants.js");
8 load("test/mjsunit/wasm/wasm-module-builder.js"); 8 load("test/mjsunit/wasm/wasm-module-builder.js");
9 9
10 var module = (function () { 10 // The following methods do not attempt to catch the exception they raise.
11 var test_throw = (function () {
11 var builder = new WasmModuleBuilder(); 12 var builder = new WasmModuleBuilder();
12 13
13 builder.addFunction("throw_param_if_not_zero", kSig_i_i) 14 builder.addFunction("throw_param_if_not_zero", kSig_i_i)
14 .addBody([ 15 .addBody([
15 kExprGetLocal, 0, 16 kExprGetLocal, 0,
16 kExprI32Const, 0, 17 kExprI32Const, 0,
17 kExprI32Ne, 18 kExprI32Ne,
18 kExprIf, kAstStmt, 19 kExprIf, kAstStmt,
19 kExprGetLocal, 0, 20 kExprGetLocal, 0,
20 kExprThrow, kAstStmt, 21 kExprThrow,
21 kExprEnd, 22 kExprEnd,
22 kExprI32Const, 1 23 kExprI32Const, 1
23 ]) 24 ])
24 .exportFunc() 25 .exportFunc()
25 26
26 builder.addFunction("throw_20", kSig_v_v) 27 builder.addFunction("throw_20", kSig_v_v)
27 .addBody([ 28 .addBody([
28 kExprI32Const, 20, 29 kExprI32Const, 20,
29 kExprThrow, kAstStmt 30 kExprThrow,
30 ]) 31 ])
31 .exportFunc() 32 .exportFunc()
32 33
33 builder.addFunction("throw_expr_with_params", kSig_v_ddi) 34 builder.addFunction("throw_expr_with_params", kSig_v_ddi)
34 .addBody([ 35 .addBody([
35 // p2 * (p0 + min(p0, p1))|0 - 20 36 // p2 * (p0 + min(p0, p1))|0 - 20
36 kExprGetLocal, 2, 37 kExprGetLocal, 2,
37 kExprGetLocal, 0, 38 kExprGetLocal, 0,
38 kExprGetLocal, 0, 39 kExprGetLocal, 0,
39 kExprGetLocal, 1, 40 kExprGetLocal, 1,
40 kExprF64Min, 41 kExprF64Min,
41 kExprF64Add, 42 kExprF64Add,
42 kExprI32SConvertF64, 43 kExprI32SConvertF64,
43 kExprI32Mul, 44 kExprI32Mul,
44 kExprI32Const, 20, 45 kExprI32Const, 20,
45 kExprI32Sub, 46 kExprI32Sub,
46 kExprThrow, kAstStmt 47 kExprThrow,
47 ]) 48 ])
48 .exportFunc() 49 .exportFunc()
49 50
50 return builder.instantiate(); 51 return builder.instantiate();
51 })(); 52 })();
52 53
53 // Check the module exists. 54 // Check the test_throw exists.
54 assertFalse(module === undefined); 55 assertFalse(test_throw === undefined);
55 assertFalse(module === null); 56 assertFalse(test_throw === null);
56 assertFalse(module === 0); 57 assertFalse(test_throw === 0);
57 assertEquals("object", typeof module.exports); 58 assertEquals("object", typeof test_throw.exports);
58 assertEquals("function", typeof module.exports.throw_param_if_not_zero); 59 assertEquals("function", typeof test_throw.exports.throw_param_if_not_zero);
59 60 assertEquals("function", typeof test_throw.exports.throw_20);
60 assertEquals(1, module.exports.throw_param_if_not_zero(0)); 61 assertEquals("function", typeof test_throw.exports.throw_expr_with_params);
61 assertWasmThrows(10, function() { module.exports.throw_param_if_not_zero(10) }); 62
62 assertWasmThrows(-1, function() { module.exports.throw_param_if_not_zero(-1) }); 63 assertEquals(1, test_throw.exports.throw_param_if_not_zero(0));
63 assertWasmThrows(20, module.exports.throw_20); 64 assertWasmThrows(10, function() { test_throw.exports.throw_param_if_not_zero(10) });
65 assertWasmThrows(-1, function() { test_throw.exports.throw_param_if_not_zero(-1) });
66 assertWasmThrows(20, test_throw.exports.throw_20);
64 assertWasmThrows( 67 assertWasmThrows(
65 -8, function() { module.exports.throw_expr_with_params(1.5, 2.5, 4); }); 68 -8, function() { test_throw.exports.throw_expr_with_params(1.5, 2.5, 4); });
66 assertWasmThrows( 69 assertWasmThrows(
67 12, function() { module.exports.throw_expr_with_params(5.7, 2.5, 4); }); 70 12, function() { test_throw.exports.throw_expr_with_params(5.7, 2.5, 4); });
71
72 // Now that we know throwing works, we test catching the exceptions we raise.
73 var test_catch = (function () {
74 var builder = new WasmModuleBuilder();
75
76 // Helper function for throwing from js. It is imported by the Wasm module
77 // as throw_i.
78 function throw_value(value) {
79 throw value;
80 }
81 var sig_index = builder.addType(kSig_v_i);
82 var kJSThrowI = builder.addImport("throw_i", sig_index);
83
84 // Helper function that throws a string. Wasm should not catch it.
85 function throw_string() {
86 throw "use wasm;";
87 }
88 sig_index = builder.addType(kSig_v_v);
89 var kJSThrowString = builder.addImport("throw_string", sig_index);
90
91 // Helper function that throws undefined. Wasm should not catch it.
92 function throw_undefined() {
93 throw undefined;
94 }
95 var kJSThrowUndefined = builder.addImport("throw_undefined", sig_index);
96
97 // Helper function that throws an fp. Wasm should not catch it.
98 function throw_fp() {
99 throw 10.5;
100 }
101 var kJSThrowFP = builder.addImport("throw_fp", sig_index);
102
103 // Helper function that throws a large number. Wasm should not catch it.
104 function throw_large() {
105 throw 1e+28;
106 }
107 var kJSThrowLarge = builder.addImport("throw_large", sig_index);
108
109 // Helper function for throwing from Wasm.
110 var kWasmThrowFunction =
111 builder.addFunction("throw", kSig_v_i)
112 .addBody([
113 kExprGetLocal, 0,
114 kExprThrow
115 ])
116 .index;
117
118 // Scenario 1: Throw and catch appear on the same function. This should
119 // happen in case of inlining, for example.
120 builder.addFunction("same_scope", kSig_i_i)
121 .addBody([
122 kExprTry, kAstI32,
123 kExprGetLocal, 0,
124 kExprI32Const, 0,
125 kExprI32Ne,
126 kExprIf, kAstStmt,
127 kExprGetLocal, 0,
128 kExprThrow,
129 kExprUnreachable,
130 kExprEnd,
131 kExprI32Const, 63,
132 kExprCatch, 1,
133 kExprGetLocal, 1,
134 kExprEnd
135 ])
136 .addLocals({i32_count: 1})
137 .exportFunc()
138 .index;
139
140 builder.addFunction("same_scope_ignore", kSig_i_i)
141 .addBody([
142 kExprTry, kAstI32,
143 kExprGetLocal, 0,
144 kExprThrow,
145 kExprUnreachable,
146 kExprCatch, 1,
147 kExprGetLocal, 0,
148 kExprEnd,
149 ])
150 .addLocals({i32_count: 1})
151 .exportFunc();
152
153 builder.addFunction("same_scope_multiple", kSig_i_i)
154 // path = 0;
155 //
Mircea Trofin 2016/09/30 16:00:44 why is this commented? could you please delete it,
John 2016/09/30 16:07:17 This documents what the test does -- it is pretty
156 // try {
157 // try {
158 // try {
159 // if (p == 1)
160 // throw 1;
161 // path |= 2
162 // } catch (v) {
163 // path |= v | 4;
164 // throw path;
165 // }
166 // if (p == 2)
167 // throw path|8;
168 // path |= 16;
169 // } catch (v) {
170 // path |= v | 32;
171 // throw path;
172 // }
173 // if (p == 3)
174 // throw path|64;
175 // path |= 128
176 // } catch (v) {
177 // path |= v | 256;
178 // }
179 //
180 // return path;
181 //
182 // p == 1 -> path == 293
183 // p == 2 -> path == 298
184 // p == 3 -> path == 338
185 // else -> path == 146
186 .addBody([
187 kExprTry, kAstI32,
188 kExprTry, kAstI32,
189 kExprTry, kAstI32,
190 kExprGetLocal, 0,
191 kExprI32Const, 1,
192 kExprI32Eq,
193 kExprIf, kAstStmt,
194 kExprI32Const, 1,
195 kExprThrow,
196 kExprUnreachable,
197 kExprEnd,
198 kExprI32Const, 2,
199 kExprCatch, 1,
200 kExprGetLocal, 1,
201 kExprI32Const, 4,
202 kExprI32Ior,
203 kExprThrow,
204 kExprUnreachable,
205 kExprEnd,
206 kExprTeeLocal, 2,
207 kExprGetLocal, 0,
208 kExprI32Const, 2,
209 kExprI32Eq,
210 kExprIf, kAstStmt,
211 kExprGetLocal, 2,
212 kExprI32Const, 8,
213 kExprI32Ior,
214 kExprThrow,
215 kExprUnreachable,
216 kExprEnd,
217 kExprI32Const, 16,
218 kExprI32Ior,
219 kExprCatch, 1,
220 kExprGetLocal, 1,
221 kExprI32Const, 32,
222 kExprI32Ior,
223 kExprThrow,
224 kExprUnreachable,
225 kExprEnd,
226 kExprTeeLocal, 2,
227 kExprGetLocal, 0,
228 kExprI32Const, 3,
229 kExprI32Eq,
230 kExprIf, kAstStmt,
231 kExprGetLocal, 2,
232 kExprI32Const, /*64=*/ 192, 0,
233 kExprI32Ior,
234 kExprThrow,
235 kExprUnreachable,
236 kExprEnd,
237 kExprI32Const, /*128=*/ 128, 1,
238 kExprI32Ior,
239 kExprCatch, 1,
240 kExprGetLocal, 1,
241 kExprI32Const, /*256=*/ 128, 2,
242 kExprI32Ior,
243 kExprEnd,
244 ])
245 .addLocals({i32_count: 2})
246 .exportFunc();
247
248 // Scenario 2: Catches an exception raised from the direct callee.
249 var kFromDirectCallee =
250 builder.addFunction("from_direct_callee", kSig_i_i)
251 .addBody([
252 kExprTry, kAstI32,
253 kExprGetLocal, 0,
254 kExprCallFunction, kWasmThrowFunction,
255 kExprI32Const, /*-1=*/ 127,
256 kExprCatch, 1,
257 kExprGetLocal, 1,
258 kExprEnd
259 ])
260 .addLocals({i32_count: 1})
261 .exportFunc()
262 .index;
263
264 // Scenario 3: Catches an exception raised from an indirect callee.
265 var kFromIndirectCalleeHelper = kFromDirectCallee + 1;
266 builder.addFunction("from_indirect_callee_helper", kSig_v_ii)
267 .addBody([
268 kExprGetLocal, 0,
269 kExprI32Const, 0,
270 kExprI32GtS,
271 kExprIf, kAstStmt,
272 kExprGetLocal, 0,
273 kExprI32Const, 1,
274 kExprI32Sub,
275 kExprGetLocal, 1,
276 kExprI32Const, 1,
277 kExprI32Sub,
278 kExprCallFunction, kFromIndirectCalleeHelper,
279 kExprEnd,
280 kExprGetLocal, 1,
281 kExprCallFunction, kWasmThrowFunction,
282 ]);
283
284 builder.addFunction("from_indirect_callee", kSig_i_i)
285 .addBody([
286 kExprTry, kAstI32,
287 kExprGetLocal, 0,
288 kExprI32Const, 0,
289 kExprCallFunction, kFromIndirectCalleeHelper,
290 kExprI32Const, /*-1=*/ 127,
291 kExprCatch, 1,
292 kExprGetLocal, 1,
293 kExprEnd
294 ])
295 .addLocals({i32_count: 1})
296 .exportFunc();
297
298 // Scenario 4: Catches an exception raised in JS.
299 builder.addFunction("from_js", kSig_i_i)
300 .addBody([
301 kExprTry, kAstI32,
302 kExprGetLocal, 0,
303 kExprCallFunction, kJSThrowI,
304 kExprI32Const, /*-1=*/ 127,
305 kExprCatch, 1,
306 kExprGetLocal, 1,
307 kExprEnd,
308 ])
309 .addLocals({i32_count: 1})
310 .exportFunc();
311
312 // Scenario 5: Does not catch an exception raised in JS if it is not a
313 // number.
314 builder.addFunction("string_from_js", kSig_v_v)
315 .addBody([
316 kExprCallFunction, kJSThrowString
317 ])
318 .exportFunc();
319
320 builder.addFunction("fp_from_js", kSig_v_v)
321 .addBody([
322 kExprCallFunction, kJSThrowFP
323 ])
324 .exportFunc();
325
326 builder.addFunction("large_from_js", kSig_v_v)
327 .addBody([
328 kExprCallFunction, kJSThrowLarge
329 ])
330 .exportFunc();
331
332 builder.addFunction("undefined_from_js", kSig_v_v)
333 .addBody([
334 kExprCallFunction, kJSThrowUndefined
335 ])
336 .exportFunc();
337
338 return builder.instantiate({
339 throw_i: throw_value,
340 throw_string: throw_string,
341 throw_fp: throw_fp,
342 throw_large, throw_large,
343 throw_undefined: throw_undefined
344 });
345 })();
346
347 // Check the test_catch exists.
348 assertFalse(test_catch === undefined);
349 assertFalse(test_catch === null);
350 assertFalse(test_catch === 0);
351 assertEquals("object", typeof test_catch.exports);
352 assertEquals("function", typeof test_catch.exports.same_scope);
353 assertEquals("function", typeof test_catch.exports.same_scope_ignore);
354 assertEquals("function", typeof test_catch.exports.same_scope_multiple);
355 assertEquals("function", typeof test_catch.exports.from_direct_callee);
356 assertEquals("function", typeof test_catch.exports.from_indirect_callee);
357 assertEquals("function", typeof test_catch.exports.from_js);
358 assertEquals("function", typeof test_catch.exports.string_from_js);
359
360 assertEquals(63, test_catch.exports.same_scope(0));
361 assertEquals(1024, test_catch.exports.same_scope(1024));
362 assertEquals(-3, test_catch.exports.same_scope(-3));
363 assertEquals(-1, test_catch.exports.same_scope_ignore(-1));
364 assertEquals(1, test_catch.exports.same_scope_ignore(1));
365 assertEquals(0x7FFFFFFF, test_catch.exports.same_scope_ignore(0x7FFFFFFF));
366 assertEquals(1024, test_catch.exports.same_scope_ignore(1024));
367 assertEquals(-1, test_catch.exports.same_scope_ignore(-1));
368 assertEquals(293, test_catch.exports.same_scope_multiple(1));
369 assertEquals(298, test_catch.exports.same_scope_multiple(2));
370 assertEquals(338, test_catch.exports.same_scope_multiple(3));
371 assertEquals(146, test_catch.exports.same_scope_multiple(0));
372 assertEquals(-10024, test_catch.exports.from_direct_callee(-10024));
373 assertEquals(3334333, test_catch.exports.from_direct_callee(3334333));
374 assertEquals(-1, test_catch.exports.from_direct_callee(0xFFFFFFFF));
375 assertEquals(0x7FFFFFFF, test_catch.exports.from_direct_callee(0x7FFFFFFF));
376 assertEquals(-10, test_catch.exports.from_indirect_callee(10));
377 assertEquals(-77, test_catch.exports.from_indirect_callee(77));
378 assertEquals(10, test_catch.exports.from_js(10));
379 assertEquals(-10, test_catch.exports.from_js(-10));
380
381 assertThrowsEquals(test_catch.exports.string_from_js, "use wasm;");
382 assertThrowsEquals(test_catch.exports.large_from_js, 1e+28);
383 assertThrowsEquals(test_catch.exports.undefined_from_js, undefined);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698