rejects.any.js (4665B)
1 // META: global=window,dedicatedworker,jsshell 2 // META: script=/wasm/jsapi/wasm-module-builder.js 3 // META: script=/wasm/jsapi/jspi/testharness-additions.js 4 5 promise_test(t => { 6 let tag = new WebAssembly.Tag({ 7 parameters: [] 8 }); 9 let builder = new WasmModuleBuilder(); 10 import_index = builder.addImport('m', 'import', kSig_i_i); 11 tag_index = builder.addImportedTag('m', 'tag', kSig_v_v); 12 builder.addFunction("test", kSig_i_i) 13 .addBody([ 14 kExprLocalGet, 0, 15 kExprCallFunction, import_index, 16 kExprThrow, tag_index 17 ]).exportFunc(); 18 19 function js_import() { 20 return Promise.resolve(); 21 }; 22 let wasm_js_import = new WebAssembly.Suspending(js_import); 23 24 let instance = builder.instantiate({ 25 m: { 26 import: wasm_js_import, 27 tag: tag 28 } 29 }); 30 let wrapped_export = WebAssembly.promising(instance.exports.test); 31 let export_promise = wrapped_export(); 32 assert_true(export_promise instanceof Promise); 33 return promise_rejects_jspi(t, new WebAssembly.Exception(tag, []), export_promise); 34 }, "Throw after the first suspension"); 35 36 // Throw an exception before suspending. The export wrapper should return a 37 // promise rejected with the exception. 38 promise_test(async (t) => { 39 let tag = new WebAssembly.Tag({ 40 parameters: [] 41 }); 42 let builder = new WasmModuleBuilder(); 43 tag_index = builder.addImportedTag('m', 'tag', kSig_v_v); 44 builder.addFunction("test", kSig_i_v) 45 .addBody([ 46 kExprThrow, tag_index 47 ]).exportFunc(); 48 49 let instance = builder.instantiate({ 50 m: { 51 tag: tag 52 } 53 }); 54 let wrapped_export = WebAssembly.promising(instance.exports.test); 55 let export_promise = wrapped_export(); 56 57 promise_rejects_jspi(t, new WebAssembly.Exception(tag, []), export_promise); 58 }, "Throw before suspending"); 59 60 // Throw an exception after the first resume event, which propagates to the 61 // promise wrapper. 62 promise_test(async (t) => { 63 let tag = new WebAssembly.Tag({ 64 parameters: [] 65 }); 66 let builder = new WasmModuleBuilder(); 67 import_index = builder.addImport('m', 'import', kSig_i_v); 68 tag_index = builder.addImportedTag('m', 'tag', kSig_v_v); 69 builder.addFunction("test", kSig_i_v) 70 .addBody([ 71 kExprCallFunction, import_index, 72 kExprThrow, tag_index 73 ]).exportFunc(); 74 75 function js_import() { 76 return Promise.resolve(42); 77 }; 78 let wasm_js_import = new WebAssembly.Suspending(js_import); 79 80 let instance = builder.instantiate({ 81 m: { 82 import: wasm_js_import, 83 tag: tag 84 } 85 }); 86 let wrapped_export = WebAssembly.promising(instance.exports.test); 87 let export_promise = wrapped_export(); 88 89 promise_rejects_jspi(t, new WebAssembly.Exception(tag, []), export_promise); 90 }, "Throw and propagate via Promise"); 91 92 promise_test(async (t) => { 93 let builder = new WasmModuleBuilder(); 94 builder.addFunction("test", kSig_i_v) 95 .addBody([ 96 kExprCallFunction, 0 97 ]).exportFunc(); 98 let instance = builder.instantiate(); 99 let wrapper = WebAssembly.promising(instance.exports.test); 100 101 // Stack overflow has undefined behavior -- check if an exception was thrown. 102 let thrown = false; 103 try { 104 await wrapper(); 105 } catch (e) { 106 thrown = true; 107 } 108 assert_true(thrown); 109 }, "Stack overflow"); 110 111 promise_test(async (t) => { 112 // The call stack of this test looks like: 113 // export1 -> import1 -> export2 -> import2 114 // Where export1 is "promising" and import2 is "suspending". Returning a 115 // promise from import2 should trap because of the JS import in the middle. 116 let builder = new WasmModuleBuilder(); 117 let import1_index = builder.addImport("m", "import1", kSig_i_v); 118 let import2_index = builder.addImport("m", "import2", kSig_i_v); 119 builder.addFunction("export1", kSig_i_v) 120 .addBody([ 121 // export1 -> import1 (unwrapped) 122 kExprCallFunction, import1_index, 123 ]).exportFunc(); 124 builder.addFunction("export2", kSig_i_v) 125 .addBody([ 126 // export2 -> import2 (suspending) 127 kExprCallFunction, import2_index, 128 ]).exportFunc(); 129 let instance; 130 131 function import1() { 132 // import1 -> export2 (unwrapped) 133 instance.exports.export2(); 134 } 135 136 function import2() { 137 return Promise.resolve(0); 138 } 139 import2 = new WebAssembly.Suspending(import2); 140 instance = builder.instantiate({ 141 'm': { 142 'import1': import1, 143 'import2': import2 144 } 145 }); 146 // export1 (promising) 147 let wrapper = WebAssembly.promising(instance.exports.export1); 148 promise_rejects_js(t, WebAssembly.SuspendError, wrapper(), 149 "trying to suspend JS frames"); 150 }, "Try to suspend JS");