1876767992
This brings our constants back in line with the changed spec text. We already use kExprTableGet and kExprTableSet, but for locals and globals we still use the old wording. This renaming is mostly mechanical. PS1 was created using: ag -l 'kExpr(Get|Set)Global' src test | \ xargs -L1 sed -E 's/kExpr(Get|Set)Global\b/kExprGlobal\1/g' -i PS2 contains manual fixes. R=mstarzinger@chromium.org Bug: v8:9810 Change-Id: I064a6448cd95bc24d31a5931b5b4ef2464ea88b1 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1847355 Commit-Queue: Clemens Backes <clemensb@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#64163}
407 lines
14 KiB
JavaScript
407 lines
14 KiB
JavaScript
// 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 --expose-gc
|
|
|
|
load("test/mjsunit/wasm/wasm-module-builder.js");
|
|
|
|
(function SerializeAndDeserializeModule() {
|
|
print(arguments.callee.name);
|
|
var builder = new WasmModuleBuilder();
|
|
builder.addImportedMemory("", "memory", 1);
|
|
var kSig_v_i = makeSig([kWasmI32], []);
|
|
var signature = builder.addType(kSig_v_i);
|
|
builder.addImport("", "some_value", kSig_i_v);
|
|
builder.addImport("", "writer", signature);
|
|
|
|
builder.addFunction("main", kSig_i_i)
|
|
.addBody([
|
|
kExprLocalGet, 0,
|
|
kExprI32LoadMem, 0, 0,
|
|
kExprI32Const, 1,
|
|
kExprCallIndirect, signature, kTableZero,
|
|
kExprLocalGet,0,
|
|
kExprI32LoadMem,0, 0,
|
|
kExprCallFunction, 0,
|
|
kExprI32Add
|
|
]).exportFunc();
|
|
|
|
// writer(mem[i]);
|
|
// return mem[i] + some_value();
|
|
builder.addFunction("_wrap_writer", signature)
|
|
.addBody([
|
|
kExprLocalGet, 0,
|
|
kExprCallFunction, 1]);
|
|
builder.appendToTable([2, 3]);
|
|
|
|
var wire_bytes = builder.toBuffer();
|
|
var module = new WebAssembly.Module(wire_bytes);
|
|
var mem_1 = new WebAssembly.Memory({initial: 1});
|
|
var view_1 = new Int32Array(mem_1.buffer);
|
|
view_1[0] = 42;
|
|
var outval_1;
|
|
var i1 = new WebAssembly.Instance(module, {"":
|
|
{some_value: () => 1,
|
|
writer: (x) => outval_1 = x ,
|
|
memory: mem_1}
|
|
});
|
|
|
|
assertEquals(43, i1.exports.main(0));
|
|
|
|
assertEquals(42, outval_1);
|
|
var buff = %SerializeWasmModule(module);
|
|
module = null;
|
|
gc();
|
|
module = %DeserializeWasmModule(buff, wire_bytes);
|
|
|
|
var mem_2 = new WebAssembly.Memory({initial: 2});
|
|
var view_2 = new Int32Array(mem_2.buffer);
|
|
|
|
view_2[0] = 50;
|
|
|
|
var outval_2;
|
|
var i2 = new WebAssembly.Instance(module, {"":
|
|
{some_value: () => 1,
|
|
writer: (x) => outval_2 = x ,
|
|
memory: mem_2}
|
|
});
|
|
|
|
assertEquals(51, i2.exports.main(0));
|
|
|
|
assertEquals(50, outval_2);
|
|
// The instances don't share memory through deserialization.
|
|
assertEquals(43, i1.exports.main(0));
|
|
})();
|
|
|
|
(function DeserializeInvalidObject() {
|
|
print(arguments.callee.name);
|
|
const invalid_buffer = new ArrayBuffer(10);
|
|
const invalid_buffer_view = new Uint8Array(10);
|
|
|
|
module = %DeserializeWasmModule(invalid_buffer, invalid_buffer_view);
|
|
assertEquals(module, undefined);
|
|
})();
|
|
|
|
(function RelationBetweenModuleAndClone() {
|
|
print(arguments.callee.name);
|
|
let builder = new WasmModuleBuilder();
|
|
builder.addFunction("main", kSig_i_v)
|
|
.addBody([kExprI32Const, 42])
|
|
.exportFunc();
|
|
|
|
var wire_bytes = builder.toBuffer();
|
|
var compiled_module = new WebAssembly.Module(wire_bytes);
|
|
var serialized = %SerializeWasmModule(compiled_module);
|
|
var clone = %DeserializeWasmModule(serialized, wire_bytes);
|
|
|
|
assertNotNull(clone);
|
|
assertFalse(clone == undefined);
|
|
assertFalse(clone == compiled_module);
|
|
assertEquals(clone.constructor, compiled_module.constructor);
|
|
})();
|
|
|
|
(function SerializeWrappersWithSameSignature() {
|
|
print(arguments.callee.name);
|
|
let builder = new WasmModuleBuilder();
|
|
builder.addFunction("main", kSig_i_v)
|
|
.addBody([kExprI32Const, 42])
|
|
.exportFunc();
|
|
builder.addFunction("main_same_signature", kSig_i_v)
|
|
.addBody([kExprI32Const, 23])
|
|
.exportFunc();
|
|
|
|
var wire_bytes = builder.toBuffer();
|
|
var compiled_module = new WebAssembly.Module(wire_bytes);
|
|
var serialized = %SerializeWasmModule(compiled_module);
|
|
var clone = %DeserializeWasmModule(serialized, wire_bytes);
|
|
|
|
assertNotNull(clone);
|
|
assertFalse(clone == undefined);
|
|
assertFalse(clone == compiled_module);
|
|
assertEquals(clone.constructor, compiled_module.constructor);
|
|
})();
|
|
|
|
(function SerializeAfterInstantiation() {
|
|
print(arguments.callee.name);
|
|
let builder = new WasmModuleBuilder();
|
|
builder.addFunction("main", kSig_i_v)
|
|
.addBody([kExprI32Const, 42])
|
|
.exportFunc();
|
|
|
|
var wire_bytes = builder.toBuffer()
|
|
var compiled_module = new WebAssembly.Module(wire_bytes);
|
|
var instance1 = new WebAssembly.Instance(compiled_module);
|
|
var instance2 = new WebAssembly.Instance(compiled_module);
|
|
var serialized = %SerializeWasmModule(compiled_module);
|
|
var clone = %DeserializeWasmModule(serialized, wire_bytes);
|
|
|
|
assertNotNull(clone);
|
|
assertFalse(clone == undefined);
|
|
assertFalse(clone == compiled_module);
|
|
assertEquals(clone.constructor, compiled_module.constructor);
|
|
var instance3 = new WebAssembly.Instance(clone);
|
|
assertFalse(instance3 == undefined);
|
|
})();
|
|
|
|
|
|
(function SerializeAfterInstantiationWithMemory() {
|
|
print(arguments.callee.name);
|
|
let builder = new WasmModuleBuilder();
|
|
builder.addImportedMemory("", "memory", 1);
|
|
builder.addFunction("main", kSig_i_v)
|
|
.addBody([kExprI32Const, 42])
|
|
.exportFunc();
|
|
|
|
var wire_bytes = builder.toBuffer()
|
|
var compiled_module = new WebAssembly.Module(wire_bytes);
|
|
var mem_1 = new WebAssembly.Memory({initial: 1});
|
|
var ffi = {"":{memory:mem_1}};
|
|
var instance1 = new WebAssembly.Instance(compiled_module, ffi);
|
|
var serialized = %SerializeWasmModule(compiled_module);
|
|
var clone = %DeserializeWasmModule(serialized, wire_bytes);
|
|
|
|
assertNotNull(clone);
|
|
assertFalse(clone == undefined);
|
|
assertFalse(clone == compiled_module);
|
|
assertEquals(clone.constructor, compiled_module.constructor);
|
|
var instance2 = new WebAssembly.Instance(clone, ffi);
|
|
assertFalse(instance2 == undefined);
|
|
})();
|
|
|
|
(function GlobalsArePrivateBetweenClones() {
|
|
print(arguments.callee.name);
|
|
var builder = new WasmModuleBuilder();
|
|
builder.addGlobal(kWasmI32, true);
|
|
builder.addFunction("read", kSig_i_v)
|
|
.addBody([
|
|
kExprGlobalGet, 0])
|
|
.exportFunc();
|
|
|
|
builder.addFunction("write", kSig_v_i)
|
|
.addBody([
|
|
kExprLocalGet, 0,
|
|
kExprGlobalSet, 0])
|
|
.exportFunc();
|
|
|
|
var wire_bytes = builder.toBuffer();
|
|
var module = new WebAssembly.Module(wire_bytes);
|
|
var i1 = new WebAssembly.Instance(module);
|
|
// serialize and replace module
|
|
var buff = %SerializeWasmModule(module);
|
|
var module_clone = %DeserializeWasmModule(buff, wire_bytes);
|
|
var i2 = new WebAssembly.Instance(module_clone);
|
|
i1.exports.write(1);
|
|
i2.exports.write(2);
|
|
assertEquals(1, i1.exports.read());
|
|
assertEquals(2, i2.exports.read());
|
|
})();
|
|
|
|
(function SharedTableTest() {
|
|
print(arguments.callee.name);
|
|
let kTableSize = 3;
|
|
var sig_index1;
|
|
|
|
function MakeTableExportingModule(constant) {
|
|
// A module that defines a table and exports it.
|
|
var builder = new WasmModuleBuilder();
|
|
builder.addType(kSig_i_i);
|
|
builder.addType(kSig_i_ii);
|
|
sig_index1 = builder.addType(kSig_i_v);
|
|
var f1 = builder.addFunction("f1", sig_index1)
|
|
.addBody([kExprI32Const, constant]);
|
|
|
|
builder.addFunction("main", kSig_i_ii)
|
|
.addBody([
|
|
kExprLocalGet, 0, // --
|
|
kExprCallIndirect, sig_index1, kTableZero]) // --
|
|
.exportAs("main");
|
|
|
|
builder.setTableBounds(kTableSize, kTableSize);
|
|
builder.addElementSegment(0, 0, false, [f1.index]);
|
|
builder.addExportOfKind("table", kExternalTable, 0);
|
|
|
|
return new WebAssembly.Module(builder.toBuffer());
|
|
}
|
|
var m1 = MakeTableExportingModule(11);
|
|
|
|
// Module {m2} imports the table and adds {f2}.
|
|
var builder = new WasmModuleBuilder();
|
|
builder.addType(kSig_i_ii);
|
|
var sig_index2 = builder.addType(kSig_i_v);
|
|
var f2 = builder.addFunction("f2", sig_index2)
|
|
.addBody([kExprI32Const, 22]);
|
|
|
|
builder.addFunction("main", kSig_i_ii)
|
|
.addBody([
|
|
kExprLocalGet, 0, // --
|
|
kExprCallIndirect, sig_index2, kTableZero]) // --
|
|
.exportAs("main");
|
|
|
|
builder.addImportedTable("z", "table", kTableSize, kTableSize);
|
|
builder.addElementSegment(0, 1, false, [f2.index]);
|
|
var m2_bytes = builder.toBuffer();
|
|
var m2 = new WebAssembly.Module(m2_bytes);
|
|
|
|
assertFalse(sig_index1 == sig_index2);
|
|
|
|
var i1 = new WebAssembly.Instance(m1);
|
|
var i2 = new WebAssembly.Instance(m2, {z: {table: i1.exports.table}});
|
|
|
|
var serialized_m2 = %SerializeWasmModule(m2);
|
|
var m2_clone = %DeserializeWasmModule(serialized_m2, m2_bytes);
|
|
|
|
var m3 = MakeTableExportingModule(33);
|
|
var i3 = new WebAssembly.Instance(m3);
|
|
var i2_prime = new WebAssembly.Instance(m2_clone,
|
|
{z: {table: i3.exports.table}});
|
|
|
|
assertEquals(11, i1.exports.main(0));
|
|
assertEquals(11, i2.exports.main(0));
|
|
|
|
assertEquals(22, i1.exports.main(1));
|
|
assertEquals(22, i2.exports.main(1));
|
|
|
|
assertEquals(33, i3.exports.main(0));
|
|
assertEquals(33, i2_prime.exports.main(0));
|
|
|
|
assertThrows(() => i1.exports.main(2));
|
|
assertThrows(() => i2.exports.main(2));
|
|
assertThrows(() => i1.exports.main(3));
|
|
assertThrows(() => i2.exports.main(3));
|
|
})();
|
|
|
|
(function StackOverflowAfterSerialization() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
var fun = builder.addFunction('main', kSig_v_v);
|
|
fun.addBody([kExprCallFunction, fun.index]);
|
|
fun.exportFunc();
|
|
|
|
var wire_bytes = builder.toBuffer();
|
|
var module = new WebAssembly.Module(wire_bytes);
|
|
var buffer = %SerializeWasmModule(module);
|
|
module = %DeserializeWasmModule(buffer, wire_bytes);
|
|
var instance = new WebAssembly.Instance(module);
|
|
|
|
assertThrows(instance.exports.main, RangeError);
|
|
})();
|
|
|
|
(function TrapAfterDeserialization() {
|
|
print(arguments.callee.name);
|
|
function GenerateSerializedModule() {
|
|
const builder = new WasmModuleBuilder();
|
|
builder.addMemory(1, 1);
|
|
builder.addFunction('main', kSig_i_i)
|
|
.addBody([kExprLocalGet, 0, kExprI32LoadMem, 0, 0])
|
|
.exportFunc();
|
|
const wire_bytes = builder.toBuffer();
|
|
const module = new WebAssembly.Module(wire_bytes);
|
|
const buffer = %SerializeWasmModule(module);
|
|
return [wire_bytes, buffer];
|
|
}
|
|
const [wire_bytes, buffer] = GenerateSerializedModule();
|
|
module = %DeserializeWasmModule(buffer, wire_bytes);
|
|
const instance = new WebAssembly.Instance(module);
|
|
|
|
assertEquals(0, instance.exports.main(0));
|
|
assertEquals(0, instance.exports.main(kPageSize - 4));
|
|
assertTraps(
|
|
kTrapMemOutOfBounds, _ => instance.exports.main(kPageSize - 3));
|
|
})();
|
|
|
|
(function DirectCallAfterSerialization() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
var fun1 = builder.addFunction('fun1', kSig_i_v)
|
|
.addBody([kExprI32Const, 23]);
|
|
var fun2 = builder.addFunction('fun2', kSig_i_v)
|
|
.addBody([kExprI32Const, 42]);
|
|
builder.addFunction('main', kSig_i_v)
|
|
.addBody([kExprCallFunction, fun1.index,
|
|
kExprCallFunction, fun2.index,
|
|
kExprI32Add])
|
|
.exportFunc();
|
|
|
|
var wire_bytes = builder.toBuffer();
|
|
var module = new WebAssembly.Module(wire_bytes);
|
|
var buffer = %SerializeWasmModule(module);
|
|
module = %DeserializeWasmModule(buffer, wire_bytes);
|
|
var instance = new WebAssembly.Instance(module);
|
|
|
|
assertEquals(65, instance.exports.main());
|
|
})();
|
|
|
|
(function ImportCallAfterSerialization() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
var fun_import = builder.addImport("", "my_import", kSig_i_v);
|
|
var fun = builder.addFunction('fun', kSig_i_v)
|
|
.addBody([kExprI32Const, 23]);
|
|
builder.addFunction('main', kSig_i_v)
|
|
.addBody([kExprCallFunction, fun.index,
|
|
kExprCallFunction, fun_import,
|
|
kExprI32Add])
|
|
.exportFunc();
|
|
|
|
var wire_bytes = builder.toBuffer();
|
|
var module = new WebAssembly.Module(wire_bytes);
|
|
var buffer = %SerializeWasmModule(module);
|
|
module = %DeserializeWasmModule(buffer, wire_bytes);
|
|
var instance = new WebAssembly.Instance(module, {"": {my_import: () => 42 }});
|
|
|
|
assertEquals(65, instance.exports.main());
|
|
})();
|
|
|
|
(function BranchTableAfterSerialization() {
|
|
print(arguments.callee.name);
|
|
const builder = new WasmModuleBuilder();
|
|
builder.addFunction('main', kSig_i_i)
|
|
.addBody([kExprBlock, kWasmStmt,
|
|
kExprBlock, kWasmStmt,
|
|
kExprBlock, kWasmStmt,
|
|
kExprBlock, kWasmStmt,
|
|
kExprBlock, kWasmStmt,
|
|
kExprBlock, kWasmStmt,
|
|
kExprBlock, kWasmStmt,
|
|
kExprLocalGet, 0,
|
|
kExprBrTable, 6, 0, 1, 2, 3, 4, 5, 6,
|
|
kExprEnd,
|
|
kExprI32Const, 3,
|
|
kExprReturn,
|
|
kExprEnd,
|
|
kExprI32Const, 7,
|
|
kExprReturn,
|
|
kExprEnd,
|
|
kExprI32Const, 9,
|
|
kExprReturn,
|
|
kExprEnd,
|
|
kExprI32Const, 11,
|
|
kExprReturn,
|
|
kExprEnd,
|
|
kExprI32Const, 23,
|
|
kExprReturn,
|
|
kExprEnd,
|
|
kExprI32Const, 35,
|
|
kExprReturn,
|
|
kExprEnd,
|
|
kExprI32Const, 42,
|
|
kExprReturn])
|
|
.exportFunc();
|
|
|
|
var wire_bytes = builder.toBuffer();
|
|
var module = new WebAssembly.Module(wire_bytes);
|
|
var buffer = %SerializeWasmModule(module);
|
|
module = %DeserializeWasmModule(buffer, wire_bytes);
|
|
var instance = new WebAssembly.Instance(module);
|
|
|
|
assertEquals(3, instance.exports.main(0));
|
|
assertEquals(7, instance.exports.main(1));
|
|
assertEquals(9, instance.exports.main(2));
|
|
assertEquals(11, instance.exports.main(3));
|
|
assertEquals(23, instance.exports.main(4));
|
|
assertEquals(35, instance.exports.main(5));
|
|
assertEquals(42, instance.exports.main(6));
|
|
assertEquals(42, instance.exports.main(9));
|
|
})();
|