| // Copyright 2019 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-type-reflection --experimental-wasm-reftypes |
| |
| load('test/mjsunit/wasm/wasm-module-builder.js'); |
| |
| (function TestTableType() { |
| let table = new WebAssembly.Table({initial: 1, element: "externref"}); |
| let type = WebAssembly.Table.type(table); |
| assertEquals(1, type.minimum); |
| assertEquals("externref", type.element); |
| assertEquals(2, Object.getOwnPropertyNames(type).length); |
| |
| table = new WebAssembly.Table({initial: 2, maximum: 15, element: "externref"}); |
| type = WebAssembly.Table.type(table); |
| assertEquals(2, type.minimum); |
| assertEquals(15, type.maximum); |
| assertEquals("externref", type.element); |
| assertEquals(3, Object.getOwnPropertyNames(type).length); |
| })(); |
| |
| (function TestGlobalType() { |
| let global = new WebAssembly.Global({value: "externref", mutable: true}); |
| let type = WebAssembly.Global.type(global); |
| assertEquals("externref", type.value); |
| assertEquals(true, type.mutable); |
| assertEquals(2, Object.getOwnPropertyNames(type).length); |
| |
| global = new WebAssembly.Global({value: "externref"}); |
| type = WebAssembly.Global.type(global); |
| assertEquals("externref", type.value); |
| assertEquals(false, type.mutable); |
| assertEquals(2, Object.getOwnPropertyNames(type).length); |
| |
| global = new WebAssembly.Global({value: "anyfunc"}); |
| type = WebAssembly.Global.type(global); |
| assertEquals("anyfunc", type.value); |
| assertEquals(false, type.mutable); |
| assertEquals(2, Object.getOwnPropertyNames(type).length); |
| })(); |
| |
| (function TestFunctionGlobalGetAndSet() { |
| let builder = new WasmModuleBuilder(); |
| let fun1 = new WebAssembly.Function({parameters:[], results:["i32"]}, _ => 7); |
| let fun2 = new WebAssembly.Function({parameters:[], results:["i32"]}, _ => 9); |
| builder.addGlobal(kWasmAnyFunc, true).exportAs("f"); |
| builder.addFunction('get_global', kSig_a_v) |
| .addBody([ |
| kExprGlobalGet, 0, |
| ]) |
| .exportFunc(); |
| builder.addFunction('set_global', kSig_v_a) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprGlobalSet, 0, |
| ]) |
| .exportFunc(); |
| let instance = builder.instantiate(); |
| |
| // Test getting and setting "funcref" global via WebAssembly. |
| assertEquals(null, instance.exports.get_global()); |
| instance.exports.set_global(fun1); |
| assertEquals(fun1, instance.exports.get_global()); |
| |
| // Test getting and setting "funcref" global via JavaScript. |
| assertEquals(fun1, instance.exports.f.value); |
| instance.exports.f.value = fun2; |
| assertEquals(fun2, instance.exports.f.value); |
| |
| // Test the full round-trip of an "funcref" global. |
| assertEquals(fun2, instance.exports.get_global()); |
| })(); |
| |
| // This is an extension of "type-reflection.js/TestFunctionTableSetAndCall" to |
| // multiple table indexes. If --experimental-wasm-reftypes is enabled by default |
| // this test case can supersede the other one. |
| (function TestFunctionMultiTableSetAndCall() { |
| let builder = new WasmModuleBuilder(); |
| let v1 = 7; let v2 = 9; let v3 = 0.0; |
| let f1 = new WebAssembly.Function({parameters:[], results:["i32"]}, _ => v1); |
| let f2 = new WebAssembly.Function({parameters:[], results:["i32"]}, _ => v2); |
| let f3 = new WebAssembly.Function({parameters:[], results:["f64"]}, _ => v3); |
| let table = new WebAssembly.Table({element: "anyfunc", initial: 2}); |
| let table_index0 = builder.addImportedTable("m", "table", 2); |
| let table_index1 = builder.addTable(kWasmAnyFunc, 1).exportAs("tbl").index; |
| let sig_index = builder.addType(kSig_i_v); |
| table.set(0, f1); |
| builder.addFunction('call0', kSig_i_i) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprCallIndirect, sig_index, table_index0 |
| ]) |
| .exportFunc(); |
| builder.addFunction('call1', kSig_i_i) |
| .addBody([ |
| kExprLocalGet, 0, |
| kExprCallIndirect, sig_index, table_index1 |
| ]) |
| .exportFunc(); |
| let instance = builder.instantiate({ m: { table: table }}); |
| |
| // Test table #0 first. |
| assertEquals(v1, instance.exports.call0(0)); |
| assertSame(f1, table.get(0)); |
| table.set(1, f2); |
| assertEquals(v2, instance.exports.call0(1)); |
| assertSame(f2, table.get(1)); |
| table.set(1, f3); |
| assertTraps(kTrapFuncSigMismatch, () => instance.exports.call0(1)); |
| assertSame(f3, table.get(1)); |
| |
| // Test table #1 next. |
| assertTraps(kTrapFuncSigMismatch, () => instance.exports.call1(0)); |
| instance.exports.tbl.set(0, f1); |
| assertEquals(v1, instance.exports.call1(0)); |
| assertSame(f1, instance.exports.tbl.get(0)); |
| instance.exports.tbl.set(0, f2); |
| assertEquals(v2, instance.exports.call1(0)); |
| assertSame(f2, instance.exports.tbl.get(0)); |
| instance.exports.tbl.set(0, f3); |
| assertTraps(kTrapFuncSigMismatch, () => instance.exports.call1(0)); |
| assertSame(f3, instance.exports.tbl.get(0)); |
| })(); |