summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/wasm/jsapi/exception/basic.tentative.any.js
blob: acf644f904f53d54918d660c419f60a15c72eabb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// META: global=window,worker,jsshell
// META: script=/wasm/jsapi/wasm-module-builder.js

function assert_throws_wasm(fn, message) {
  try {
    fn();
    assert_not_reached(`expected to throw with ${message}`);
  } catch (e) {
    assert_true(e instanceof WebAssembly.Exception, `Error should be a WebAssembly.Exception with ${message}`);
  }
}

promise_test(async () => {
  const kWasmAnyRef = 0x6f;
  const kSig_v_r = makeSig([kWasmAnyRef], []);
  const builder = new WasmModuleBuilder();
  const tagIndex = builder.addTag(kSig_v_r);
  builder.addFunction("throw_param", kSig_v_r)
    .addBody([
      kExprLocalGet, 0,
      kExprThrow, tagIndex,
    ])
    .exportFunc();
  const buffer = builder.toBuffer();
  const {instance} = await WebAssembly.instantiate(buffer, {});
  const values = [
    undefined,
    null,
    true,
    false,
    "test",
    Symbol(),
    0,
    1,
    4.2,
    NaN,
    Infinity,
    {},
    () => {},
  ];
  for (const v of values) {
    assert_throws_wasm(() => instance.exports.throw_param(v), String(v));
  }
}, "Wasm function throws argument");

promise_test(async () => {
  const builder = new WasmModuleBuilder();
  const tagIndex = builder.addTag(kSig_v_a);
  builder.addFunction("throw_null", kSig_v_v)
    .addBody([
      kExprRefNull, kWasmAnyFunc,
      kExprThrow, tagIndex,
    ])
    .exportFunc();
  const buffer = builder.toBuffer();
  const {instance} = await WebAssembly.instantiate(buffer, {});
  assert_throws_wasm(() => instance.exports.throw_null());
}, "Wasm function throws null");

promise_test(async () => {
  const builder = new WasmModuleBuilder();
  const tagIndex = builder.addTag(kSig_v_i);
  builder.addFunction("throw_int", kSig_v_v)
    .addBody([
      ...wasmI32Const(7),
      kExprThrow, tagIndex,
    ])
    .exportFunc();
  const buffer = builder.toBuffer();
  const {instance} = await WebAssembly.instantiate(buffer, {});
  assert_throws_wasm(() => instance.exports.throw_int());
}, "Wasm function throws integer");

promise_test(async () => {
  const builder = new WasmModuleBuilder();
  const fnIndex = builder.addImport("module", "fn", kSig_v_v);
  const tagIndex= builder.addTag(kSig_v_r);
  builder.addFunction("catch_exception", kSig_r_v)
    .addBody([
      kExprTry, kWasmStmt,
        kExprCallFunction, fnIndex,
      kExprCatch, tagIndex,
        kExprReturn,
      kExprEnd,
      kExprRefNull, kWasmAnyRef,
    ])
    .exportFunc();

  const buffer = builder.toBuffer();

  const error = new Error();
  const fn = () => { throw error };
  const {instance} = await WebAssembly.instantiate(buffer, {
    module: { fn }
  });
  assert_throws_exactly(error, () => instance.exports.catch_exception());
}, "Imported JS function throws");

promise_test(async () => {
  const builder = new WasmModuleBuilder();
  const fnIndex = builder.addImport("module", "fn", kSig_v_v);
  builder.addFunction("catch_and_rethrow", kSig_r_v)
    .addBody([
      kExprTry, kWasmStmt,
        kExprCallFunction, fnIndex,
      kExprCatchAll,
        kExprRethrow, 0x00,
      kExprEnd,
      kExprRefNull, kWasmAnyRef,
    ])
    .exportFunc();

  const buffer = builder.toBuffer();

  const error = new Error();
  const fn = () => { throw error };
  const {instance} = await WebAssembly.instantiate(buffer, {
    module: { fn }
  });
  assert_throws_exactly(error, () => instance.exports.catch_and_rethrow());
}, "Imported JS function throws, Wasm catches and rethrows");