/* * Copyright 2017 WebAssembly Community Group participants * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function testJSAPI() { const WasmPage = 64 * 1024; const emptyModuleBinary = new WasmModuleBuilder().toBuffer(); const importingModuleBinary = (() => { let builder = new WasmModuleBuilder(); builder.addImport('', 'f', kSig_v_v); return builder.toBuffer(); })(); const complexImportingModuleBinary = (() => { let builder = new WasmModuleBuilder(); builder.addImport('a', 'b', kSig_v_v); builder.addImportedMemory('c', 'd', 1); builder.addImportedTable('e', 'f', 1); builder.addImportedGlobal('g', '⚡', kWasmI32); return builder.toBuffer(); })(); const exportingModuleBinary = (() => { let builder = new WasmModuleBuilder(); builder .addFunction('f', kSig_i_v) .addBody([ kExprI32Const, 42 ]) .exportFunc(); return builder.toBuffer(); })(); const complexExportingModuleBinary = (() => { let builder = new WasmModuleBuilder(); builder .addFunction('a', kSig_v_v) .addBody([]) .exportFunc(); builder.addMemory(1, 1, /* exported */ false); builder.exportMemoryAs('b'); builder.setFunctionTableLength(1); builder.addExportOfKind('c', kExternalTable, 0); // Default init for global values is 0. Keep that. builder.addGlobal(kWasmI32, /* mutable */ false) .exportAs("⚡"); return builder.toBuffer(); })(); const moduleBinaryImporting2Memories = (() => { var builder = new WasmModuleBuilder(); builder.addImportedMemory("", "memory1"); builder.addImportedMemory("", "memory2"); return builder.toBuffer(); })(); const moduleBinaryWithMemSectionAndMemImport = (() => { var builder = new WasmModuleBuilder(); builder.addMemory(1, 1, false); builder.addImportedMemory("", "memory1"); return builder.toBuffer(); })(); let Module; let Instance; let CompileError; let LinkError; let RuntimeError; let Memory; let instanceProto; let memoryProto; let mem1; let Table; let tbl1; let tableProto; let emptyModule; let exportingModule; let exportingInstance; let exportsObj; let importingModule; // Start of tests. test(() => { const wasmDesc = Object.getOwnPropertyDescriptor(this, 'WebAssembly'); assert_equals(typeof wasmDesc.value, "object"); assert_true(wasmDesc.writable); assert_false(wasmDesc.enumerable); assert_true(wasmDesc.configurable); }, "'WebAssembly' data property on global object"); test(() => { const wasmDesc = Object.getOwnPropertyDescriptor(this, 'WebAssembly'); assert_equals(WebAssembly, wasmDesc.value); assert_equals(String(WebAssembly), "[object WebAssembly]"); }, "'WebAssembly' object"); test(() => { const compileErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'CompileError'); const linkErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'LinkError'); const runtimeErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'RuntimeError'); assert_equals(typeof compileErrorDesc.value, "function"); assert_equals(typeof linkErrorDesc.value, "function"); assert_equals(typeof runtimeErrorDesc.value, "function"); assert_equals(compileErrorDesc.writable, true); assert_equals(linkErrorDesc.writable, true); assert_equals(runtimeErrorDesc.writable, true); assert_equals(compileErrorDesc.enumerable, false); assert_equals(linkErrorDesc.enumerable, false); assert_equals(runtimeErrorDesc.enumerable, false); assert_equals(compileErrorDesc.configurable, true); assert_equals(linkErrorDesc.configurable, true); assert_equals(runtimeErrorDesc.configurable, true); CompileError = WebAssembly.CompileError; LinkError = WebAssembly.LinkError; RuntimeError = WebAssembly.RuntimeError; }, "'WebAssembly.(Compile|Link|Runtime)Error' data property"); test(() => { const compileErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'CompileError'); const linkErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'LinkError'); const runtimeErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'RuntimeError'); assert_equals(CompileError, compileErrorDesc.value); assert_equals(LinkError, linkErrorDesc.value); assert_equals(RuntimeError, runtimeErrorDesc.value); assert_equals(CompileError.length, 1); assert_equals(LinkError.length, 1); assert_equals(RuntimeError.length, 1); assert_equals(CompileError.name, "CompileError"); assert_equals(LinkError.name, "LinkError"); assert_equals(RuntimeError.name, "RuntimeError"); }, "'WebAssembly.(Compile|Runtime)Error' constructor function"); test(() => { const compileError = new CompileError; const runtimeError = new RuntimeError; assert_equals(compileError instanceof CompileError, true); assert_equals(runtimeError instanceof RuntimeError, true); assert_equals(compileError instanceof Error, true); assert_equals(runtimeError instanceof Error, true); assert_equals(compileError instanceof TypeError, false); assert_equals(runtimeError instanceof TypeError, false); assert_equals(compileError.message, ""); assert_equals(runtimeError.message, ""); // FIXME https://bugs.webkit.org/show_bug.cgi?id=173159 assert_equals(new CompileError("hi").message, "hi"); // FIXME https://bugs.webkit.org/show_bug.cgi?id=173159 assert_equals(new RuntimeError("hi").message, "hi"); }, "'WebAssembly.(Compile|Runtime)Error' instance objects"); test(() => { const moduleDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Module'); assert_equals(typeof moduleDesc.value, "function"); assert_equals(moduleDesc.writable, true); assert_equals(moduleDesc.enumerable, false); assert_equals(moduleDesc.configurable, true); Module = WebAssembly.Module; }, "'WebAssembly.Module' data property"); test(() => { const moduleDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Module'); assert_equals(Module, moduleDesc.value); assert_equals(Module.length, 1); assert_equals(Module.name, "Module"); assertThrows(() => Module(), TypeError); assertThrows(() => new Module(), TypeError); assertThrows(() => new Module(undefined), TypeError); assertThrows(() => new Module(1), TypeError); assertThrows(() => new Module({}), TypeError); assertThrows(() => new Module(new Uint8Array()), CompileError); assertThrows(() => new Module(new ArrayBuffer()), CompileError); assert_equals(new Module(emptyModuleBinary) instanceof Module, true); assert_equals(new Module(new Uint8Array(emptyModuleBinary)) instanceof Module, true); }, "'WebAssembly.Module' constructor function"); test(() => { const moduleProtoDesc = Object.getOwnPropertyDescriptor(Module, 'prototype'); assert_equals(typeof moduleProtoDesc.value, "object"); assert_equals(moduleProtoDesc.writable, false); assert_equals(moduleProtoDesc.enumerable, false); assert_equals(moduleProtoDesc.configurable, false); }, "'WebAssembly.Module.prototype' data property"); test(() => { const moduleProtoDesc = Object.getOwnPropertyDescriptor(Module, 'prototype'); const moduleProto = Module.prototype; assert_equals(moduleProto, moduleProtoDesc.value); assert_equals(String(moduleProto), "[object WebAssembly.Module]"); assert_equals(Object.getPrototypeOf(moduleProto), Object.prototype); }, "'WebAssembly.Module.prototype' object"); test(() => { const moduleProto = Module.prototype; emptyModule = new Module(emptyModuleBinary); exportingModule = new Module(exportingModuleBinary); importingModule = new Module(importingModuleBinary); assert_equals(typeof emptyModule, "object"); assert_equals(String(emptyModule), "[object WebAssembly.Module]"); assert_equals(Object.getPrototypeOf(emptyModule), moduleProto); }, "'WebAssembly.Module' instance objects"); test(() => { const moduleImportsDesc = Object.getOwnPropertyDescriptor(Module, 'imports'); assert_equals(typeof moduleImportsDesc.value, "function"); assert_equals(moduleImportsDesc.writable, true); assert_equals(moduleImportsDesc.enumerable, false); assert_equals(moduleImportsDesc.configurable, true); }, "'WebAssembly.Module.imports' data property"); test(() => { const moduleImportsDesc = Object.getOwnPropertyDescriptor(Module, 'imports'); const moduleImports = moduleImportsDesc.value; assert_equals(moduleImports.length, 1); assertThrows(() => moduleImports(), TypeError); assertThrows(() => moduleImports(undefined), TypeError); assertThrows(() => moduleImports({}), TypeError); var arr = moduleImports(emptyModule); assert_equals(arr instanceof Array, true); assert_equals(arr.length, 0); var arr = moduleImports(new Module(complexImportingModuleBinary)); assert_equals(arr instanceof Array, true); assert_equals(arr.length, 4); assert_equals(arr[0].kind, "function"); assert_equals(arr[0].module, "a"); assert_equals(arr[0].name, "b"); assert_equals(arr[1].kind, "memory"); assert_equals(arr[1].module, "c"); assert_equals(arr[1].name, "d"); assert_equals(arr[2].kind, "table"); assert_equals(arr[2].module, "e"); assert_equals(arr[2].name, "f"); assert_equals(arr[3].kind, "global"); assert_equals(arr[3].module, "g"); assert_equals(arr[3].name, "⚡"); }, "'WebAssembly.Module.imports' method"); test(() => { const moduleExportsDesc = Object.getOwnPropertyDescriptor(Module, 'exports'); assert_equals(typeof moduleExportsDesc.value, "function"); assert_equals(moduleExportsDesc.writable, true); assert_equals(moduleExportsDesc.enumerable, false); assert_equals(moduleExportsDesc.configurable, true); }, "'WebAssembly.Module.exports' data property"); test(() => { const moduleExportsDesc = Object.getOwnPropertyDescriptor(Module, 'exports'); const moduleExports = moduleExportsDesc.value; assert_equals(moduleExports.length, 1); assertThrows(() => moduleExports(), TypeError); assertThrows(() => moduleExports(undefined), TypeError); assertThrows(() => moduleExports({}), TypeError); var arr = moduleExports(emptyModule); assert_equals(arr instanceof Array, true); assert_equals(arr.length, 0); var arr = moduleExports(new Module(complexExportingModuleBinary)); assert_equals(arr instanceof Array, true); assert_equals(arr.length, 4); assert_equals(arr[0].kind, "function"); assert_equals(arr[0].name, "a"); assert_equals(arr[1].kind, "memory"); assert_equals(arr[1].name, "b"); assert_equals(arr[2].kind, "table"); assert_equals(arr[2].name, "c"); assert_equals(arr[3].kind, "global"); assert_equals(arr[3].name, "⚡"); }, "'WebAssembly.Module.exports' method"); test(() => { const customSectionsDesc = Object.getOwnPropertyDescriptor(Module, 'customSections'); assert_equals(typeof customSectionsDesc.value, "function"); assert_equals(customSectionsDesc.writable, true); assert_equals(customSectionsDesc.enumerable, false); assert_equals(customSectionsDesc.configurable, true); }, "'WebAssembly.Module.customSections' data property"); test(() => { const customSectionsDesc = Object.getOwnPropertyDescriptor(Module, 'customSections'); const moduleCustomSections = customSectionsDesc.value; assert_equals(moduleCustomSections.length, 2); assertThrows(() => moduleCustomSections(), TypeError); assertThrows(() => moduleCustomSections(undefined), TypeError); assertThrows(() => moduleCustomSections({}), TypeError); var arr = moduleCustomSections(emptyModule); assert_equals(arr instanceof Array, true); assert_equals(arr.length, 0); }, "'WebAssembly.Module.customSections' method"); test(() => { const instanceDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Instance'); assert_equals(typeof instanceDesc.value, "function"); assert_equals(instanceDesc.writable, true); assert_equals(instanceDesc.enumerable, false); assert_equals(instanceDesc.configurable, true); Instance = WebAssembly.Instance; }, "'WebAssembly.Instance' data property"); test(() => { const instanceDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Instance'); assert_equals(Instance, instanceDesc.value); assert_equals(Instance.length, 1); assert_equals(Instance.name, "Instance"); assertThrows(() => Instance(), TypeError); assertThrows(() => new Instance(1), TypeError); assertThrows(() => new Instance({}), TypeError); assertThrows(() => new Instance(emptyModule, null), TypeError); assertThrows(() => new Instance(importingModule, null), TypeError); assertThrows(() => new Instance(importingModule, undefined), TypeError); assertThrows(() => new Instance(importingModule, {}), TypeError); assertThrows(() => new Instance(importingModule, {"":{g:()=>{}}}), LinkError); assertThrows(() => new Instance(importingModule, {t:{f:()=>{}}}), TypeError); assert_equals(new Instance(emptyModule) instanceof Instance, true); assert_equals(new Instance(emptyModule, {}) instanceof Instance, true); }, "'WebAssembly.Instance' constructor function"); test(() => { const instanceProtoDesc = Object.getOwnPropertyDescriptor(Instance, 'prototype'); assert_equals(typeof instanceProtoDesc.value, "object"); assert_equals(instanceProtoDesc.writable, false); assert_equals(instanceProtoDesc.enumerable, false); assert_equals(instanceProtoDesc.configurable, false); }, "'WebAssembly.Instance.prototype' data property"); test(() => { instanceProto = Instance.prototype; const instanceProtoDesc = Object.getOwnPropertyDescriptor(Instance, 'prototype'); assert_equals(instanceProto, instanceProtoDesc.value); assert_equals(String(instanceProto), "[object WebAssembly.Instance]"); assert_equals(Object.getPrototypeOf(instanceProto), Object.prototype); }, "'WebAssembly.Instance.prototype' object"); test(() => { const instanceProto = Instance.prototype; exportingInstance = new Instance(exportingModule); assert_equals(typeof exportingInstance, "object"); assert_equals(String(exportingInstance), "[object WebAssembly.Instance]"); assert_equals(Object.getPrototypeOf(exportingInstance), instanceProto); }, "'WebAssembly.Instance' instance objects"); test(() => { const exportsDesc = Object.getOwnPropertyDescriptor(instanceProto, 'exports'); assert_equals(typeof exportsDesc.get, "function"); assert_equals(exportsDesc.set, undefined); assert_equals(exportsDesc.enumerable, false); assert_equals(exportsDesc.configurable, true); const exportsGetter = exportsDesc.get; assertThrows(() => exportsGetter.call(), TypeError); assertThrows(() => exportsGetter.call({}), TypeError); assert_equals(typeof exportsGetter.call(exportingInstance), "object"); }, "'WebAssembly.Instance.prototype.exports' accessor property"); test(() => { exportsObj = exportingInstance.exports; assert_equals(typeof exportsObj, "object"); assert_equals(Object.isExtensible(exportsObj), false); assert_equals(Object.getPrototypeOf(exportsObj), null); assert_equals(Object.keys(exportsObj).join(), "f"); exportsObj.g = 1; assert_equals(Object.keys(exportsObj).join(), "f"); assertThrows(() => Object.setPrototypeOf(exportsObj, {}), TypeError); assert_equals(Object.getPrototypeOf(exportsObj), null); assertThrows(() => Object.defineProperty(exportsObj, 'g', {}), TypeError); assert_equals(Object.keys(exportsObj).join(), "f"); }, "exports object"); test(() => { const f = exportsObj.f; assert_equals(f instanceof Function, true); assert_equals(f.length, 0); assert_equals('name' in f, true); assert_equals(Function.prototype.call.call(f), 42); assertThrows(() => new f(), TypeError); }, "Exported WebAssembly functions"); test(() => { const memoryDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Memory'); assert_equals(typeof memoryDesc.value, "function"); assert_equals(memoryDesc.writable, true); assert_equals(memoryDesc.enumerable, false); assert_equals(memoryDesc.configurable, true); Memory = WebAssembly.Memory; }, "'WebAssembly.Memory' data property"); test(() => { const memoryDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Memory'); assert_equals(Memory, memoryDesc.value); assert_equals(Memory.length, 1); assert_equals(Memory.name, "Memory"); assertThrows(() => Memory(), TypeError); assertThrows(() => new Memory(1), TypeError); assertThrows(() => new Memory({initial:{valueOf() { throw new Error("here")}}}), Error); assertThrows(() => new Memory({initial:-1}), RangeError); assertThrows(() => new Memory({initial:Math.pow(2,32)}), RangeError); assertThrows(() => new Memory({initial:1, maximum: Math.pow(2,32)/Math.pow(2,14) }), RangeError); assertThrows(() => new Memory({initial:2, maximum:1 }), RangeError); assertThrows(() => new Memory({maximum: -1 }), RangeError); assert_equals(new Memory({initial:1}) instanceof Memory, true); assert_equals(new Memory({initial:1.5}).buffer.byteLength, WasmPage); }, "'WebAssembly.Memory' constructor function"); test(() => { const memoryProtoDesc = Object.getOwnPropertyDescriptor(Memory, 'prototype'); assert_equals(typeof memoryProtoDesc.value, "object"); assert_equals(memoryProtoDesc.writable, false); assert_equals(memoryProtoDesc.enumerable, false); assert_equals(memoryProtoDesc.configurable, false); }, "'WebAssembly.Memory.prototype' data property"); test(() => { memoryProto = Memory.prototype; const memoryProtoDesc = Object.getOwnPropertyDescriptor(Memory, 'prototype'); assert_equals(memoryProto, memoryProtoDesc.value); assert_equals(String(memoryProto), "[object WebAssembly.Memory]"); assert_equals(Object.getPrototypeOf(memoryProto), Object.prototype); }, "'WebAssembly.Memory.prototype' object"); test(() => { mem1 = new Memory({initial:1}); assert_equals(typeof mem1, "object"); assert_equals(String(mem1), "[object WebAssembly.Memory]"); assert_equals(Object.getPrototypeOf(mem1), memoryProto); }, "'WebAssembly.Memory' instance objects"); test(() => { const bufferDesc = Object.getOwnPropertyDescriptor(memoryProto, 'buffer'); assert_equals(typeof bufferDesc.get, "function"); assert_equals(bufferDesc.set, undefined); assert_equals(bufferDesc.enumerable, false); assert_equals(bufferDesc.configurable, true); }, "'WebAssembly.Memory.prototype.buffer' accessor property"); test(() => { const bufferDesc = Object.getOwnPropertyDescriptor(memoryProto, 'buffer'); const bufferGetter = bufferDesc.get; assertThrows(() => bufferGetter.call(), TypeError); assertThrows(() => bufferGetter.call({}), TypeError); assert_equals(bufferGetter.call(mem1) instanceof ArrayBuffer, true); assert_equals(bufferGetter.call(mem1).byteLength, WasmPage); }, "'WebAssembly.Memory.prototype.buffer' getter"); test(() => { const memGrowDesc = Object.getOwnPropertyDescriptor(memoryProto, 'grow'); assert_equals(typeof memGrowDesc.value, "function"); assert_equals(memGrowDesc.enumerable, false); assert_equals(memGrowDesc.configurable, true); }, "'WebAssembly.Memory.prototype.grow' data property"); test(() => { const memGrowDesc = Object.getOwnPropertyDescriptor(memoryProto, 'grow'); const memGrow = memGrowDesc.value; assert_equals(memGrow.length, 1); assertThrows(() => memGrow.call(), TypeError); assertThrows(() => memGrow.call({}), TypeError); assertThrows(() => memGrow.call(mem1, -1), RangeError); assertThrows(() => memGrow.call(mem1, Math.pow(2,32)), RangeError); var mem = new Memory({initial:1, maximum:2}); var buf = mem.buffer; assert_equals(buf.byteLength, WasmPage); assert_equals(mem.grow(0), 1); assert_equals(buf !== mem.buffer, true); assert_equals(buf.byteLength, 0); buf = mem.buffer; assert_equals(buf.byteLength, WasmPage); assert_equals(mem.grow(1), 1); assert_equals(buf !== mem.buffer, true); assert_equals(buf.byteLength, 0); buf = mem.buffer; assert_equals(buf.byteLength, 2 * WasmPage); assertThrows(() => mem.grow(1), Error); assert_equals(buf, mem.buffer); }, "'WebAssembly.Memory.prototype.grow' method"); test(() => { const tableDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Table'); assert_equals(typeof tableDesc.value, "function"); assert_equals(tableDesc.writable, true); assert_equals(tableDesc.enumerable, false); assert_equals(tableDesc.configurable, true); Table = WebAssembly.Table; }, "'WebAssembly.Table' data property"); test(() => { const tableDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Table'); assert_equals(Table, tableDesc.value); assert_equals(Table.length, 1); assert_equals(Table.name, "Table"); assertThrows(() => Table(), TypeError); assertThrows(() => new Table(1), TypeError); assertThrows(() => new Table({initial:1, element:1}), TypeError); assertThrows(() => new Table({initial:1, element:"any"}), TypeError); assertThrows(() => new Table({initial:1, element:{valueOf() { return "anyfunc" }}}), TypeError); assertThrows(() => new Table({initial:{valueOf() { throw new Error("here")}}, element:"anyfunc"}), Error); assertThrows(() => new Table({initial:-1, element:"anyfunc"}), RangeError); assertThrows(() => new Table({initial:Math.pow(2,32), element:"anyfunc"}), RangeError); assertThrows(() => new Table({initial:2, maximum:1, element:"anyfunc"}), RangeError); assertThrows(() => new Table({initial:2, maximum:Math.pow(2,32), element:"anyfunc"}), RangeError); assert_equals(new Table({initial:1, element:"anyfunc"}) instanceof Table, true); assert_equals(new Table({initial:1.5, element:"anyfunc"}) instanceof Table, true); assert_equals(new Table({initial:1, maximum:1.5, element:"anyfunc"}) instanceof Table, true); assert_equals(new Table({initial:1, maximum:Math.pow(2,32)-1, element:"anyfunc"}) instanceof Table, true); }, "'WebAssembly.Table' constructor function"); test(() => { const tableProtoDesc = Object.getOwnPropertyDescriptor(Table, 'prototype'); assert_equals(typeof tableProtoDesc.value, "object"); assert_equals(tableProtoDesc.writable, false); assert_equals(tableProtoDesc.enumerable, false); assert_equals(tableProtoDesc.configurable, false); }, "'WebAssembly.Table.prototype' data property"); test(() => { const tableProtoDesc = Object.getOwnPropertyDescriptor(Table, 'prototype'); tableProto = Table.prototype; assert_equals(tableProto, tableProtoDesc.value); assert_equals(String(tableProto), "[object WebAssembly.Table]"); assert_equals(Object.getPrototypeOf(tableProto), Object.prototype); }, "'WebAssembly.Table.prototype' object"); test(() => { tbl1 = new Table({initial:2, element:"anyfunc"}); assert_equals(typeof tbl1, "object"); assert_equals(String(tbl1), "[object WebAssembly.Table]"); assert_equals(Object.getPrototypeOf(tbl1), tableProto); }, "'WebAssembly.Table' instance objects"); test(() => { const lengthDesc = Object.getOwnPropertyDescriptor(tableProto, 'length'); assert_equals(typeof lengthDesc.get, "function"); assert_equals(lengthDesc.set, undefined); assert_equals(lengthDesc.enumerable, false); assert_equals(lengthDesc.configurable, true); }, "'WebAssembly.Table.prototype.length' accessor data property"); test(() => { const lengthDesc = Object.getOwnPropertyDescriptor(tableProto, 'length'); const lengthGetter = lengthDesc.get; assert_equals(lengthGetter.length, 0); assertThrows(() => lengthGetter.call(), TypeError); assertThrows(() => lengthGetter.call({}), TypeError); assert_equals(typeof lengthGetter.call(tbl1), "number"); assert_equals(lengthGetter.call(tbl1), 2); }, "'WebAssembly.Table.prototype.length' getter"); test(() => { const getDesc = Object.getOwnPropertyDescriptor(tableProto, 'get'); assert_equals(typeof getDesc.value, "function"); assert_equals(getDesc.enumerable, false); assert_equals(getDesc.configurable, true); }, "'WebAssembly.Table.prototype.get' data property"); test(() => { const getDesc = Object.getOwnPropertyDescriptor(tableProto, 'get'); const get = getDesc.value; assert_equals(get.length, 1); assertThrows(() => get.call(), TypeError); assertThrows(() => get.call({}), TypeError); assert_equals(get.call(tbl1, 0), null); assert_equals(get.call(tbl1, 1), null); assert_equals(get.call(tbl1, 1.5), null); assertThrows(() => get.call(tbl1, 2), RangeError); assertThrows(() => get.call(tbl1, 2.5), RangeError); assertThrows(() => get.call(tbl1, -1), RangeError); assertThrows(() => get.call(tbl1, Math.pow(2,33)), RangeError); assertThrows(() => get.call(tbl1, {valueOf() { throw new Error("hi") }}), Error); }, "'WebAssembly.Table.prototype.get' method"); test(() => { const setDesc = Object.getOwnPropertyDescriptor(tableProto, 'set'); assert_equals(typeof setDesc.value, "function"); assert_equals(setDesc.enumerable, false); assert_equals(setDesc.configurable, true); }, "'WebAssembly.Table.prototype.set' data property"); test(() => { const setDesc = Object.getOwnPropertyDescriptor(tableProto, 'set'); const set = setDesc.value; assert_equals(set.length, 2); assertThrows(() => set.call(), TypeError); assertThrows(() => set.call({}), TypeError); assertThrows(() => set.call(tbl1, 0), TypeError); assertThrows(() => set.call(tbl1, 2, null), RangeError); assertThrows(() => set.call(tbl1, -1, null), RangeError); assertThrows(() => set.call(tbl1, Math.pow(2,33), null), RangeError); assertThrows(() => set.call(tbl1, 0, undefined), TypeError); assertThrows(() => set.call(tbl1, 0, {}), TypeError); assertThrows(() => set.call(tbl1, 0, function() {}), TypeError); assertThrows(() => set.call(tbl1, 0, Math.sin), TypeError); assertThrows(() => set.call(tbl1, {valueOf() { throw Error("hai") }}, null), Error); assert_equals(set.call(tbl1, 0, null), undefined); assert_equals(set.call(tbl1, 1, null), undefined); }, "'WebAssembly.Table.prototype.set' method"); test(() => { const tblGrowDesc = Object.getOwnPropertyDescriptor(tableProto, 'grow'); assert_equals(typeof tblGrowDesc.value, "function"); assert_equals(tblGrowDesc.enumerable, false); assert_equals(tblGrowDesc.configurable, true); }, "'WebAssembly.Table.prototype.grow' data property"); test(() => { const tblGrowDesc = Object.getOwnPropertyDescriptor(tableProto, 'grow'); const tblGrow = tblGrowDesc.value; assert_equals(tblGrow.length, 1); assertThrows(() => tblGrow.call(), TypeError); assertThrows(() => tblGrow.call({}), TypeError); assertThrows(() => tblGrow.call(tbl1, -1), RangeError); assertThrows(() => tblGrow.call(tbl1, Math.pow(2,32)), RangeError); var tbl = new Table({element:"anyfunc", initial:1, maximum:2}); assert_equals(tbl.length, 1); assert_equals(tbl.grow(0), 1); assert_equals(tbl.length, 1); assert_equals(tbl.grow(1), 1); assert_equals(tbl.length, 2); assertThrows(() => tbl.grow(1), Error); }, "'WebAssembly.Table.prototype.grow' method"); test(() => { assertThrows(() => WebAssembly.validate(), TypeError); assertThrows(() => WebAssembly.validate("hi"), TypeError); assert_true(WebAssembly.validate(emptyModuleBinary)); assert_true(WebAssembly.validate(complexImportingModuleBinary)); assert_false(WebAssembly.validate(moduleBinaryImporting2Memories)); assert_false(WebAssembly.validate(moduleBinaryWithMemSectionAndMemImport)); }, "'WebAssembly.validate' method"); /* FIXME https://bugs.webkit.org/show_bug.cgi?id=173180 test(() => { const compileDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'compile'); assert_equals(typeof compileDesc.value, "function"); assert_equals(compileDesc.writable, true); assert_equals(compileDesc.enumerable, false); assert_equals(compileDesc.configurable, true); }, "'WebAssembly.compile' data property"); test(() => { const compile = WebAssembly.compile; const compileDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'compile'); assert_equals(compile, compileDesc.value); assert_equals(compile.length, 1); assert_equals(compile.name, "compile"); }, "'WebAssembly.compile' function"); */ var num_tests = 1; function assertCompileError(args, err) { promise_test(() => { return WebAssembly.compile(...args) .then(_ => { throw null; }) .catch(error => { assert_equals(error instanceof err, true); return Promise.resolve() }); }, `assertCompileError ${num_tests++}`); } assertCompileError([], TypeError); assertCompileError([undefined], TypeError); assertCompileError([1], TypeError); assertCompileError([{}], TypeError); assertCompileError([new Uint8Array()], CompileError); assertCompileError([new ArrayBuffer()], CompileError); // FIXME: https://github.com/WebAssembly/spec/pull/503 //assertCompileError([new Uint8Array("hi!")], CompileError); //assertCompileError([new ArrayBuffer("hi!")], CompileError); num_tests = 1; function assertCompileSuccess(bytes) { promise_test(() => { return WebAssembly.compile(bytes) .then(module => { assert_equals(module instanceof Module, true); }); }, `assertCompileSuccess ${num_tests++}`); } assertCompileSuccess(emptyModuleBinary); assertCompileSuccess(new Uint8Array(emptyModuleBinary)); /* FIXME https://bugs.webkit.org/show_bug.cgi?id=173180 test(() => { const instantiateDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'instantiate'); assert_equals(typeof instantiateDesc.value, "function"); assert_equals(instantiateDesc.writable, true); assert_equals(instantiateDesc.enumerable, false); assert_equals(instantiateDesc.configurable, true); }, "'WebAssembly.instantiate' data property");*/ test(() => { const instantiateDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'instantiate'); const instantiate = WebAssembly.instantiate; /* FIXME https://bugs.webkit.org/show_bug.cgi?id=173180 assert_equals(instantiate, instantiateDesc.value); assert_equals(instantiate.length, 1); assert_equals(instantiate.name, "instantiate");*/ function assertInstantiateError(args, err) { promise_test(() => { return instantiate(...args) .then(m => { throw null; }) .catch(error => { assert_equals(error instanceof err, true); }) }, 'unexpected success in assertInstantiateError'); } var scratch_memory = new WebAssembly.Memory({initial:1}); var scratch_table = new WebAssembly.Table({element:"anyfunc", initial:1, maximum:1}); assertInstantiateError([], TypeError); assertInstantiateError([undefined], TypeError); assertInstantiateError([1], TypeError); assertInstantiateError([{}], TypeError); assertInstantiateError([new Uint8Array()], CompileError); assertInstantiateError([new ArrayBuffer()], CompileError); // FIXME: https://github.com/WebAssembly/spec/pull/503 // assertInstantiateError([new Uint8Array("hi!")], CompileError); // assertInstantiateError([new ArrayBuffer("hi!")], CompileError); assertInstantiateError([importingModule], TypeError); assertInstantiateError([importingModule, null], TypeError); assertInstantiateError([importingModuleBinary, null], TypeError); assertInstantiateError([emptyModule, null], TypeError); assertInstantiateError([importingModuleBinary, null], TypeError); assertInstantiateError([importingModuleBinary, undefined], TypeError); assertInstantiateError([importingModuleBinary, {}], TypeError); assertInstantiateError([importingModuleBinary, {"":{g:()=>{}}}], LinkError); assertInstantiateError([importingModuleBinary, {t:{f:()=>{}}}], TypeError); assertInstantiateError([complexImportingModuleBinary, null], TypeError); assertInstantiateError([complexImportingModuleBinary, undefined], TypeError); assertInstantiateError([complexImportingModuleBinary, {}], TypeError); assertInstantiateError([complexImportingModuleBinary, {"c": {"d": scratch_memory}}], TypeError); function assertInstantiateSuccess(module, imports) { promise_test(()=> { return instantiate(module, imports) .then(result => { if (module instanceof Module) { assert_equals(result instanceof Instance, true); } else { assert_equals(result.module instanceof Module, true); assert_equals(result.instance instanceof Instance, true); var desc = Object.getOwnPropertyDescriptor(result, 'module'); assert_equals(desc.writable, true); assert_equals(desc.enumerable, true); assert_equals(desc.configurable, true); desc = Object.getOwnPropertyDescriptor(result, 'instance'); assert_equals(desc.writable, true); assert_equals(desc.enumerable, true); assert_equals(desc.configurable, true); } })}, 'unexpected failure in assertInstantiateSuccess'); } assertInstantiateSuccess(emptyModule); assertInstantiateSuccess(emptyModuleBinary); assertInstantiateSuccess(new Uint8Array(emptyModuleBinary)); assertInstantiateSuccess(importingModule, {"":{f:()=>{}}}); assertInstantiateSuccess(importingModuleBinary, {"":{f:()=>{}}}); assertInstantiateSuccess(new Uint8Array(importingModuleBinary), {"":{f:()=>{}}}); assertInstantiateSuccess(complexImportingModuleBinary, { a:{b:()=>{}}, c:{d:scratch_memory}, e:{f:scratch_table}, g:{'⚡':1}}); }, "'WebAssembly.instantiate' function"); })();