• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// META: global=window,worker,jsshell
2// META: script=/wasm/jsapi/wasm-module-builder.js
3
4function assert_throws_wasm(fn, message) {
5  try {
6    fn();
7    assert_not_reached(`expected to throw with ${message}`);
8  } catch (e) {
9    assert_true(e instanceof WebAssembly.Exception, `Error should be a WebAssembly.Exception with ${message}`);
10  }
11}
12
13promise_test(async () => {
14  const kWasmAnyRef = 0x6f;
15  const kSig_v_r = makeSig([kWasmAnyRef], []);
16  const builder = new WasmModuleBuilder();
17  const tagIndex = builder.addTag(kSig_v_r);
18  builder.addFunction("throw_param", kSig_v_r)
19    .addBody([
20      kExprLocalGet, 0,
21      kExprThrow, tagIndex,
22    ])
23    .exportFunc();
24  const buffer = builder.toBuffer();
25  const {instance} = await WebAssembly.instantiate(buffer, {});
26  const values = [
27    undefined,
28    null,
29    true,
30    false,
31    "test",
32    Symbol(),
33    0,
34    1,
35    4.2,
36    NaN,
37    Infinity,
38    {},
39    () => {},
40  ];
41  for (const v of values) {
42    assert_throws_wasm(() => instance.exports.throw_param(v), String(v));
43  }
44}, "Wasm function throws argument");
45
46promise_test(async () => {
47  const builder = new WasmModuleBuilder();
48  const tagIndex = builder.addTag(kSig_v_a);
49  builder.addFunction("throw_null", kSig_v_v)
50    .addBody([
51      kExprRefNull, kWasmAnyFunc,
52      kExprThrow, tagIndex,
53    ])
54    .exportFunc();
55  const buffer = builder.toBuffer();
56  const {instance} = await WebAssembly.instantiate(buffer, {});
57  assert_throws_wasm(() => instance.exports.throw_null());
58}, "Wasm function throws null");
59
60promise_test(async () => {
61  const builder = new WasmModuleBuilder();
62  const tagIndex = builder.addTag(kSig_v_i);
63  builder.addFunction("throw_int", kSig_v_v)
64    .addBody([
65      ...wasmI32Const(7),
66      kExprThrow, tagIndex,
67    ])
68    .exportFunc();
69  const buffer = builder.toBuffer();
70  const {instance} = await WebAssembly.instantiate(buffer, {});
71  assert_throws_wasm(() => instance.exports.throw_int());
72}, "Wasm function throws integer");
73
74promise_test(async () => {
75  const builder = new WasmModuleBuilder();
76  const fnIndex = builder.addImport("module", "fn", kSig_v_v);
77  const tagIndex= builder.addTag(kSig_v_r);
78  builder.addFunction("catch_exception", kSig_r_v)
79    .addBody([
80      kExprTry, kWasmStmt,
81        kExprCallFunction, fnIndex,
82      kExprCatch, tagIndex,
83        kExprReturn,
84      kExprEnd,
85      kExprRefNull, kWasmAnyRef,
86    ])
87    .exportFunc();
88
89  const buffer = builder.toBuffer();
90
91  const error = new Error();
92  const fn = () => { throw error };
93  const {instance} = await WebAssembly.instantiate(buffer, {
94    module: { fn }
95  });
96  assert_throws_exactly(error, () => instance.exports.catch_exception());
97}, "Imported JS function throws");
98
99promise_test(async () => {
100  const builder = new WasmModuleBuilder();
101  const fnIndex = builder.addImport("module", "fn", kSig_v_v);
102  builder.addFunction("catch_and_rethrow", kSig_r_v)
103    .addBody([
104      kExprTry, kWasmStmt,
105        kExprCallFunction, fnIndex,
106      kExprCatchAll,
107        kExprRethrow, 0x00,
108      kExprEnd,
109      kExprRefNull, kWasmAnyRef,
110    ])
111    .exportFunc();
112
113  const buffer = builder.toBuffer();
114
115  const error = new Error();
116  const fn = () => { throw error };
117  const {instance} = await WebAssembly.instantiate(buffer, {
118    module: { fn }
119  });
120  assert_throws_exactly(error, () => instance.exports.catch_and_rethrow());
121}, "Imported JS function throws, Wasm catches and rethrows");
122