| // 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 --allow-natives-syntax |
| |
| 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); |
| assertPromiseResult( |
| promise, module => CheckInstance(new WebAssembly.Instance(module))); |
| |
| print('async instantiate...'); |
| let instance_promise = WebAssembly.instantiate(buffer); |
| assertPromiseResult(instance_promise, pair => CheckInstance(pair.instance)); |
| })(); |
| |
| // 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]); |
| assertThrowsAsync( |
| WebAssembly.compile(builder.toBuffer()), WebAssembly.CompileError); |
| })(); |
| |
| // 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); |
| assertPromiseResult(promise, 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); |
| })(); |