| // 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: --expose-gc |
| |
| load("test/mjsunit/wasm/wasm-module-builder.js"); |
| |
| (function TestBasic() { |
| let global = new WebAssembly.Global({value: '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({value: 'f32'}, 1); |
| let builder = new WasmModuleBuilder(); |
| builder.addImportedGlobal("mod", "g", kWasmI32); |
| |
| assertThrows(() => builder.instantiate({mod: {g: global}})); |
| })(); |
| |
| (function TestMutableMismatch() { |
| let global = new WebAssembly.Global({value: 'f64'}, 1); |
| let builder = new WasmModuleBuilder(); |
| builder.addImportedGlobal("mod", "g", kWasmF64, true); |
| |
| assertThrows(() => builder.instantiate({mod: {g: global}})); |
| |
| global = new WebAssembly.Global({value: '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({value: 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()); |
| })(); |
| |
| (function TestImportedAndNonImportedMutableGlobal() { |
| let global = new WebAssembly.Global({value: 'i32', mutable: true}, 1); |
| let builder = new WasmModuleBuilder(); |
| builder.addImportedGlobal("mod", "g", kWasmI32, true); |
| builder.addGlobal(kWasmI32, true).exportAs('i32'); |
| builder.instantiate({mod: {g: global}}); |
| })(); |