9166affb29
The WasmInstanceObject stores two new arrays: - imported_mutable_globals_buffers_: a FixedArray of all the imported globals' array buffers. - imported_mutable_globals: a calloc'd array of Addresses pointing to the mutable global in its array buffer. When accessing the global, the generated code looks up the address in imported_mutable_globals to find where to load/store. Bug: v8:7625 Change-Id: I60844c21a788fce28f346455f10f2283d1c152e9 Reviewed-on: https://chromium-review.googlesource.com/1020602 Commit-Queue: Ben Smith <binji@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#52794}
177 lines
5.6 KiB
JavaScript
177 lines
5.6 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', value: 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', value: 1});
|
|
let builder = new WasmModuleBuilder();
|
|
builder.addImportedGlobal("mod", "g", kWasmI32);
|
|
builder.addFunction("main", kSig_i_v)
|
|
.addBody([kExprGetGlobal, 0])
|
|
.exportAs("main");
|
|
|
|
assertThrows(() => builder.instantiate({mod: {g: global}}));
|
|
})();
|
|
|
|
(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());
|
|
})();
|