diff --git a/document/js-api/index.bs b/document/js-api/index.bs index 3f5803815e..9dc8a7a84c 100644 --- a/document/js-api/index.bs +++ b/document/js-api/index.bs @@ -372,11 +372,11 @@ dictionary WebAssemblyCompileOptions { [Exposed=*] namespace WebAssembly { - boolean validate(BufferSource bytes, optional WebAssemblyCompileOptions options = {}); - Promise<Module> compile(BufferSource bytes, optional WebAssemblyCompileOptions options = {}); + boolean validate([AllowResizable] AllowSharedBufferSource bytes, optional WebAssemblyCompileOptions options = {}); + Promise<Module> compile([AllowResizable] AllowSharedBufferSource bytes, optional WebAssemblyCompileOptions options = {}); Promise<WebAssemblyInstantiatedSource> instantiate( - BufferSource bytes, optional object importObject, optional WebAssemblyCompileOptions options = {}); + [AllowResizable] AllowSharedBufferSource bytes, optional object importObject, optional WebAssemblyCompileOptions options = {}); Promise<Instance> instantiate( Module moduleObject, optional object importObject); @@ -704,7 +704,7 @@ dictionary ModuleImportDescriptor { [LegacyNamespace=WebAssembly, Exposed=*] interface Module { - constructor(BufferSource bytes, optional WebAssemblyCompileOptions options = {}); + constructor([AllowResizable] AllowSharedBufferSource bytes, optional WebAssemblyCompileOptions options = {}); static sequence<ModuleExportDescriptor> exports(Module moduleObject); static sequence<ModuleImportDescriptor> imports(Module moduleObject); static sequence<ArrayBuffer> customSections(Module moduleObject, DOMString sectionName); diff --git a/test/js-api/constructor/compile.any.js b/test/js-api/constructor/compile.any.js index e94ce11717..9c83ddcfd3 100644 --- a/test/js-api/constructor/compile.any.js +++ b/test/js-api/constructor/compile.any.js @@ -7,9 +7,42 @@ function assert_Module(module) { assert_true(Object.isExtensible(module), "Extensibility"); } +function copyToSharedBuffer(buffer) { + const sab = new SharedArrayBuffer(buffer.byteLength); + new Uint8Array(sab).set(buffer); + return new Uint8Array(sab); +} + +function copyToResizableBuffer(buffer) { + const rab = new ArrayBuffer(buffer.byteLength, { maxByteLength: buffer.byteLength * 2 }); + new Uint8Array(rab).set(buffer); + return new Uint8Array(rab); +} + +function copyToGrowableSharedBuffer(buffer) { + const gsab = new SharedArrayBuffer(buffer.byteLength, { maxByteLength: buffer.byteLength * 2 }); + new Uint8Array(gsab).set(buffer); + return new Uint8Array(gsab); +} + let emptyModuleBinary; +let emptyModuleSharedBuffer; +let emptyModuleResizableBuffer; +let emptyModuleGrowableSharedBuffer; +let invalidModuleBinary; +let invalidModuleSharedBuffer; +let invalidModuleResizableBuffer; +let invalidModuleGrowableSharedBuffer; setup(() => { emptyModuleBinary = new WasmModuleBuilder().toBuffer(); + emptyModuleSharedBuffer = copyToSharedBuffer(emptyModuleBinary); + emptyModuleResizableBuffer = copyToResizableBuffer(emptyModuleBinary); + emptyModuleGrowableSharedBuffer = copyToGrowableSharedBuffer(emptyModuleBinary); + + invalidModuleBinary = new Uint8Array(Array.from(emptyModuleBinary).concat([0, 0])); + invalidModuleSharedBuffer = copyToSharedBuffer(invalidModuleBinary); + invalidModuleResizableBuffer = copyToResizableBuffer(invalidModuleBinary); + invalidModuleGrowableSharedBuffer = copyToGrowableSharedBuffer(invalidModuleBinary); }); promise_test(t => { @@ -64,8 +97,7 @@ promise_test(t => { }, "Empty buffer"); promise_test(t => { - const buffer = new Uint8Array(Array.from(emptyModuleBinary).concat([0, 0])); - return promise_rejects_js(t, WebAssembly.CompileError, WebAssembly.compile(buffer)); + return promise_rejects_js(t, WebAssembly.CompileError, WebAssembly.compile(invalidModuleBinary)); }, "Invalid code"); promise_test(() => { @@ -83,3 +115,27 @@ promise_test(() => { buffer[0] = 1; return promise.then(assert_Module); }, "Changing the buffer"); + +promise_test(() => { + return WebAssembly.compile(emptyModuleSharedBuffer).then(assert_Module); +}, "SharedArrayBuffer-backed view"); + +promise_test(t => { + return promise_rejects_js(t, WebAssembly.CompileError, WebAssembly.compile(invalidModuleSharedBuffer)); +}, "Invalid module in SharedArrayBuffer"); + +promise_test(() => { + return WebAssembly.compile(emptyModuleResizableBuffer).then(assert_Module); +}, "Resizable ArrayBuffer-backed view"); + +promise_test(t => { + return promise_rejects_js(t, WebAssembly.CompileError, WebAssembly.compile(invalidModuleResizableBuffer)); +}, "Invalid module in resizable ArrayBuffer"); + +promise_test(() => { + return WebAssembly.compile(emptyModuleGrowableSharedBuffer).then(assert_Module); +}, "Growable SharedArrayBuffer-backed view"); + +promise_test(t => { + return promise_rejects_js(t, WebAssembly.CompileError, WebAssembly.compile(invalidModuleGrowableSharedBuffer)); +}, "Invalid module in growable SharedArrayBuffer"); diff --git a/test/js-api/constructor/instantiate.any.js b/test/js-api/constructor/instantiate.any.js index 8152f3a56f..30f83efefa 100644 --- a/test/js-api/constructor/instantiate.any.js +++ b/test/js-api/constructor/instantiate.any.js @@ -3,9 +3,42 @@ // META: script=/wasm/jsapi/assertions.js // META: script=/wasm/jsapi/instanceTestFactory.js +function copyToSharedBuffer(buffer) { + const sab = new SharedArrayBuffer(buffer.byteLength); + new Uint8Array(sab).set(buffer); + return new Uint8Array(sab); +} + +function copyToResizableBuffer(buffer) { + const rab = new ArrayBuffer(buffer.byteLength, { maxByteLength: buffer.byteLength * 2 }); + new Uint8Array(rab).set(buffer); + return new Uint8Array(rab); +} + +function copyToGrowableSharedBuffer(buffer) { + const gsab = new SharedArrayBuffer(buffer.byteLength, { maxByteLength: buffer.byteLength * 2 }); + new Uint8Array(gsab).set(buffer); + return new Uint8Array(gsab); +} + let emptyModuleBinary; +let emptyModuleSharedBuffer; +let emptyModuleResizableBuffer; +let emptyModuleGrowableSharedBuffer; +let invalidModuleBinary; +let invalidModuleSharedBuffer; +let invalidModuleResizableBuffer; +let invalidModuleGrowableSharedBuffer; setup(() => { emptyModuleBinary = new WasmModuleBuilder().toBuffer(); + emptyModuleSharedBuffer = copyToSharedBuffer(emptyModuleBinary); + emptyModuleResizableBuffer = copyToResizableBuffer(emptyModuleBinary); + emptyModuleGrowableSharedBuffer = copyToGrowableSharedBuffer(emptyModuleBinary); + + invalidModuleBinary = new Uint8Array(Array.from(emptyModuleBinary).concat([0, 0])); + invalidModuleSharedBuffer = copyToSharedBuffer(invalidModuleBinary); + invalidModuleResizableBuffer = copyToResizableBuffer(invalidModuleBinary); + invalidModuleGrowableSharedBuffer = copyToGrowableSharedBuffer(invalidModuleBinary); }); promise_test(t => { @@ -139,8 +172,7 @@ promise_test(t => { }, "Empty buffer"); promise_test(t => { - const buffer = new Uint8Array(Array.from(emptyModuleBinary).concat([0, 0])); - return promise_rejects_js(t, WebAssembly.CompileError, WebAssembly.instantiate(buffer)); + return promise_rejects_js(t, WebAssembly.CompileError, WebAssembly.instantiate(invalidModuleBinary)); }, "Invalid code"); promise_test(() => { @@ -150,3 +182,27 @@ promise_test(() => { buffer[0] = 1; return promise.then(assert_WebAssemblyInstantiatedSource); }, "Changing the buffer"); + +promise_test(() => { + return WebAssembly.instantiate(emptyModuleSharedBuffer).then(assert_WebAssemblyInstantiatedSource); +}, "SharedArrayBuffer-backed view"); + +promise_test(t => { + return promise_rejects_js(t, WebAssembly.CompileError, WebAssembly.instantiate(invalidModuleSharedBuffer)); +}, "Invalid module in SharedArrayBuffer"); + +promise_test(() => { + return WebAssembly.instantiate(emptyModuleResizableBuffer).then(assert_WebAssemblyInstantiatedSource); +}, "Resizable ArrayBuffer-backed view"); + +promise_test(t => { + return promise_rejects_js(t, WebAssembly.CompileError, WebAssembly.instantiate(invalidModuleResizableBuffer)); +}, "Invalid module in resizable ArrayBuffer"); + +promise_test(() => { + return WebAssembly.instantiate(emptyModuleGrowableSharedBuffer).then(assert_WebAssemblyInstantiatedSource); +}, "Growable SharedArrayBuffer-backed view"); + +promise_test(t => { + return promise_rejects_js(t, WebAssembly.CompileError, WebAssembly.instantiate(invalidModuleGrowableSharedBuffer)); +}, "Invalid module in growable SharedArrayBuffer"); diff --git a/test/js-api/constructor/validate.any.js b/test/js-api/constructor/validate.any.js index 8b4f4582ab..005e13e383 100644 --- a/test/js-api/constructor/validate.any.js +++ b/test/js-api/constructor/validate.any.js @@ -1,9 +1,42 @@ // META: global=window,dedicatedworker,jsshell // META: script=/wasm/jsapi/wasm-module-builder.js +function copyToSharedBuffer(buffer) { + const sab = new SharedArrayBuffer(buffer.byteLength); + new Uint8Array(sab).set(buffer); + return new Uint8Array(sab); +} + +function copyToResizableBuffer(buffer) { + const rab = new ArrayBuffer(buffer.byteLength, { maxByteLength: buffer.byteLength * 2 }); + new Uint8Array(rab).set(buffer); + return new Uint8Array(rab); +} + +function copyToGrowableSharedBuffer(buffer) { + const gsab = new SharedArrayBuffer(buffer.byteLength, { maxByteLength: buffer.byteLength * 2 }); + new Uint8Array(gsab).set(buffer); + return new Uint8Array(gsab); +} + let emptyModuleBinary; +let emptyModuleSharedBuffer; +let emptyModuleResizableBuffer; +let emptyModuleGrowableSharedBuffer; +let invalidModuleBinary; +let invalidModuleSharedBuffer; +let invalidModuleResizableBuffer; +let invalidModuleGrowableSharedBuffer; setup(() => { emptyModuleBinary = new WasmModuleBuilder().toBuffer(); + emptyModuleSharedBuffer = copyToSharedBuffer(emptyModuleBinary); + emptyModuleResizableBuffer = copyToResizableBuffer(emptyModuleBinary); + emptyModuleGrowableSharedBuffer = copyToGrowableSharedBuffer(emptyModuleBinary); + + invalidModuleBinary = new Uint8Array(Array.from(emptyModuleBinary).concat([0, 0])); + invalidModuleSharedBuffer = copyToSharedBuffer(invalidModuleBinary); + invalidModuleResizableBuffer = copyToResizableBuffer(invalidModuleBinary); + invalidModuleGrowableSharedBuffer = copyToGrowableSharedBuffer(invalidModuleBinary); }); test(() => { @@ -97,3 +130,27 @@ for (const [module, expected] of modules) { test(() => { assert_true(WebAssembly.validate(emptyModuleBinary, {})); }, "Stray argument"); + +test(() => { + assert_true(WebAssembly.validate(emptyModuleSharedBuffer)); +}, "SharedArrayBuffer-backed view"); + +test(() => { + assert_false(WebAssembly.validate(invalidModuleSharedBuffer)); +}, "Invalid module in SharedArrayBuffer"); + +test(() => { + assert_true(WebAssembly.validate(emptyModuleResizableBuffer)); +}, "Resizable ArrayBuffer-backed view"); + +test(() => { + assert_false(WebAssembly.validate(invalidModuleResizableBuffer)); +}, "Invalid module in resizable ArrayBuffer"); + +test(() => { + assert_true(WebAssembly.validate(emptyModuleGrowableSharedBuffer)); +}, "Growable SharedArrayBuffer-backed view"); + +test(() => { + assert_false(WebAssembly.validate(invalidModuleGrowableSharedBuffer)); +}, "Invalid module in growable SharedArrayBuffer"); diff --git a/test/js-api/module/constructor.any.js b/test/js-api/module/constructor.any.js index 9978f7e6ac..6e4247a230 100644 --- a/test/js-api/module/constructor.any.js +++ b/test/js-api/module/constructor.any.js @@ -2,9 +2,42 @@ // META: script=/wasm/jsapi/wasm-module-builder.js // META: script=/wasm/jsapi/assertions.js +function copyToSharedBuffer(buffer) { + const sab = new SharedArrayBuffer(buffer.byteLength); + new Uint8Array(sab).set(buffer); + return new Uint8Array(sab); +} + +function copyToResizableBuffer(buffer) { + const rab = new ArrayBuffer(buffer.byteLength, { maxByteLength: buffer.byteLength * 2 }); + new Uint8Array(rab).set(buffer); + return new Uint8Array(rab); +} + +function copyToGrowableSharedBuffer(buffer) { + const gsab = new SharedArrayBuffer(buffer.byteLength, { maxByteLength: buffer.byteLength * 2 }); + new Uint8Array(gsab).set(buffer); + return new Uint8Array(gsab); +} + let emptyModuleBinary; +let emptyModuleSharedBuffer; +let emptyModuleResizableBuffer; +let emptyModuleGrowableSharedBuffer; +let invalidModuleBinary; +let invalidModuleSharedBuffer; +let invalidModuleResizableBuffer; +let invalidModuleGrowableSharedBuffer; setup(() => { emptyModuleBinary = new WasmModuleBuilder().toBuffer(); + emptyModuleSharedBuffer = copyToSharedBuffer(emptyModuleBinary); + emptyModuleResizableBuffer = copyToResizableBuffer(emptyModuleBinary); + emptyModuleGrowableSharedBuffer = copyToGrowableSharedBuffer(emptyModuleBinary); + + invalidModuleBinary = new Uint8Array(Array.from(emptyModuleBinary).concat([0, 0])); + invalidModuleSharedBuffer = copyToSharedBuffer(invalidModuleBinary); + invalidModuleResizableBuffer = copyToResizableBuffer(invalidModuleBinary); + invalidModuleGrowableSharedBuffer = copyToGrowableSharedBuffer(invalidModuleBinary); }); test(() => { @@ -49,8 +82,7 @@ test(() => { }, "Empty buffer"); test(() => { - const buffer = new Uint8Array(Array.from(emptyModuleBinary).concat([0, 0])); - assert_throws_js(WebAssembly.CompileError, () => new WebAssembly.Module(buffer)); + assert_throws_js(WebAssembly.CompileError, () => new WebAssembly.Module(invalidModuleBinary)); }, "Invalid code"); test(() => { @@ -67,3 +99,30 @@ test(() => { const module = new WebAssembly.Module(emptyModuleBinary, {}); assert_equals(Object.getPrototypeOf(module), WebAssembly.Module.prototype); }, "Stray argument"); + +test(() => { + const module = new WebAssembly.Module(emptyModuleSharedBuffer); + assert_true(module instanceof WebAssembly.Module); +}, "SharedArrayBuffer-backed view"); + +test(() => { + assert_throws_js(WebAssembly.CompileError, () => new WebAssembly.Module(invalidModuleSharedBuffer)); +}, "Invalid module in SharedArrayBuffer"); + +test(() => { + const module = new WebAssembly.Module(emptyModuleResizableBuffer); + assert_true(module instanceof WebAssembly.Module); +}, "Resizable ArrayBuffer-backed view"); + +test(() => { + assert_throws_js(WebAssembly.CompileError, () => new WebAssembly.Module(invalidModuleResizableBuffer)); +}, "Invalid module in resizable ArrayBuffer"); + +test(() => { + const module = new WebAssembly.Module(emptyModuleGrowableSharedBuffer); + assert_true(module instanceof WebAssembly.Module); +}, "Growable SharedArrayBuffer-backed view"); + +test(() => { + assert_throws_js(WebAssembly.CompileError, () => new WebAssembly.Module(invalidModuleGrowableSharedBuffer)); +}, "Invalid module in growable SharedArrayBuffer");