// |jit-test| skip-if: !wasmStreamingEnabled() load(libdir + "wasm-binary.js"); function testInstantiate(source, importObj, exportName, expectedValue) { var result; WebAssembly.instantiateStreaming(code, importObj).then(r => { result = r }); drainJobQueue(); assertEq(result !== undefined, true); assertEq(result.module instanceof WebAssembly.Module, true); assertEq(result.instance instanceof WebAssembly.Instance, true); assertEq(result.instance.exports[exportName](), expectedValue); } function testBoth(source, exportName, expectedValue) { var module; WebAssembly.compileStreaming(code).then(m => { module = m }); drainJobQueue(); assertEq(module !== undefined, true); assertEq(module instanceof WebAssembly.Module, true); assertEq(new WebAssembly.Instance(module).exports[exportName](), expectedValue); testInstantiate(source, undefined, exportName, expectedValue); } function testFailInstantiate(source, importObj, error) { var caught = false; WebAssembly.instantiateStreaming(source).catch(err => { assertEq(err instanceof error, true); caught = true; }); drainJobQueue(); assertEq(caught, true); } function testFailBoth(source, error) { var caught = false; WebAssembly.compileStreaming(source).catch(err => { assertEq(err instanceof error, true); caught = true; }); drainJobQueue(); assertEq(caught, true); testFailInstantiate(source, undefined, error); } var code = wasmTextToBinary('(module (func (export "run") (result i32) i32.const 42))'); testBoth(code, 'run', 42); testFailBoth(42, TypeError); testBoth(Promise.resolve(code), 'run', 42); testFailBoth(Promise.resolve(42), TypeError); testFailBoth(Promise.reject(new String("fail")), String); testBoth({then(resolve) { resolve(code) }}, 'run', 42); testFailBoth({then(resolve) { resolve(42) }}, TypeError); testFailBoth(new Promise((resolve, reject) => { reject(new Error("hi")) }), Error); testFailBoth(new Promise((resolve, reject) => { reject(new String("hi")) }), String); var code = wasmTextToBinary('(module (func $im (import "js" "foo") (result i32)) (func (export "run") (result i32) (i32.add (i32.const 1) (call $im))))'); testInstantiate(code, {js:{foo() { return 42 }}}, 'run', 43); testFailInstantiate(code, null, TypeError); testFailInstantiate(code, {js:42}, TypeError); testFailInstantiate(code, {js:{foo:42}}, TypeError); var text = `(module\n`; text += ` (func (result i32) i32.const 0)\n`; for (var i = 1; i <= 200; i++) text += ` (func (result i32) (i32.add (i32.const ${i}) (call ${i-1})))\n`; text += ` (func (export "run") (result i32) call 100)\n`; text += `)`; var code = wasmTextToBinary(text); // fuzzing-safe disables setBufferStreamParams if (typeof setBufferStreamParams == 'function') { assertEq(code.length > 1000, true); for ([delayMillis, chunkSize] of [[0, 10], [1, 10], [0, 100], [1, 100], [0, 1000], [1, 1000], [10, 1000]]) { setBufferStreamParams(delayMillis, chunkSize); testBoth(code, 'run', 5050); } setBufferStreamParams(1, 100); var arr = []; for (var i = 0; i < 10; i++) arr.push(WebAssembly.instantiateStreaming(code)); var results; Promise.all(arr).then(r => results = r); drainJobQueue(); assertEq(results.length === 10, true); for (var i = 0; i < 10; i++) assertEq(results[i].instance.exports.run(), 5050); } // No code section, but data section: var code = wasmTextToBinary('(module (memory (import "js" "mem") 1) (data (i32.const 0) "a"))'); var mem = new WebAssembly.Memory({initial:1}); WebAssembly.instantiateStreaming(code, {js:{mem}}); drainJobQueue(); assertEq(new Uint8Array(mem.buffer)[0], 97); // Junk section before code section. testFailBoth(moduleWithSections([{name: 100, body: [1, 2, 3]}, bodySection([])]), WebAssembly.CompileError);