2747d0e6da
* If the mutability of the global object doesn't match the module, then it should throw a LinkError. * There was a missing `return` when importing a Number as a mutable global. * All globals were being exported as immutable. * Attempting to set the value of an immutable global should throw a TypeError. * The length of the setter function should be 1. Bug: v8:7625 Change-Id: I08d6a428506a18db15eecadf4cbcee89e0658924 Reviewed-on: https://chromium-review.googlesource.com/1031626 Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Commit-Queue: Ben Smith <binji@chromium.org> Cr-Commit-Position: refs/heads/master@{#52865}
194 lines
6.1 KiB
JavaScript
194 lines
6.1 KiB
JavaScript
// Copyright 2018 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: --experimental-wasm-mut-global --expose-gc
|
|
|
|
load("test/mjsunit/wasm/wasm-constants.js");
|
|
load("test/mjsunit/wasm/wasm-module-builder.js");
|
|
|
|
(function TestBasic() {
|
|
let global = new WebAssembly.Global({type: 'i32'}, 1);
|
|
let builder = new WasmModuleBuilder();
|
|
builder.addImportedGlobal("mod", "g", kWasmI32);
|
|
builder.addFunction("main", kSig_i_v)
|
|
.addBody([kExprGetGlobal, 0])
|
|
.exportAs("main");
|
|
|
|
let main = builder.instantiate({mod: {g: global}}).exports.main;
|
|
assertEquals(1, main());
|
|
})();
|
|
|
|
(function TestTypeMismatch() {
|
|
let global = new WebAssembly.Global({type: 'f32'}, 1);
|
|
let builder = new WasmModuleBuilder();
|
|
builder.addImportedGlobal("mod", "g", kWasmI32);
|
|
|
|
assertThrows(() => builder.instantiate({mod: {g: global}}));
|
|
})();
|
|
|
|
(function TestMutableMismatch() {
|
|
let global = new WebAssembly.Global({type: 'f64'}, 1);
|
|
let builder = new WasmModuleBuilder();
|
|
builder.addImportedGlobal("mod", "g", kWasmF64, true);
|
|
|
|
assertThrows(() => builder.instantiate({mod: {g: global}}));
|
|
|
|
global = new WebAssembly.Global({type: 'i32', mutable: true}, 1);
|
|
builder = new WasmModuleBuilder();
|
|
builder.addImportedGlobal("mod", "g", kWasmI32);
|
|
|
|
assertThrows(() => builder.instantiate({mod: {g: global}}));
|
|
})();
|
|
|
|
(function TestImportMutableAsNumber() {
|
|
let builder = new WasmModuleBuilder();
|
|
builder.addImportedGlobal("mod", "g", kWasmF32, true);
|
|
assertThrows(() => builder.instantiate({mod: {g: 1234}}));
|
|
})();
|
|
|
|
(function TestImportI64AsNumber() {
|
|
let builder = new WasmModuleBuilder();
|
|
builder.addImportedGlobal("mod", "g", kWasmI64);
|
|
assertThrows(() => builder.instantiate({mod: {g: 1234}}));
|
|
})();
|
|
|
|
function addGlobalGetterAndSetter(builder, index, name, type) {
|
|
builder.addFunction('get' + name, makeSig([], [type]))
|
|
.addBody([kExprGetGlobal, index])
|
|
.exportFunc();
|
|
builder.addFunction('set' + name, makeSig([type], []))
|
|
.addBody([kExprGetLocal, 0, kExprSetGlobal, index])
|
|
.exportFunc();
|
|
}
|
|
|
|
(function TestImportMutableGlobal() {
|
|
const globalDesc = [
|
|
{name: 'i32', type: kWasmI32},
|
|
{name: 'f32', type: kWasmF32},
|
|
{name: 'f64', type: kWasmF64},
|
|
];
|
|
|
|
let globals = {};
|
|
let builder = new WasmModuleBuilder();
|
|
|
|
for (let [index, {name, type}] of globalDesc.entries()) {
|
|
globals[name] = new WebAssembly.Global({type: name, mutable: true});
|
|
builder.addImportedGlobal("mod", name, type, true);
|
|
addGlobalGetterAndSetter(builder, index, name, type);
|
|
}
|
|
|
|
let inst = builder.instantiate(
|
|
{mod: {i32: globals.i32, f32: globals.f32, f64: globals.f64}});
|
|
|
|
for (let type of ['i32', 'f32', 'f64']) {
|
|
let global = globals[type];
|
|
let get = inst.exports['get' + type];
|
|
let set = inst.exports['set' + type];
|
|
|
|
assertEquals(get(), global.value, type);
|
|
set(1234567);
|
|
assertEquals(1234567, global.value, type);
|
|
global.value = 7654321;
|
|
assertEquals(7654321, get(), type);
|
|
}
|
|
})();
|
|
|
|
(function TestImportExportedMutableGlobal() {
|
|
const globalDesc = [
|
|
{name: 'i32', type: kWasmI32},
|
|
{name: 'f32', type: kWasmF32},
|
|
{name: 'f64', type: kWasmF64},
|
|
];
|
|
|
|
let builder1 = new WasmModuleBuilder();
|
|
let builder2 = new WasmModuleBuilder();
|
|
for (let [index, {name, type}] of globalDesc.entries()) {
|
|
builder1.addGlobal(type, true).exportAs(name);
|
|
addGlobalGetterAndSetter(builder1, index, name, type);
|
|
|
|
builder2.addImportedGlobal("mod", name, type, true);
|
|
addGlobalGetterAndSetter(builder2, index, name, type);
|
|
}
|
|
let inst1 = builder1.instantiate();
|
|
let inst2 = builder2.instantiate({
|
|
mod: {
|
|
i32: inst1.exports.i32,
|
|
f32: inst1.exports.f32,
|
|
f64: inst1.exports.f64
|
|
}
|
|
});
|
|
|
|
for (let type of ['i32', 'f32', 'f64']) {
|
|
let get1 = inst1.exports['get' + type];
|
|
let get2 = inst2.exports['get' + type];
|
|
let set1 = inst1.exports['set' + type];
|
|
let set2 = inst2.exports['set' + type];
|
|
|
|
assertEquals(get1(), get2(), type);
|
|
set1(1234567);
|
|
assertEquals(1234567, get2(), type);
|
|
set2(7654321);
|
|
assertEquals(7654321, get1(), type);
|
|
}
|
|
})();
|
|
|
|
(function TestImportExportedMutableGlobalI64() {
|
|
function addGettersAndSetters(builder) {
|
|
const index = 0;
|
|
builder.addFunction('geti64_hi', makeSig([], [kWasmI32]))
|
|
.addBody([
|
|
kExprGetGlobal, index,
|
|
kExprI64Const, 32, kExprI64ShrU,
|
|
kExprI32ConvertI64])
|
|
.exportFunc();
|
|
builder.addFunction('geti64_lo', makeSig([], [kWasmI32]))
|
|
.addBody([kExprGetGlobal, index, kExprI32ConvertI64])
|
|
.exportFunc();
|
|
builder.addFunction("seti64", makeSig([kWasmI32, kWasmI32], []))
|
|
.addBody([
|
|
kExprGetLocal, 1, kExprI64UConvertI32,
|
|
kExprGetLocal, 0, kExprI64UConvertI32,
|
|
kExprI64Const, 32, kExprI64Shl,
|
|
kExprI64Ior,
|
|
kExprSetGlobal, index])
|
|
.exportFunc();
|
|
};
|
|
|
|
let builder = new WasmModuleBuilder();
|
|
builder.addGlobal(kWasmI64, true).exportAs('i64');
|
|
addGettersAndSetters(builder);
|
|
let inst1 = builder.instantiate();
|
|
|
|
builder = new WasmModuleBuilder();
|
|
builder.addImportedGlobal("mod", 'i64', kWasmI64, true);
|
|
addGettersAndSetters(builder);
|
|
let inst2 = builder.instantiate({ mod: { i64: inst1.exports.i64 } });
|
|
|
|
assertEquals(inst1.exports.geti64_lo(), inst2.exports.geti64_lo());
|
|
assertEquals(inst1.exports.geti64_hi(), inst2.exports.geti64_hi());
|
|
inst1.exports.seti64(13579, 24680);
|
|
assertEquals(13579, inst2.exports.geti64_hi());
|
|
assertEquals(24680, inst2.exports.geti64_lo());
|
|
inst2.exports.seti64(97531, 86420);
|
|
assertEquals(97531, inst1.exports.geti64_hi());
|
|
assertEquals(86420, inst1.exports.geti64_lo());
|
|
})();
|
|
|
|
(function TestImportMutableAcrossGc() {
|
|
let builder = new WasmModuleBuilder();
|
|
builder.addGlobal(kWasmI32, true).exportAs('i32');
|
|
let inst1 = builder.instantiate();
|
|
|
|
builder = new WasmModuleBuilder();
|
|
builder.addImportedGlobal("mod", 'i32', kWasmI32, true);
|
|
addGlobalGetterAndSetter(builder, 0, 'i32', kWasmI32);
|
|
let inst2 = builder.instantiate({ mod: { i32: inst1.exports.i32 } });
|
|
|
|
delete inst1;
|
|
gc();
|
|
|
|
inst2.exports.seti32(0x789abcde);
|
|
assertEquals(0x789abcde, inst2.exports.geti32());
|
|
})();
|