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