| // 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: --expose-wasm --experimental-wasm-anyref |
| |
| load("test/mjsunit/wasm/wasm-module-builder.js"); |
| |
| (function TestGetAndSet() { |
| function addTableWithAccessors(builder, type, size, name) { |
| const table = builder.addTable(type, size); |
| const set_sig = makeSig([kWasmI32, type], []); |
| builder.addFunction('set_' + name, set_sig) |
| .addBody([kExprGetLocal, 0, |
| kExprGetLocal, 1, |
| kExprTableSet, table.index]) |
| .exportFunc(); |
| |
| const get_sig = makeSig([kWasmI32], [type]); |
| builder.addFunction('get_' + name, get_sig) |
| .addBody([kExprGetLocal, 0, kExprTableGet, table.index]) |
| .exportFunc(); |
| } |
| |
| const builder = new WasmModuleBuilder(); |
| |
| addTableWithAccessors(builder, kWasmAnyFunc, 10, 'table_func1'); |
| addTableWithAccessors(builder, kWasmAnyRef, 20, 'table_ref1'); |
| addTableWithAccessors(builder, kWasmAnyRef, 9, 'table_ref2'); |
| addTableWithAccessors(builder, kWasmAnyFunc, 12, 'table_func2'); |
| |
| let exports = builder.instantiate().exports; |
| const dummy_ref = {foo : 1, bar : 3}; |
| const dummy_func = exports.set_table_func1; |
| |
| (function testTableGetInitialValue() { |
| print(arguments.callee.name); |
| // Tables are initialized with `null`. |
| assertSame(null, exports.get_table_func1(1)); |
| assertSame(null, exports.get_table_func2(2)); |
| assertSame(null, exports.get_table_ref1(3)); |
| assertSame(null, exports.get_table_ref2(4)); |
| })(); |
| |
| (function testTableGetOOB() { |
| print(arguments.callee.name); |
| assertSame(null, exports.get_table_func2(11)); |
| assertTraps(kTrapTableOutOfBounds, () => exports.get_table_func1(11)); |
| assertTraps(kTrapTableOutOfBounds, () => exports.get_table_func2(21)); |
| assertTraps(kTrapTableOutOfBounds, () => exports.get_table_func1(-1)); |
| assertTraps(kTrapTableOutOfBounds, () => exports.get_table_func2(-2)); |
| assertSame(null, exports.get_table_ref1(14)); |
| assertTraps(kTrapTableOutOfBounds, () => exports.get_table_ref2(14)); |
| assertTraps(kTrapTableOutOfBounds, () => exports.get_table_ref1(44)); |
| assertTraps(kTrapTableOutOfBounds, () => exports.get_table_ref2(-1)); |
| assertTraps(kTrapTableOutOfBounds, () => exports.get_table_ref1(-4)); |
| })(); |
| |
| (function testTableSetOOB() { |
| print(arguments.callee.name); |
| exports.set_table_func2(11, dummy_func); |
| assertTraps(kTrapTableOutOfBounds, () => exports.set_table_func1(11, dummy_func)); |
| assertTraps(kTrapTableOutOfBounds, () => exports.set_table_func2(21, dummy_func)); |
| exports.set_table_ref1(14, dummy_ref); |
| assertTraps(kTrapTableOutOfBounds, () => exports.set_table_ref2(14, dummy_ref)); |
| assertTraps(kTrapTableOutOfBounds, () => exports.set_table_ref1(44, dummy_ref)); |
| })(); |
| |
| (function testTableSet() { |
| print(arguments.callee.name); |
| assertSame(null, exports.get_table_func1(3)); |
| exports.set_table_func1(3, dummy_func); |
| assertSame(dummy_func, exports.get_table_func1(3)); |
| assertSame(null, exports.get_table_func2(3)); |
| |
| assertSame(null, exports.get_table_func2(7)); |
| exports.set_table_func2(7, dummy_func); |
| assertSame(dummy_func, exports.get_table_func2(7)); |
| assertSame(null, exports.get_table_func1(7)); |
| |
| assertSame(null, exports.get_table_ref1(3)); |
| exports.set_table_ref1(3, dummy_ref); |
| assertSame(dummy_ref, exports.get_table_ref1(3)); |
| assertSame(null, exports.get_table_ref2(3)); |
| |
| assertSame(null, exports.get_table_ref2(7)); |
| exports.set_table_ref2(7, dummy_ref); |
| assertSame(dummy_ref, exports.get_table_ref2(7)); |
| assertSame(null, exports.get_table_ref1(7)); |
| })(); |
| |
| (function testSetFunctionTableInvalidType() { |
| print(arguments.callee.name); |
| assertThrows(() => exports.set_table_func2(7, dummy_ref), TypeError); |
| })(); |
| })(); |
| |
| (function testGetFunctionFromInitializedTable() { |
| print(arguments.callee.name); |
| const value1 = 11; |
| const value2 = 22; |
| const value3 = 13; |
| |
| const builder = new WasmModuleBuilder(); |
| const t1 = builder.addTable(kWasmAnyFunc, 10).index; |
| const t2 = builder.addTable(kWasmAnyFunc, 12).index; |
| |
| const f1 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, value1]); |
| const f2 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, value2]); |
| const f3 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, value3]); |
| builder.addFunction('get_t1', kSig_a_i) |
| .addBody([kExprGetLocal, 0, kExprTableGet, t1]) |
| .exportFunc(); |
| builder.addFunction('get_t2', kSig_a_i) |
| .addBody([kExprGetLocal, 0, kExprTableGet, t2]) |
| .exportFunc(); |
| |
| const offset1 = 3; |
| const offset2 = 9; |
| builder.addElementSegment(t1, offset1, false, [f1.index, f2.index]); |
| builder.addElementSegment(t2, offset2, false, [f3.index, f1.index]); |
| |
| const instance = builder.instantiate(); |
| |
| assertEquals(value1, instance.exports.get_t1(offset1)()); |
| assertEquals(value2, instance.exports.get_t1(offset1 + 1)()); |
| assertEquals(value3, instance.exports.get_t2(offset2)()); |
| assertEquals(value1, instance.exports.get_t2(offset2 + 1)()); |
| })(); |
| |
| (function testRefFuncInTableIsCallable() { |
| print(arguments.callee.name); |
| const expected = 54; |
| const index = 3; |
| const builder = new WasmModuleBuilder(); |
| const table_index = builder.addTable(kWasmAnyFunc, 15, 15).index; |
| const sig_index = builder.addType(kSig_i_v); |
| const function_index = builder.addFunction('hidden', sig_index) |
| .addBody([kExprI32Const, expected]) |
| .index; |
| |
| builder.addFunction('main', kSig_i_v) |
| .addBody([ |
| kExprI32Const, index, // entry index |
| kExprRefFunc, function_index, // function reference |
| kExprTableSet, table_index, // -- |
| kExprI32Const, index, // entry index |
| kExprCallIndirect, sig_index, table_index // -- |
| |
| ]) |
| .exportFunc(); |
| |
| const instance = builder.instantiate(); |
| assertEquals(expected, instance.exports.main()); |
| })(); |