11cb0ef41Sopenharmony_ci// META: global=window,worker,jsshell
21cb0ef41Sopenharmony_ci// META: script=/wasm/jsapi/wasm-module-builder.js
31cb0ef41Sopenharmony_ci
41cb0ef41Sopenharmony_cifunction assert_throws_wasm(fn, message) {
51cb0ef41Sopenharmony_ci  try {
61cb0ef41Sopenharmony_ci    fn();
71cb0ef41Sopenharmony_ci    assert_not_reached(`expected to throw with ${message}`);
81cb0ef41Sopenharmony_ci  } catch (e) {
91cb0ef41Sopenharmony_ci    assert_true(e instanceof WebAssembly.Exception, `Error should be a WebAssembly.Exception with ${message}`);
101cb0ef41Sopenharmony_ci  }
111cb0ef41Sopenharmony_ci}
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_cipromise_test(async () => {
141cb0ef41Sopenharmony_ci  const kWasmAnyRef = 0x6f;
151cb0ef41Sopenharmony_ci  const kSig_v_r = makeSig([kWasmAnyRef], []);
161cb0ef41Sopenharmony_ci  const builder = new WasmModuleBuilder();
171cb0ef41Sopenharmony_ci  const tagIndex = builder.addTag(kSig_v_r);
181cb0ef41Sopenharmony_ci  builder.addFunction("throw_param", kSig_v_r)
191cb0ef41Sopenharmony_ci    .addBody([
201cb0ef41Sopenharmony_ci      kExprLocalGet, 0,
211cb0ef41Sopenharmony_ci      kExprThrow, tagIndex,
221cb0ef41Sopenharmony_ci    ])
231cb0ef41Sopenharmony_ci    .exportFunc();
241cb0ef41Sopenharmony_ci  const buffer = builder.toBuffer();
251cb0ef41Sopenharmony_ci  const {instance} = await WebAssembly.instantiate(buffer, {});
261cb0ef41Sopenharmony_ci  const values = [
271cb0ef41Sopenharmony_ci    undefined,
281cb0ef41Sopenharmony_ci    null,
291cb0ef41Sopenharmony_ci    true,
301cb0ef41Sopenharmony_ci    false,
311cb0ef41Sopenharmony_ci    "test",
321cb0ef41Sopenharmony_ci    Symbol(),
331cb0ef41Sopenharmony_ci    0,
341cb0ef41Sopenharmony_ci    1,
351cb0ef41Sopenharmony_ci    4.2,
361cb0ef41Sopenharmony_ci    NaN,
371cb0ef41Sopenharmony_ci    Infinity,
381cb0ef41Sopenharmony_ci    {},
391cb0ef41Sopenharmony_ci    () => {},
401cb0ef41Sopenharmony_ci  ];
411cb0ef41Sopenharmony_ci  for (const v of values) {
421cb0ef41Sopenharmony_ci    assert_throws_wasm(() => instance.exports.throw_param(v), String(v));
431cb0ef41Sopenharmony_ci  }
441cb0ef41Sopenharmony_ci}, "Wasm function throws argument");
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_cipromise_test(async () => {
471cb0ef41Sopenharmony_ci  const builder = new WasmModuleBuilder();
481cb0ef41Sopenharmony_ci  const tagIndex = builder.addTag(kSig_v_a);
491cb0ef41Sopenharmony_ci  builder.addFunction("throw_null", kSig_v_v)
501cb0ef41Sopenharmony_ci    .addBody([
511cb0ef41Sopenharmony_ci      kExprRefNull, kWasmAnyFunc,
521cb0ef41Sopenharmony_ci      kExprThrow, tagIndex,
531cb0ef41Sopenharmony_ci    ])
541cb0ef41Sopenharmony_ci    .exportFunc();
551cb0ef41Sopenharmony_ci  const buffer = builder.toBuffer();
561cb0ef41Sopenharmony_ci  const {instance} = await WebAssembly.instantiate(buffer, {});
571cb0ef41Sopenharmony_ci  assert_throws_wasm(() => instance.exports.throw_null());
581cb0ef41Sopenharmony_ci}, "Wasm function throws null");
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_cipromise_test(async () => {
611cb0ef41Sopenharmony_ci  const builder = new WasmModuleBuilder();
621cb0ef41Sopenharmony_ci  const tagIndex = builder.addTag(kSig_v_i);
631cb0ef41Sopenharmony_ci  builder.addFunction("throw_int", kSig_v_v)
641cb0ef41Sopenharmony_ci    .addBody([
651cb0ef41Sopenharmony_ci      ...wasmI32Const(7),
661cb0ef41Sopenharmony_ci      kExprThrow, tagIndex,
671cb0ef41Sopenharmony_ci    ])
681cb0ef41Sopenharmony_ci    .exportFunc();
691cb0ef41Sopenharmony_ci  const buffer = builder.toBuffer();
701cb0ef41Sopenharmony_ci  const {instance} = await WebAssembly.instantiate(buffer, {});
711cb0ef41Sopenharmony_ci  assert_throws_wasm(() => instance.exports.throw_int());
721cb0ef41Sopenharmony_ci}, "Wasm function throws integer");
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_cipromise_test(async () => {
751cb0ef41Sopenharmony_ci  const builder = new WasmModuleBuilder();
761cb0ef41Sopenharmony_ci  const fnIndex = builder.addImport("module", "fn", kSig_v_v);
771cb0ef41Sopenharmony_ci  const tagIndex= builder.addTag(kSig_v_r);
781cb0ef41Sopenharmony_ci  builder.addFunction("catch_exception", kSig_r_v)
791cb0ef41Sopenharmony_ci    .addBody([
801cb0ef41Sopenharmony_ci      kExprTry, kWasmStmt,
811cb0ef41Sopenharmony_ci        kExprCallFunction, fnIndex,
821cb0ef41Sopenharmony_ci      kExprCatch, tagIndex,
831cb0ef41Sopenharmony_ci        kExprReturn,
841cb0ef41Sopenharmony_ci      kExprEnd,
851cb0ef41Sopenharmony_ci      kExprRefNull, kWasmAnyRef,
861cb0ef41Sopenharmony_ci    ])
871cb0ef41Sopenharmony_ci    .exportFunc();
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci  const buffer = builder.toBuffer();
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci  const error = new Error();
921cb0ef41Sopenharmony_ci  const fn = () => { throw error };
931cb0ef41Sopenharmony_ci  const {instance} = await WebAssembly.instantiate(buffer, {
941cb0ef41Sopenharmony_ci    module: { fn }
951cb0ef41Sopenharmony_ci  });
961cb0ef41Sopenharmony_ci  assert_throws_exactly(error, () => instance.exports.catch_exception());
971cb0ef41Sopenharmony_ci}, "Imported JS function throws");
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_cipromise_test(async () => {
1001cb0ef41Sopenharmony_ci  const builder = new WasmModuleBuilder();
1011cb0ef41Sopenharmony_ci  const fnIndex = builder.addImport("module", "fn", kSig_v_v);
1021cb0ef41Sopenharmony_ci  builder.addFunction("catch_and_rethrow", kSig_r_v)
1031cb0ef41Sopenharmony_ci    .addBody([
1041cb0ef41Sopenharmony_ci      kExprTry, kWasmStmt,
1051cb0ef41Sopenharmony_ci        kExprCallFunction, fnIndex,
1061cb0ef41Sopenharmony_ci      kExprCatchAll,
1071cb0ef41Sopenharmony_ci        kExprRethrow, 0x00,
1081cb0ef41Sopenharmony_ci      kExprEnd,
1091cb0ef41Sopenharmony_ci      kExprRefNull, kWasmAnyRef,
1101cb0ef41Sopenharmony_ci    ])
1111cb0ef41Sopenharmony_ci    .exportFunc();
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci  const buffer = builder.toBuffer();
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci  const error = new Error();
1161cb0ef41Sopenharmony_ci  const fn = () => { throw error };
1171cb0ef41Sopenharmony_ci  const {instance} = await WebAssembly.instantiate(buffer, {
1181cb0ef41Sopenharmony_ci    module: { fn }
1191cb0ef41Sopenharmony_ci  });
1201cb0ef41Sopenharmony_ci  assert_throws_exactly(error, () => instance.exports.catch_and_rethrow());
1211cb0ef41Sopenharmony_ci}, "Imported JS function throws, Wasm catches and rethrows");
122