// Copyright 2015 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Flags: --expose-wasm load("test/mjsunit/wasm/wasm-constants.js"); load("test/mjsunit/wasm/wasm-module-builder.js"); let kReturnValue = 17; let buffer = (() => { let builder = new WasmModuleBuilder(); builder.addMemory(1, 1, true); builder.addFunction("main", kSig_i_v) .addBody([kExprI32Const, kReturnValue]) .exportFunc(); return builder.toBuffer(); })() function CheckInstance(instance) { assertFalse(instance === undefined); assertFalse(instance === null); assertFalse(instance === 0); assertEquals("object", typeof instance); // Check the exports object is frozen. assertFalse(Object.isExtensible(instance.exports)); assertTrue(Object.isFrozen(instance.exports)); // Check the memory is WebAssembly.Memory. var mem = instance.exports.memory; assertFalse(mem === undefined); assertFalse(mem === null); assertFalse(mem === 0); assertEquals("object", typeof mem); assertTrue(mem instanceof WebAssembly.Memory); var buf = mem.buffer; assertTrue(buf instanceof ArrayBuffer); assertEquals(65536, buf.byteLength); for (var i = 0; i < 4; i++) { instance.exports.memory = 0; // should be ignored mem.buffer = 0; // should be ignored assertSame(mem, instance.exports.memory); assertSame(buf, mem.buffer); } // Check the properties of the main function. let main = instance.exports.main; assertFalse(main === undefined); assertFalse(main === null); assertFalse(main === 0); assertEquals("function", typeof main); assertEquals(kReturnValue, main()); } // Official API (function BasicJSAPITest() { print("sync module compile..."); let module = new WebAssembly.Module(buffer); print("sync module instantiate..."); CheckInstance(new WebAssembly.Instance(module)); print("async module compile..."); let promise = WebAssembly.compile(buffer); promise.then(module => CheckInstance(new WebAssembly.Instance(module))); print("async instantiate..."); let instance_promise = WebAssembly.instantiate(buffer); instance_promise.then(CheckInstance); })(); // Check that validate works correctly for a module. assertTrue(WebAssembly.validate(buffer)); assertFalse(WebAssembly.validate(bytes(88, 88, 88, 88, 88, 88, 88, 88))); // Negative tests. (function InvalidModules() { print("InvalidModules..."); let invalid_cases = [undefined, 1, "", "a", {some:1, obj: "b"}]; let len = invalid_cases.length; for (var i = 0; i < len; ++i) { try { let instance = new WebAssembly.Instance(invalid_cases[i]); assertUnreachable("should not be able to instantiate invalid modules."); } catch (e) { assertContains("Argument 0", e.toString()); } } })(); // Compile async an invalid blob. (function InvalidBinaryAsyncCompilation() { print("InvalidBinaryAsyncCompilation..."); let builder = new WasmModuleBuilder(); builder.addFunction("f", kSig_i_i) .addBody([kExprCallFunction, 0]); let promise = WebAssembly.compile(builder.toBuffer()); promise .then(compiled => assertUnreachable("should not be able to compile invalid blob.")) .catch(e => assertContains("invalid signature index", e.toString())); })(); // Multiple instances tests. (function ManyInstances() { print("ManyInstances..."); let compiled_module = new WebAssembly.Module(buffer); let instance_1 = new WebAssembly.Instance(compiled_module); let instance_2 = new WebAssembly.Instance(compiled_module); assertTrue(instance_1 != instance_2); })(); (function ManyInstancesAsync() { print("ManyInstancesAsync..."); let promise = WebAssembly.compile(buffer); promise.then(compiled_module => { let instance_1 = new WebAssembly.Instance(compiled_module); let instance_2 = new WebAssembly.Instance(compiled_module); assertTrue(instance_1 != instance_2); }); })(); (function InstancesAreIsolatedFromEachother() { print("InstancesAreIsolatedFromEachother..."); var builder = new WasmModuleBuilder(); builder.addImportedMemory("", "memory", 1); var kSig_v_i = makeSig([kWasmI32], []); var signature = builder.addType(kSig_v_i); builder.addImport("m", "some_value", kSig_i_v); builder.addImport("m", "writer", signature); builder.addFunction("main", kSig_i_i) .addBody([ kExprGetLocal, 0, kExprI32LoadMem, 0, 0, kExprI32Const, 1, kExprCallIndirect, signature, kTableZero, kExprGetLocal,0, kExprI32LoadMem,0, 0, kExprCallFunction, 0, kExprI32Add ]).exportFunc(); // writer(mem[i]); // return mem[i] + some_value(); builder.addFunction("_wrap_writer", signature) .addBody([ kExprGetLocal, 0, kExprCallFunction, 1]); builder.appendToTable([2, 3]); var module = new WebAssembly.Module(builder.toBuffer()); var mem_1 = new WebAssembly.Memory({initial: 1}); var mem_2 = new WebAssembly.Memory({initial: 1}); var view_1 = new Int32Array(mem_1.buffer); var view_2 = new Int32Array(mem_2.buffer); view_1[0] = 42; view_2[0] = 1000; var outval_1; var outval_2; var i1 = new WebAssembly.Instance(module, {m: {some_value: () => 1, writer: (x)=>outval_1 = x }, "": {memory: mem_1}}); var i2 = new WebAssembly.Instance(module, {m: {some_value: () => 2, writer: (x)=>outval_2 = x }, "": {memory: mem_2}}); assertEquals(43, i1.exports.main(0)); assertEquals(1002, i2.exports.main(0)); assertEquals(42, outval_1); assertEquals(1000, outval_2); })(); (function GlobalsArePrivateToTheInstance() { print("GlobalsArePrivateToTheInstance..."); var builder = new WasmModuleBuilder(); builder.addGlobal(kWasmI32, true); builder.addFunction("read", kSig_i_v) .addBody([ kExprGetGlobal, 0]) .exportFunc(); builder.addFunction("write", kSig_v_i) .addBody([ kExprGetLocal, 0, kExprSetGlobal, 0]) .exportFunc(); var module = new WebAssembly.Module(builder.toBuffer()); var i1 = new WebAssembly.Instance(module); var i2 = new WebAssembly.Instance(module); i1.exports.write(1); i2.exports.write(2); assertEquals(1, i1.exports.read()); assertEquals(2, i2.exports.read()); })(); (function InstanceMemoryIsIsolated() { print("InstanceMemoryIsIsolated..."); var builder = new WasmModuleBuilder(); builder.addImportedMemory("", "memory", 1); builder.addFunction("f", kSig_i_v) .addBody([ kExprI32Const, 0, kExprI32LoadMem, 0, 0 ]).exportFunc(); var mem_1 = new WebAssembly.Memory({initial: 1}); var mem_2 = new WebAssembly.Memory({initial: 1}); var view_1 = new Int32Array(mem_1.buffer); var view_2 = new Int32Array(mem_2.buffer); view_1[0] = 1; view_2[0] = 1000; var module = new WebAssembly.Module(builder.toBuffer()); var i1 = new WebAssembly.Instance(module, {"":{memory:mem_1}}); var i2 = new WebAssembly.Instance(module, {"":{memory:mem_2}}); assertEquals(1, i1.exports.f()); assertEquals(1000, i2.exports.f()); })(); (function MustBeMemory() { print("MustBeMemory..."); var memory = new ArrayBuffer(65536); let builder = new WasmModuleBuilder(); builder.addImportedMemory("", "memory"); let module = new WebAssembly.Module(builder.toBuffer()); assertThrows(() => new WebAssembly.Instance(module, {"":{memory:memory}}), WebAssembly.LinkError); })(); (function TestNoMemoryToExport() { let builder = new WasmModuleBuilder(); builder.exportMemoryAs('memory'); assertThrows(() => builder.instantiate(), WebAssembly.CompileError); })(); (function TestIterableExports() { print("TestIterableExports..."); let builder = new WasmModuleBuilder; builder.addExport("a", builder.addFunction("", kSig_v_v).addBody([])); builder.addExport("b", builder.addFunction("", kSig_v_v).addBody([])); builder.addExport("c", builder.addFunction("", kSig_v_v).addBody([])); builder.addExport("d", builder.addFunction("", kSig_v_v).addBody([])); builder.addExport("e", builder.addGlobal(kWasmI32, false)); let module = new WebAssembly.Module(builder.toBuffer()); let instance = new WebAssembly.Instance(module); let exports_count = 0; for (var e in instance.exports) ++exports_count; assertEquals(5, exports_count); })();