blob: d2489f3e89d71acbc9e4597834f5b98dc58d32e8 [file] [log] [blame]
// 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-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);
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]);
let promise = WebAssembly.compile(builder.toBuffer());
assertPromiseResult(
promise, compiled => assertUnreachable(
'should not be able to compile invalid blob.'),
e => assertInstanceof(e, 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);
})();