|
3 | 3 | // META: script=/wasm/jsapi/wasm-module-builder.js |
4 | 4 |
|
5 | 5 | test(() => { |
6 | | - const tag = new WebAssembly.Tag({ parameters: ["i32"] }); |
7 | | - const exn = new WebAssembly.Exception(tag, [42]); |
8 | | - const exn_same_payload = new WebAssembly.Exception(tag, [42]); |
9 | | - const exn_diff_payload = new WebAssembly.Exception(tag, [53]); |
10 | | - |
11 | 6 | const builder = new WasmModuleBuilder(); |
12 | | - const jsfuncIndex = builder.addImport("module", "jsfunc", kSig_v_v); |
13 | | - const tagIndex = builder.addImportedTag("module", "tag", kSig_v_i); |
| 7 | + |
| 8 | + // Tag defined in JavaScript and imported into Wasm |
| 9 | + const jsTag = new WebAssembly.Tag({ parameters: ["i32"] }); |
| 10 | + const jsTagIndex = builder.addImportedTag("module", "jsTag", kSig_v_i) |
| 11 | + const jsTagExn = new WebAssembly.Exception(jsTag, [42]); |
| 12 | + const jsTagExnSamePayload = new WebAssembly.Exception(jsTag, [42]); |
| 13 | + const jsTagExnDiffPayload = new WebAssembly.Exception(jsTag, [53]); |
| 14 | + const throwJSTagExnIndex = builder.addImport("module", "throwJSTagExn", kSig_v_v); |
| 15 | + |
14 | 16 | const imports = { |
15 | 17 | module: { |
16 | | - jsfunc: function() { throw exn; }, |
17 | | - tag: tag |
| 18 | + throwJSTagExn: function() { throw jsTagExn; }, |
| 19 | + jsTag: jsTag |
18 | 20 | } |
19 | 21 | }; |
20 | 22 |
|
| 23 | + // Call a JS function that throws an exception using a JS-defined tag, catches |
| 24 | + // it with a 'catch' instruction, and rethrows it. |
21 | 25 | builder |
22 | | - .addFunction("catch_rethrow", kSig_v_v) |
| 26 | + .addFunction("catch_js_tag_rethrow", kSig_v_v) |
23 | 27 | .addBody([ |
24 | 28 | kExprTry, kWasmStmt, |
25 | | - kExprCallFunction, jsfuncIndex, |
26 | | - kExprCatch, tagIndex, |
| 29 | + kExprCallFunction, throwJSTagExnIndex, |
| 30 | + kExprCatch, jsTagIndex, |
27 | 31 | kExprDrop, |
28 | 32 | kExprRethrow, 0x00, |
29 | 33 | kExprEnd |
30 | 34 | ]) |
31 | 35 | .exportFunc(); |
32 | 36 |
|
| 37 | + // Call a JS function that throws an exception using a JS-defined tag, catches |
| 38 | + // it with a 'catch_all' instruction, and rethrows it. |
33 | 39 | builder |
34 | | - .addFunction("catch_all_rethrow", kSig_v_v) |
| 40 | + .addFunction("catch_all_js_tag_rethrow", kSig_v_v) |
35 | 41 | .addBody([ |
36 | 42 | kExprTry, kWasmStmt, |
37 | | - kExprCallFunction, jsfuncIndex, |
| 43 | + kExprCallFunction, throwJSTagExnIndex, |
38 | 44 | kExprCatchAll, |
39 | 45 | kExprRethrow, 0x00, |
40 | 46 | kExprEnd |
41 | 47 | ]) |
42 | 48 | .exportFunc(); |
43 | 49 |
|
44 | 50 | const buffer = builder.toBuffer(); |
| 51 | + |
| 52 | + // The exception object's identity should be preserved across 'rethrow's in |
| 53 | + // Wasm code. Do tests with a tag defined in JS. |
45 | 54 | WebAssembly.instantiate(buffer, imports).then(result => { |
46 | 55 | try { |
47 | | - result.instance.exports.catch_rethrow(); |
| 56 | + result.instance.exports.catch_js_tag_rethrow(); |
48 | 57 | } catch (e) { |
49 | | - assert_equals(e, exn); |
50 | | - assert_not_equals(e, exn_same_payload); |
51 | | - assert_not_equals(e, exn_diff_payload); |
| 58 | + assert_equals(e, jsTagExn); |
| 59 | + // Even if they have the same payload, they are different objects, so they |
| 60 | + // shouldn't compare equal. |
| 61 | + assert_not_equals(e, jsTagExnSamePayload); |
| 62 | + assert_not_equals(e, jsTagExnDiffPayload); |
52 | 63 | } |
53 | 64 | try { |
54 | | - result.instance.exports.catch_all_rethrow(); |
| 65 | + result.instance.exports.catch_all_js_tag_rethrow(); |
55 | 66 | } catch (e) { |
56 | | - assert_equals(e, exn); |
57 | | - assert_not_equals(e, exn_same_payload); |
58 | | - assert_not_equals(e, exn_diff_payload); |
| 67 | + assert_equals(e, jsTagExn); |
| 68 | + assert_not_equals(e, jsTagExnSamePayload); |
| 69 | + assert_not_equals(e, jsTagExnDiffPayload); |
59 | 70 | } |
60 | 71 | }); |
61 | 72 | }, "Identity check"); |
0 commit comments