basic.tentative.any.js (3898B)
1 // META: global=window,worker,jsshell,shadowrealm 2 // META: script=/wasm/jsapi/wasm-module-builder.js 3 4 function 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 // According to the spec discussion, the current `WebAssembly.Exception` does not have `[[ErrorData]]` semantically. 11 // - https://github.com/WebAssembly/spec/issues/1914 12 // - https://webassembly.github.io/spec/js-api/#exceptions 13 // - https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-properties-of-error-instances 14 assert_false(Error.isError(e), `Error.isError(WebAssembly.Exception) should be false due to lacking [[ErrorData]]`); 15 } 16 } 17 18 promise_test(async () => { 19 const kSig_v_r = makeSig([kWasmExternRef], []); 20 const builder = new WasmModuleBuilder(); 21 const tagIndex = builder.addTag(kSig_v_r); 22 builder.addFunction("throw_param", kSig_v_r) 23 .addBody([ 24 kExprLocalGet, 0, 25 kExprThrow, tagIndex, 26 ]) 27 .exportFunc(); 28 const buffer = builder.toBuffer(); 29 const {instance} = await WebAssembly.instantiate(buffer, {}); 30 const values = [ 31 undefined, 32 null, 33 true, 34 false, 35 "test", 36 Symbol(), 37 0, 38 1, 39 4.2, 40 NaN, 41 Infinity, 42 {}, 43 () => {}, 44 ]; 45 for (const v of values) { 46 assert_throws_wasm(() => instance.exports.throw_param(v), String(v)); 47 } 48 }, "Wasm function throws argument"); 49 50 promise_test(async () => { 51 const builder = new WasmModuleBuilder(); 52 const tagIndex = builder.addTag(kSig_v_a); 53 builder.addFunction("throw_null", kSig_v_v) 54 .addBody([ 55 kExprRefNull, kAnyFuncCode, 56 kExprThrow, tagIndex, 57 ]) 58 .exportFunc(); 59 const buffer = builder.toBuffer(); 60 const {instance} = await WebAssembly.instantiate(buffer, {}); 61 assert_throws_wasm(() => instance.exports.throw_null()); 62 }, "Wasm function throws null"); 63 64 promise_test(async () => { 65 const builder = new WasmModuleBuilder(); 66 const tagIndex = builder.addTag(kSig_v_i); 67 builder.addFunction("throw_int", kSig_v_v) 68 .addBody([ 69 ...wasmI32Const(7), 70 kExprThrow, tagIndex, 71 ]) 72 .exportFunc(); 73 const buffer = builder.toBuffer(); 74 const {instance} = await WebAssembly.instantiate(buffer, {}); 75 assert_throws_wasm(() => instance.exports.throw_int()); 76 }, "Wasm function throws integer"); 77 78 promise_test(async () => { 79 const builder = new WasmModuleBuilder(); 80 const fnIndex = builder.addImport("module", "fn", kSig_v_v); 81 const tagIndex= builder.addTag(kSig_v_r); 82 builder.addFunction("catch_exception", kSig_r_v) 83 .addBody([ 84 kExprTry, kWasmStmt, 85 kExprCallFunction, fnIndex, 86 kExprCatch, tagIndex, 87 kExprReturn, 88 kExprEnd, 89 kExprRefNull, kExternRefCode, 90 ]) 91 .exportFunc(); 92 93 const buffer = builder.toBuffer(); 94 95 const error = new Error(); 96 const fn = () => { throw error }; 97 const {instance} = await WebAssembly.instantiate(buffer, { 98 module: { fn } 99 }); 100 assert_throws_exactly(error, () => instance.exports.catch_exception()); 101 }, "Imported JS function throws"); 102 103 promise_test(async () => { 104 const builder = new WasmModuleBuilder(); 105 const fnIndex = builder.addImport("module", "fn", kSig_v_v); 106 builder.addFunction("catch_and_rethrow", kSig_r_v) 107 .addBody([ 108 kExprTry, kWasmStmt, 109 kExprCallFunction, fnIndex, 110 kExprCatchAll, 111 kExprRethrow, 0x00, 112 kExprEnd, 113 kExprRefNull, kExternRefCode, 114 ]) 115 .exportFunc(); 116 117 const buffer = builder.toBuffer(); 118 119 const error = new Error(); 120 const fn = () => { throw error }; 121 const {instance} = await WebAssembly.instantiate(buffer, { 122 module: { fn } 123 }); 124 assert_throws_exactly(error, () => instance.exports.catch_and_rethrow()); 125 }, "Imported JS function throws, Wasm catches and rethrows");