blob: bde5793acc2312ac7fd050c6151c0c7663bb9062 [file] [log] [blame]
Kaido Kertf309f9a2021-04-30 12:09:15 -07001// Copyright 2019 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Flags: --expose-wasm --experimental-wasm-reftypes
6
7load("test/mjsunit/wasm/wasm-module-builder.js");
8
9(function TestGetAndSet() {
10function addTableWithAccessors(builder, type, size, name) {
11 const table = builder.addTable(type, size);
12 const set_sig = makeSig([kWasmI32, type], []);
13 builder.addFunction('set_' + name, set_sig)
14 .addBody([kExprLocalGet, 0,
15 kExprLocalGet, 1,
16 kExprTableSet, table.index])
17 .exportFunc();
18
19 const get_sig = makeSig([kWasmI32], [type]);
20 builder.addFunction('get_' + name, get_sig)
21 .addBody([kExprLocalGet, 0, kExprTableGet, table.index])
22 .exportFunc();
23}
24
25const builder = new WasmModuleBuilder();
26
27addTableWithAccessors(builder, kWasmAnyFunc, 10, 'table_func1');
28addTableWithAccessors(builder, kWasmExternRef, 20, 'table_ref1');
29addTableWithAccessors(builder, kWasmExternRef, 9, 'table_ref2');
30addTableWithAccessors(builder, kWasmAnyFunc, 12, 'table_func2');
31
32let exports = builder.instantiate().exports;
33const dummy_ref = {foo : 1, bar : 3};
34const dummy_func = exports.set_table_func1;
35
36(function testTableGetInitialValue() {
37 print(arguments.callee.name);
38 // Tables are initialized with `null`.
39 assertSame(null, exports.get_table_func1(1));
40 assertSame(null, exports.get_table_func2(2));
41 assertSame(null, exports.get_table_ref1(3));
42 assertSame(null, exports.get_table_ref2(4));
43})();
44
45(function testTableGetOOB() {
46 print(arguments.callee.name);
47 assertSame(null, exports.get_table_func2(11));
48 assertTraps(kTrapTableOutOfBounds, () => exports.get_table_func1(11));
49 assertTraps(kTrapTableOutOfBounds, () => exports.get_table_func2(21));
50 assertTraps(kTrapTableOutOfBounds, () => exports.get_table_func1(-1));
51 assertTraps(kTrapTableOutOfBounds, () => exports.get_table_func2(-2));
52 assertSame(null, exports.get_table_ref1(14));
53 assertTraps(kTrapTableOutOfBounds, () => exports.get_table_ref2(14));
54 assertTraps(kTrapTableOutOfBounds, () => exports.get_table_ref1(44));
55 assertTraps(kTrapTableOutOfBounds, () => exports.get_table_ref2(-1));
56 assertTraps(kTrapTableOutOfBounds, () => exports.get_table_ref1(-4));
57})();
58
59(function testTableSetOOB() {
60 print(arguments.callee.name);
61 exports.set_table_func2(11, dummy_func);
62 assertTraps(kTrapTableOutOfBounds, () => exports.set_table_func1(11, dummy_func));
63 assertTraps(kTrapTableOutOfBounds, () => exports.set_table_func2(21, dummy_func));
64 exports.set_table_ref1(14, dummy_ref);
65 assertTraps(kTrapTableOutOfBounds, () => exports.set_table_ref2(14, dummy_ref));
66 assertTraps(kTrapTableOutOfBounds, () => exports.set_table_ref1(44, dummy_ref));
67})();
68
69(function testTableSet() {
70 print(arguments.callee.name);
71 assertSame(null, exports.get_table_func1(3));
72 exports.set_table_func1(3, dummy_func);
73 assertSame(dummy_func, exports.get_table_func1(3));
74 assertSame(null, exports.get_table_func2(3));
75
76 assertSame(null, exports.get_table_func2(7));
77 exports.set_table_func2(7, dummy_func);
78 assertSame(dummy_func, exports.get_table_func2(7));
79 assertSame(null, exports.get_table_func1(7));
80
81 assertSame(null, exports.get_table_ref1(3));
82 exports.set_table_ref1(3, dummy_ref);
83 assertSame(dummy_ref, exports.get_table_ref1(3));
84 assertSame(null, exports.get_table_ref2(3));
85
86 assertSame(null, exports.get_table_ref2(7));
87 exports.set_table_ref2(7, dummy_ref);
88 assertSame(dummy_ref, exports.get_table_ref2(7));
89 assertSame(null, exports.get_table_ref1(7));
90})();
91
92(function testSetFunctionTableInvalidType() {
93 print(arguments.callee.name);
94 assertThrows(() => exports.set_table_func2(7, dummy_ref), TypeError);
95})();
96})();
97
98(function testGetFunctionFromInitializedTable() {
99 print(arguments.callee.name);
100 const value1 = 11;
101 const value2 = 22;
102 const value3 = 13;
103
104 const builder = new WasmModuleBuilder();
105 const t1 = builder.addTable(kWasmAnyFunc, 10).index;
106 const t2 = builder.addTable(kWasmAnyFunc, 12).index;
107
108 const f1 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, value1]);
109 const f2 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, value2]);
110 const f3 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, value3]);
111 builder.addFunction('get_t1', kSig_a_i)
112 .addBody([kExprLocalGet, 0, kExprTableGet, t1])
113 .exportFunc();
114 builder.addFunction('get_t2', kSig_a_i)
115 .addBody([kExprLocalGet, 0, kExprTableGet, t2])
116 .exportFunc();
117
118 const offset1 = 3;
119 const offset2 = 9;
120 builder.addElementSegment(t1, offset1, false, [f1.index, f2.index]);
121 builder.addElementSegment(t2, offset2, false, [f3.index, f1.index]);
122
123 const instance = builder.instantiate();
124
125 assertEquals(value1, instance.exports.get_t1(offset1)());
126 assertEquals(value2, instance.exports.get_t1(offset1 + 1)());
127 assertEquals(value3, instance.exports.get_t2(offset2)());
128 assertEquals(value1, instance.exports.get_t2(offset2 + 1)());
129})();
130
131(function testRefFuncInTableIsCallable() {
132 print(arguments.callee.name);
133 const expected = 54;
134 const index = 3;
135 const builder = new WasmModuleBuilder();
136 const table_index = builder.addTable(kWasmAnyFunc, 15, 15).index;
137 const sig_index = builder.addType(kSig_i_v);
138 const function_index = builder.addFunction('hidden', sig_index)
139 .addBody([kExprI32Const, expected])
140 .index;
141 builder.addDeclarativeElementSegment([function_index]);
142
143 builder.addFunction('main', kSig_i_v)
144 .addBody([
145 kExprI32Const, index, // entry index
146 kExprRefFunc, function_index, // function reference
147 kExprTableSet, table_index, // --
148 kExprI32Const, index, // entry index
149 kExprCallIndirect, sig_index, table_index // --
150
151 ])
152 .exportFunc();
153
154 const instance = builder.instantiate();
155 assertEquals(expected, instance.exports.main());
156})();