| // 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-reftypes --expose-gc |
| |
| load("test/mjsunit/wasm/wasm-module-builder.js"); |
| |
| (function TestDefaultValue() { |
| print(arguments.callee.name); |
| let builder = new WasmModuleBuilder(); |
| const g_null = builder.addGlobal(kWasmExternRef, true).index; |
| const g_nullfunc = builder.addGlobal(kWasmAnyFunc, true).index; |
| builder.addFunction("get_externref_global", kSig_r_v) |
| .addBody([kExprGlobalGet, g_null]) |
| .exportAs("get_externref_global"); |
| builder.addFunction("get_anyfunc_global", kSig_a_v) |
| .addBody([kExprGlobalGet, g_nullfunc]) |
| .exportAs("get_anyfunc_global"); |
| |
| const instance = builder.instantiate(); |
| assertEquals(null, instance.exports.get_externref_global()); |
| assertEquals(null, instance.exports.get_anyfunc_global()); |
| })(); |
| |
| (function TestDefaultValueSecondGlobal() { |
| print(arguments.callee.name); |
| let builder = new WasmModuleBuilder(); |
| const g_setref = builder.addGlobal(kWasmExternRef, true); |
| const g_setfunc = builder.addGlobal(kWasmAnyFunc, true); |
| const g_null = builder.addGlobal(kWasmExternRef, true); |
| const g_nullfunc = builder.addGlobal(kWasmAnyFunc, true); |
| builder.addFunction("get_externref_global", kSig_r_r) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprGlobalSet, g_setref.index, |
| kExprGlobalGet, g_null.index |
| ]) |
| .exportAs("get_externref_global"); |
| builder.addFunction("get_anyfunc_global", kSig_a_a) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprGlobalSet, g_setfunc.index, |
| kExprGlobalGet, g_nullfunc.index |
| ]) |
| .exportAs("get_anyfunc_global"); |
| |
| const instance = builder.instantiate(); |
| assertEquals(null, instance.exports.get_externref_global({})); |
| assertEquals(null, instance.exports.get_anyfunc_global( |
| instance.exports.get_externref_global)); |
| })(); |
| |
| (function TestExternRefGlobalChangeValue() { |
| print(arguments.callee.name); |
| let builder = new WasmModuleBuilder(); |
| // Dummy global for offset. |
| builder.addGlobal(kWasmExternRef, true); |
| const g = builder.addGlobal(kWasmExternRef, true); |
| builder.addFunction("main", kSig_r_r) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprGlobalSet, g.index, |
| kExprGlobalGet, g.index |
| ]) |
| .exportAs("main"); |
| |
| const instance = builder.instantiate(); |
| |
| const test_value = { hello: 'world' }; |
| assertSame(test_value, instance.exports.main(test_value)); |
| })(); |
| |
| (function TestAnyFuncGlobalChangeValue() { |
| print(arguments.callee.name); |
| let builder = new WasmModuleBuilder(); |
| // Dummy global for offset. |
| builder.addGlobal(kWasmAnyFunc, true); |
| const g = builder.addGlobal(kWasmAnyFunc, true); |
| builder.addFunction("main", kSig_a_a) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprGlobalSet, g.index, |
| kExprGlobalGet, g.index |
| ]) |
| .exportAs("main"); |
| |
| const instance = builder.instantiate(); |
| |
| const test_value = instance.exports.main; |
| assertSame(test_value, instance.exports.main(test_value)); |
| })(); |
| |
| (function TestGlobalChangeValueWithGC() { |
| print(arguments.callee.name); |
| let builder = new WasmModuleBuilder(); |
| const gc_index = builder.addImport("q", "gc", kSig_v_v); |
| // Dummy global for offset. |
| builder.addGlobal(kWasmExternRef, true); |
| const g = builder.addGlobal(kWasmExternRef, true); |
| builder.addFunction("main", kSig_r_r) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprGlobalSet, g.index, |
| kExprCallFunction, gc_index, // call gc |
| kExprGlobalGet, g.index |
| ]) |
| .exportAs("main"); |
| |
| const instance = builder.instantiate({ q: { gc: gc } }); |
| |
| const test_value = { hello: 'world' }; |
| assertSame(test_value, instance.exports.main(test_value)); |
| assertSame(5, instance.exports.main(5)); |
| assertSame("Hello", instance.exports.main("Hello")); |
| })(); |
| |
| (function TestGlobalAsRoot() { |
| print(arguments.callee.name); |
| let builder = new WasmModuleBuilder(); |
| const g = builder.addGlobal(kWasmExternRef, true); |
| builder.addFunction("get_global", kSig_r_v) |
| .addBody([ |
| kExprGlobalGet, g.index |
| ]) |
| .exportAs("get_global"); |
| |
| builder.addFunction("set_global", kSig_v_r) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprGlobalSet, g.index |
| ]) |
| .exportAs("set_global"); |
| |
| const instance = builder.instantiate(); |
| |
| let test_value = { hello: 'world' }; |
| instance.exports.set_global(test_value); |
| test_value = null; |
| gc(); |
| |
| const result = instance.exports.get_global(); |
| |
| assertEquals('world', result.hello); |
| })(); |
| |
| (function TestImportedExternRef() { |
| print(arguments.callee.name); |
| function Test(obj) { |
| let builder = new WasmModuleBuilder(); |
| const g = builder.addImportedGlobal('m', 'val', kWasmExternRef); |
| builder.addFunction('main', kSig_r_v) |
| .addBody([kExprGlobalGet, g]) |
| .exportAs('main'); |
| |
| const instance = builder.instantiate({ m: { val: obj } }); |
| assertSame(obj, instance.exports.main()); |
| } |
| Test(null); |
| Test(undefined); |
| Test(1653); |
| Test("mystring"); |
| Test({ q: 14 }); |
| Test(print); |
| })(); |
| |
| function dummy_func() { |
| let builder = new WasmModuleBuilder(); |
| builder.addFunction("dummy", kSig_i_v) |
| .addBody([kExprI32Const, 12]) |
| .exportAs("dummy"); |
| return builder.instantiate().exports.dummy; |
| } |
| |
| (function TestImportedAnyFunc() { |
| print(arguments.callee.name); |
| |
| let builder = new WasmModuleBuilder(); |
| const g = builder.addImportedGlobal('m', 'val', kWasmAnyFunc); |
| builder.addFunction('main', kSig_a_v) |
| .addBody([kExprGlobalGet, g]) |
| .exportAs('main'); |
| |
| const module = builder.toModule(); |
| const instance = new WebAssembly.Instance(module, { m: { val: null } }); |
| assertSame(null, instance.exports.main()); |
| |
| const instance2 = new WebAssembly.Instance( |
| module, { m: { val: instance.exports.main } }); |
| assertSame(instance.exports.main, instance2.exports.main()); |
| |
| assertThrows(() => new WebAssembly.Instance(module, { m: { val: {} } }), |
| WebAssembly.LinkError); |
| })(); |
| |
| (function TestExternRefGlobalObjectDefaultValue() { |
| print(arguments.callee.name); |
| let default_init = new WebAssembly.Global({ value: 'externref', mutable: true }); |
| assertSame(null, default_init.value); |
| assertSame(null, default_init.valueOf()); |
| })(); |
| |
| (function TestAnyFuncGlobalObjectDefaultValue() { |
| print(arguments.callee.name); |
| let default_init = new WebAssembly.Global({ value: 'anyfunc', mutable: true }); |
| assertSame(null, default_init.value); |
| assertSame(null, default_init.valueOf()); |
| })(); |
| |
| (function TestExternRefGlobalObject() { |
| print(arguments.callee.name); |
| function TestGlobal(obj) { |
| const global = new WebAssembly.Global({ value: 'externref' }, obj); |
| assertSame(obj, global.value); |
| assertSame(obj, global.valueOf()); |
| } |
| |
| TestGlobal(null); |
| TestGlobal(undefined); |
| TestGlobal(1663); |
| TestGlobal("testmyglobal"); |
| TestGlobal({ a: 11 }); |
| TestGlobal(print); |
| })(); |
| |
| (function TestAnyFuncGlobalObject() { |
| print(arguments.callee.name); |
| |
| const dummy = dummy_func(); |
| const global = new WebAssembly.Global({ value: 'anyfunc' }, dummy); |
| assertSame(dummy, global.value); |
| assertSame(dummy, global.valueOf()); |
| |
| const global_null = new WebAssembly.Global({ value: 'anyfunc' }, null); |
| assertSame(null, global_null.value); |
| assertSame(null, global_null.valueOf()); |
| |
| assertThrows(() => new WebAssembly.Global({ value: 'anyfunc' }, {}), TypeError); |
| })(); |
| |
| (function TestExternRefGlobalObjectSetValue() { |
| print(arguments.callee.name); |
| let global = new WebAssembly.Global({ value: 'externref', mutable: true }); |
| |
| function TestGlobal(obj) { |
| global.value = obj; |
| assertSame(obj, global.value); |
| assertSame(obj, global.valueOf()); |
| } |
| |
| TestGlobal(null); |
| assertThrows(() => TestGlobal(undefined), TypeError); |
| TestGlobal(1663); |
| TestGlobal("testmyglobal"); |
| TestGlobal({ a: 11 }); |
| TestGlobal(print); |
| })(); |
| |
| |
| (function TestAnyFuncGlobalObjectSetValue() { |
| print(arguments.callee.name); |
| let global = new WebAssembly.Global({ value: 'anyfunc', mutable: true }); |
| |
| const dummy = dummy_func(); |
| global.value = dummy; |
| assertSame(dummy, global.value); |
| assertSame(dummy, global.valueOf()); |
| |
| global.value = null; |
| assertSame(null, global.value); |
| assertSame(null, global.valueOf()); |
| |
| assertThrows(() => global.value = {}, TypeError); |
| })(); |
| |
| (function TestExportMutableRefGlobal() { |
| print(arguments.callee.name); |
| let builder = new WasmModuleBuilder(); |
| const g1 = builder.addGlobal(kWasmExternRef, true).exportAs("global1"); |
| const g2 = builder.addGlobal(kWasmAnyFunc, true).exportAs("global2"); |
| builder.addGlobal(kWasmI32, true); // Dummy. |
| builder.addGlobal(kWasmExternRef, true); // Dummy. |
| const g3 = builder.addGlobal(kWasmExternRef, true).exportAs("global3"); |
| const g4 = builder.addGlobal(kWasmAnyFunc, true).exportAs("global4"); |
| builder.addFunction("main", |
| makeSig([kWasmExternRef, kWasmAnyFunc, kWasmExternRef, kWasmAnyFunc], [])) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprGlobalSet, g1.index, |
| kExprLocalGet, 1, |
| kExprGlobalSet, g2.index, |
| kExprLocalGet, 2, |
| kExprGlobalSet, g3.index, |
| kExprLocalGet, 3, |
| kExprGlobalSet, g4.index |
| ]) |
| .exportAs("main"); |
| |
| const instance = builder.instantiate(); |
| const obj1 = { x: 221 }; |
| const func2 = instance.exports.main; |
| const obj3 = print; |
| const func4 = dummy_func(); |
| instance.exports.main(obj1, func2, obj3, func4); |
| assertSame(obj1, instance.exports.global1.value); |
| assertSame(func2, instance.exports.global2.value); |
| assertSame(obj3, instance.exports.global3.value); |
| assertSame(func4, instance.exports.global4.value); |
| })(); |
| |
| (function TestImportMutableExternRefGlobal() { |
| print(arguments.callee.name); |
| function Test(obj) { |
| let builder = new WasmModuleBuilder(); |
| const g = builder.addImportedGlobal('m', 'val', kWasmExternRef, true); |
| builder.addFunction('main', kSig_r_v) |
| .addBody([kExprGlobalGet, g]) |
| .exportAs('main'); |
| |
| const global = new WebAssembly.Global({ value: 'externref', mutable: 'true' }, obj); |
| const instance = builder.instantiate({ m: { val: global } }); |
| assertSame(obj, instance.exports.main()); |
| } |
| Test(null); |
| Test(undefined); |
| Test(1653); |
| Test("mystring"); |
| Test({ q: 14 }); |
| Test(print); |
| })(); |
| |
| (function TestImportMutableAnyFuncGlobal() { |
| print(arguments.callee.name); |
| function Test(obj) { |
| let builder = new WasmModuleBuilder(); |
| const g = builder.addImportedGlobal('m', 'val', kWasmAnyFunc, true); |
| builder.addFunction('main', kSig_a_v) |
| .addBody([kExprGlobalGet, g]) |
| .exportAs('main'); |
| |
| const global = new WebAssembly.Global({ value: 'anyfunc', mutable: 'true' }, obj); |
| const instance = builder.instantiate({ m: { val: global } }); |
| assertSame(obj, instance.exports.main()); |
| } |
| Test(dummy_func()); |
| Test(null); |
| })(); |
| |
| (function TestImportMutableExternRefGlobalFromOtherInstance() { |
| print(arguments.callee.name); |
| |
| // Create an instance which exports globals. |
| let builder1 = new WasmModuleBuilder(); |
| const g3 = builder1.addGlobal(kWasmExternRef, true).exportAs("e3"); |
| builder1.addGlobal(kWasmI32, true).exportAs("e1"); // Dummy. |
| builder1.addGlobal(kWasmExternRef, true).exportAs("e4"); // Dummy. |
| const g2 = builder1.addGlobal(kWasmExternRef, true).exportAs("e2"); |
| |
| builder1.addFunction("set_globals", kSig_v_rr) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprGlobalSet, g2.index, |
| kExprLocalGet, 1, |
| kExprGlobalSet, g3.index, |
| ]) |
| .exportAs("set_globals"); |
| |
| builder1.addFunction('get_global2', kSig_r_v) |
| .addBody([kExprGlobalGet, g2.index]) |
| .exportAs('get_global2'); |
| |
| builder1.addFunction('get_global3', kSig_r_v) |
| .addBody([kExprGlobalGet, g3.index]) |
| .exportAs('get_global3'); |
| |
| const instance1 = builder1.instantiate(); |
| const obj2 = { x: 221 }; |
| const obj3 = print; |
| instance1.exports.set_globals(obj2, obj3); |
| |
| // Create an instance which imports the globals of the other instance. |
| let builder2 = new WasmModuleBuilder(); |
| const i1 = builder2.addImportedGlobal('exports', 'e1', kWasmI32, true); |
| const i2 = builder2.addImportedGlobal('exports', 'e2', kWasmExternRef, true); |
| const i3 = builder2.addImportedGlobal('exports', 'e3', kWasmExternRef, true); |
| const i4 = builder2.addImportedGlobal('exports', 'e4', kWasmExternRef, true); |
| |
| builder2.addExportOfKind("reexport1", kExternalGlobal, i1); |
| builder2.addExportOfKind("reexport2", kExternalGlobal, i2); |
| builder2.addExportOfKind("reexport3", kExternalGlobal, i3); |
| builder2.addExportOfKind("reexport4", kExternalGlobal, i4); |
| |
| builder2.addFunction("set_globals", kSig_v_rr) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprGlobalSet, i2, |
| kExprLocalGet, 1, |
| kExprGlobalSet, i3, |
| ]) |
| .exportAs("set_globals"); |
| |
| builder2.addFunction('get_global2', kSig_r_v) |
| .addBody([kExprGlobalGet, i2]) |
| .exportAs('get_global2'); |
| |
| builder2.addFunction('get_global3', kSig_r_v) |
| .addBody([kExprGlobalGet, i3]) |
| .exportAs('get_global3'); |
| |
| const instance2 = builder2.instantiate(instance1); |
| // Check if the globals were imported correctly. |
| assertSame(obj2, instance2.exports.get_global2()); |
| assertSame(obj3, instance2.exports.get_global3()); |
| |
| assertSame(obj2, instance2.exports.reexport2.value); |
| assertSame(obj3, instance2.exports.reexport3.value); |
| |
| // Check if instance2 can make changes visible for instance1. |
| instance2.exports.set_globals(null, undefined); |
| assertEquals(null, instance1.exports.get_global2()); |
| assertEquals(undefined, instance1.exports.get_global3()); |
| |
| assertEquals(null, instance2.exports.reexport2.value); |
| assertEquals(undefined, instance2.exports.reexport3.value); |
| |
| // Check if instance1 can make changes visible for instance2. |
| instance1.exports.set_globals("foo", 66343); |
| assertEquals("foo", instance2.exports.get_global2()); |
| assertEquals(66343, instance2.exports.get_global3()); |
| |
| assertEquals("foo", instance2.exports.reexport2.value); |
| assertEquals(66343, instance2.exports.reexport3.value); |
| |
| const bar2 = { f: "oo" }; |
| const bar3 = { b: "ar" }; |
| instance2.exports.reexport2.value = bar2; |
| instance2.exports.reexport3.value = bar3; |
| |
| assertSame(bar2, instance1.exports.get_global2()); |
| assertSame(bar3, instance1.exports.get_global3()); |
| assertSame(bar2, instance2.exports.get_global2()); |
| assertSame(bar3, instance2.exports.get_global3()); |
| })(); |
| |
| (function TestImportMutableAnyFuncGlobalFromOtherInstance() { |
| print(arguments.callee.name); |
| |
| // Create an instance which exports globals. |
| let builder1 = new WasmModuleBuilder(); |
| const g3 = builder1.addGlobal(kWasmAnyFunc, true).exportAs("e3"); |
| builder1.addGlobal(kWasmI32, true).exportAs("e1"); // Dummy. |
| builder1.addGlobal(kWasmAnyFunc, true).exportAs("e4"); // Dummy. |
| const g2 = builder1.addGlobal(kWasmAnyFunc, true).exportAs("e2"); |
| |
| builder1.addFunction("set_globals", kSig_v_aa) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprGlobalSet, g2.index, |
| kExprLocalGet, 1, |
| kExprGlobalSet, g3.index, |
| ]) |
| .exportAs("set_globals"); |
| |
| builder1.addFunction('get_global2', kSig_a_v) |
| .addBody([kExprGlobalGet, g2.index]) |
| .exportAs('get_global2'); |
| |
| builder1.addFunction('get_global3', kSig_a_v) |
| .addBody([kExprGlobalGet, g3.index]) |
| .exportAs('get_global3'); |
| |
| const instance1 = builder1.instantiate(); |
| const obj2 = dummy_func(); |
| const obj3 = instance1.exports.set_globals; |
| const obj4 = instance1.exports.get_global3; |
| instance1.exports.set_globals(obj2, obj3); |
| |
| // Create an instance which imports the globals of the other instance. |
| let builder2 = new WasmModuleBuilder(); |
| const i1 = builder2.addImportedGlobal('exports', 'e1', kWasmI32, true); |
| const i2 = builder2.addImportedGlobal('exports', 'e2', kWasmAnyFunc, true); |
| const i3 = builder2.addImportedGlobal('exports', 'e3', kWasmAnyFunc, true); |
| const i4 = builder2.addImportedGlobal('exports', 'e4', kWasmAnyFunc, true); |
| |
| builder2.addExportOfKind("reexport1", kExternalGlobal, i1); |
| builder2.addExportOfKind("reexport2", kExternalGlobal, i2); |
| builder2.addExportOfKind("reexport3", kExternalGlobal, i3); |
| builder2.addExportOfKind("reexport4", kExternalGlobal, i4); |
| |
| builder2.addFunction("set_globals", kSig_v_aa) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprGlobalSet, i2, |
| kExprLocalGet, 1, |
| kExprGlobalSet, i3, |
| ]) |
| .exportAs("set_globals"); |
| |
| builder2.addFunction('get_global2', kSig_a_v) |
| .addBody([kExprGlobalGet, i2]) |
| .exportAs('get_global2'); |
| |
| builder2.addFunction('get_global3', kSig_a_v) |
| .addBody([kExprGlobalGet, i3]) |
| .exportAs('get_global3'); |
| |
| const instance2 = builder2.instantiate(instance1); |
| // Check if the globals were imported correctly. |
| assertSame(obj2, instance2.exports.get_global2()); |
| assertSame(obj3, instance2.exports.get_global3()); |
| |
| assertSame(obj2, instance2.exports.reexport2.value); |
| assertSame(obj3, instance2.exports.reexport3.value); |
| |
| // Check if instance2 can make changes visible for instance1. |
| instance2.exports.set_globals(null, obj4); |
| assertEquals(null, instance1.exports.get_global2()); |
| assertEquals(obj4, instance1.exports.get_global3()); |
| |
| assertEquals(null, instance2.exports.reexport2.value); |
| assertEquals(obj4, instance2.exports.reexport3.value); |
| |
| // Check if instance1 can make changes visible for instance2. |
| instance1.exports.set_globals(obj2, obj3); |
| assertEquals(obj2, instance2.exports.get_global2()); |
| assertEquals(obj3, instance2.exports.get_global3()); |
| |
| assertEquals(obj2, instance2.exports.reexport2.value); |
| assertEquals(obj3, instance2.exports.reexport3.value); |
| })(); |
| |
| (function TestImportMutableAnyFuncGlobalAsExternRefFails() { |
| print(arguments.callee.name); |
| let builder1 = new WasmModuleBuilder(); |
| const g3 = builder1.addGlobal(kWasmAnyFunc, true).exportAs("e3"); |
| builder1.addGlobal(kWasmExternRef, true).exportAs("e1"); // Dummy. |
| builder1.addGlobal(kWasmAnyFunc, true).exportAs("e2"); // Dummy. |
| const instance1 = builder1.instantiate(); |
| |
| let builder2 = new WasmModuleBuilder(); |
| const i1 = builder2.addImportedGlobal('exports', 'e1', kWasmExternRef, true); |
| const i2 = builder2.addImportedGlobal('exports', 'e2', kWasmExternRef, true); |
| assertThrows(() => builder2.instantiate(instance1), WebAssembly.LinkError); |
| })(); |
| |
| (function TestRefFuncGlobalInit() { |
| print(arguments.callee.name); |
| let builder = new WasmModuleBuilder(); |
| const g_func = builder.addGlobal(kWasmAnyFunc, true); |
| const f_func = builder.addFunction('get_anyfunc_global', kSig_a_v) |
| .addBody([kExprGlobalGet, g_func.index]) |
| .exportAs('get_anyfunc_global'); |
| builder.addDeclarativeElementSegment([f_func.index]); |
| g_func.function_index = f_func.index; |
| |
| const instance = builder.instantiate(); |
| assertEquals( |
| instance.exports.get_anyfunc_global, |
| instance.exports.get_anyfunc_global()); |
| })(); |
| |
| (function TestRefFuncGlobalInitWithImport() { |
| print(arguments.callee.name); |
| let builder = new WasmModuleBuilder(); |
| const sig_index = builder.addType(kSig_i_v); |
| const import_wasm = builder.addImport('m', 'wasm', sig_index); |
| const import_js = builder.addImport('m', 'js', sig_index); |
| const g_wasm = builder.addGlobal(kWasmAnyFunc, true); |
| const g_js = builder.addGlobal(kWasmAnyFunc, true); |
| builder.addDeclarativeElementSegment([import_wasm, import_js]); |
| g_wasm.function_index = import_wasm; |
| g_js.function_index = import_js; |
| builder.addFunction('get_global_wasm', kSig_a_v) |
| .addBody([kExprGlobalGet, g_wasm.index]) |
| .exportFunc(); |
| builder.addFunction('get_global_js', kSig_a_v) |
| .addBody([kExprGlobalGet, g_js.index]) |
| .exportFunc(); |
| |
| const expected_wasm = dummy_func(); |
| const expected_val = 27; |
| // I want to test here that imported JS functions get wrapped by wasm-to-js |
| // and js-to-wasm wrappers. That's why {expected_js} does not return an |
| // integer directly but an object with a {valueOf} function. |
| function expected_js() { |
| const result = {}; |
| result.valueOf = () => expected_val; |
| return result; |
| }; |
| |
| const instance = |
| builder.instantiate({m: {wasm: expected_wasm, js: expected_js}}); |
| |
| assertSame(expected_wasm, instance.exports.get_global_wasm()); |
| assertSame(expected_val, instance.exports.get_global_js()()); |
| })(); |
| |
| (function TestSetGlobalWriteBarrier() { |
| print(arguments.callee.name); |
| let builder = new WasmModuleBuilder(); |
| const global = builder.addGlobal(kWasmExternRef, true).index; |
| builder.addFunction("set_global", kSig_v_r) |
| .addBody([kExprLocalGet, 0, kExprGlobalSet, global]) |
| .exportFunc(); |
| builder.addFunction("get_global", kSig_r_v) |
| .addBody([kExprGlobalGet, global]) |
| .exportFunc(); |
| |
| const instance = builder.instantiate(); |
| // Trigger GC twice to make sure the instance is moved to mature space. |
| gc(); |
| gc(); |
| const test_value = { hello: 'world' }; |
| instance.exports.set_global(test_value); |
| // Run another GC to test if the writebarrier existed. |
| gc(); |
| assertSame(test_value, instance.exports.get_global()); |
| })(); |