OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Flags: --expose-wasm | 5 // Flags: --expose-wasm |
6 | 6 |
7 load("test/mjsunit/wasm/wasm-constants.js"); | 7 load("test/mjsunit/wasm/wasm-constants.js"); |
8 load("test/mjsunit/wasm/wasm-module-builder.js"); | 8 load("test/mjsunit/wasm/wasm-module-builder.js"); |
9 | 9 |
10 function AddFunctions(builder) { | 10 function AddFunctions(builder) { |
(...skipping 12 matching lines...) Expand all Loading... |
23 ]); | 23 ]); |
24 let sub = builder.addFunction("sub", sig_index) | 24 let sub = builder.addFunction("sub", sig_index) |
25 .addBody([ | 25 .addBody([ |
26 kExprGetLocal, 0, // -- | 26 kExprGetLocal, 0, // -- |
27 kExprGetLocal, 1, // -- | 27 kExprGetLocal, 1, // -- |
28 kExprI32Sub // -- | 28 kExprI32Sub // -- |
29 ]); | 29 ]); |
30 return {mul: mul, add: add, sub: sub}; | 30 return {mul: mul, add: add, sub: sub}; |
31 } | 31 } |
32 | 32 |
33 function js_div(a, b) { return (a / b) | 0; } | |
34 | |
35 (function ExportedTableTest() { | 33 (function ExportedTableTest() { |
36 print("ExportedTableTest..."); | 34 print("ExportedTableTest..."); |
37 | 35 |
38 let builder = new WasmModuleBuilder(); | 36 let builder = new WasmModuleBuilder(); |
39 | 37 |
40 let d = builder.addImport("js_div", kSig_i_ii); | 38 let d = builder.addImport("js_div", kSig_i_ii); |
41 let f = AddFunctions(builder); | 39 let f = AddFunctions(builder); |
42 builder.addFunction("main", kSig_i_ii) | 40 builder.addFunction("main", kSig_i_ii) |
43 .addBody([ | 41 .addBody([ |
44 kExprI32Const, 33, // -- | 42 kExprI32Const, 33, // -- |
45 kExprGetLocal, 0, // -- | 43 kExprGetLocal, 0, // -- |
46 kExprGetLocal, 1, // -- | 44 kExprGetLocal, 1, // -- |
47 kExprCallIndirect, 0, kTableZero]) // -- | 45 kExprCallIndirect, 0, kTableZero]) // -- |
48 .exportAs("main"); | 46 .exportAs("main"); |
49 | 47 |
50 f.add.exportAs("blarg"); | 48 f.add.exportAs("blarg"); |
51 | 49 |
52 builder.setFunctionTableLength(10); | 50 builder.setFunctionTableLength(10); |
53 let g = builder.addImportedGlobal("base", undefined, kAstI32); | 51 let g = builder.addImportedGlobal("base", undefined, kAstI32); |
54 builder.addFunctionTableInit(g, true, [f.mul.index, f.add.index, | 52 builder.addFunctionTableInit(g, true, [f.mul.index, f.add.index, |
55 f.sub.index, | 53 f.sub.index, |
56 d]); | 54 d]); |
57 builder.addExportOfKind("table", kExternalTable, 0); | 55 builder.addExportOfKind("table", kExternalTable, 0); |
58 | 56 |
59 let module = new WebAssembly.Module(builder.toBuffer()); | 57 let module = new WebAssembly.Module(builder.toBuffer()); |
60 | 58 |
| 59 function js_div(a, b) { return (a / b) | 0; } |
| 60 |
61 for (let i = 0; i < 5; i++) { | 61 for (let i = 0; i < 5; i++) { |
62 print(" base = " + i); | 62 print(" base = " + i); |
63 let instance = new WebAssembly.Instance(module, {base: i, js_div: js_div}); | 63 let instance = new WebAssembly.Instance(module, {base: i, js_div: js_div}); |
64 main = instance.exports.main; | 64 main = instance.exports.main; |
65 let table = instance.exports.table; | 65 let table = instance.exports.table; |
66 assertTrue(table instanceof WebAssembly.Table); | 66 assertTrue(table instanceof WebAssembly.Table); |
67 assertEquals(10, table.length); | 67 assertEquals(10, table.length); |
68 for (let j = 0; j < i; j++) { | 68 for (let j = 0; j < i; j++) { |
69 assertSame(null, table.get(j)); | 69 assertSame(null, table.get(j)); |
70 } | 70 } |
(...skipping 22 matching lines...) Expand all Loading... |
93 for (let j = i + 4; j < 10; j++) { | 93 for (let j = i + 4; j < 10; j++) { |
94 assertSame(null, table.get(j)); | 94 assertSame(null, table.get(j)); |
95 } | 95 } |
96 | 96 |
97 assertEquals(-33, mul(-11, 3)); | 97 assertEquals(-33, mul(-11, 3)); |
98 assertEquals(4444444, add(3333333, 1111111)); | 98 assertEquals(4444444, add(3333333, 1111111)); |
99 assertEquals(-9999, sub(1, 10000)); | 99 assertEquals(-9999, sub(1, 10000)); |
100 assertEquals(-44, exp_div(-88.1, 2)); | 100 assertEquals(-44, exp_div(-88.1, 2)); |
101 } | 101 } |
102 })(); | 102 })(); |
103 | |
104 | |
105 (function ImportedTableTest() { | |
106 let kTableSize = 10; | |
107 print("ImportedTableTest..."); | |
108 var builder = new WasmModuleBuilder(); | |
109 | |
110 let d = builder.addImport("js_div", kSig_i_ii); | |
111 let f = AddFunctions(builder); | |
112 builder.setFunctionTableLength(kTableSize); | |
113 let g = builder.addImportedGlobal("base", undefined, kAstI32); | |
114 builder.addFunctionTableInit(g, true, [f.mul.index, f.add.index, | |
115 f.sub.index, | |
116 d]); | |
117 builder.addExportOfKind("table", kExternalTable, 0); | |
118 | |
119 let m1 = new WebAssembly.Module(builder.toBuffer()); | |
120 | |
121 var builder = new WasmModuleBuilder(); | |
122 | |
123 builder.addImportedTable("table", undefined, kTableSize, kTableSize); | |
124 builder.addFunction("main", kSig_i_ii) | |
125 .addBody([ | |
126 kExprI32Const, 33, // -- | |
127 kExprGetLocal, 0, // -- | |
128 kExprGetLocal, 1, // -- | |
129 kExprCallIndirect, 0, kTableZero]) // -- | |
130 .exportAs("main"); | |
131 | |
132 let m2 = new WebAssembly.Module(builder.toBuffer()); | |
133 | |
134 // Run 5 trials at different table bases. | |
135 for (let i = 0; i < 5; i++) { | |
136 print(" base = " + i); | |
137 let i1 = new WebAssembly.Instance(m1, {base: i, js_div: js_div}); | |
138 let table = i1.exports.table; | |
139 assertEquals(10, table.length); | |
140 let i2 = new WebAssembly.Instance(m2, {table: table}); | |
141 let main = i2.exports.main; | |
142 | |
143 for (var j = 0; j < i; j++) { | |
144 assertThrows(() => main(0, j)); | |
145 assertSame(null, table.get(j)); | |
146 } | |
147 | |
148 // mul | |
149 assertEquals("function", typeof table.get(i+0)); | |
150 assertEquals(0, main(0, i+0)); | |
151 assertEquals(66, main(2, i+0)); | |
152 | |
153 // add | |
154 assertEquals("function", typeof table.get(i+1)); | |
155 assertEquals(33, main(0, i+1)); | |
156 assertEquals(38, main(5, i+1)); | |
157 | |
158 // sub | |
159 assertEquals("function", typeof table.get(i+2)); | |
160 assertEquals(32, main(1, i+2)); | |
161 assertEquals(28, main(5, i+2)); | |
162 | |
163 // div | |
164 assertEquals("function", typeof table.get(i+3)); | |
165 assertEquals(8, main(4, i+3)); | |
166 assertEquals(3, main(11, i+3)); | |
167 | |
168 for (var j = i + 4; j < (kTableSize + 5); j++) { | |
169 assertThrows(x => main(0, j)); | |
170 if (j < kTableSize) assertSame(null, table.get(j)); | |
171 } | |
172 } | |
173 })(); | |
174 | |
175 (function ImportedTableTest() { | |
176 let kTableSize = 10; | |
177 print("ManualTableTest..."); | |
178 | |
179 var builder = new WasmModuleBuilder(); | |
180 | |
181 let d = builder.addImport("js_div", kSig_i_ii); | |
182 builder.addImportedTable("table", undefined, kTableSize, kTableSize); | |
183 let g = builder.addImportedGlobal("base", undefined, kAstI32); | |
184 let f = AddFunctions(builder); | |
185 builder.addFunctionTableInit(g, true, [f.mul.index, f.add.index, | |
186 f.sub.index, | |
187 d]); | |
188 builder.addFunction("main", kSig_i_ii) | |
189 .addBody([ | |
190 kExprI32Const, 55, // -- | |
191 kExprGetLocal, 0, // -- | |
192 kExprGetLocal, 1, // -- | |
193 kExprCallIndirect, 0, kTableZero]) // -- | |
194 .exportAs("main"); | |
195 | |
196 let m2 = new WebAssembly.Module(builder.toBuffer()); | |
197 | |
198 // Run 5 trials at different table bases. | |
199 for (let i = 0; i < 5; i++) { | |
200 print(" base = " + i); | |
201 let table = new WebAssembly.Table({element: "anyfunc", | |
202 initial: kTableSize}); | |
203 assertEquals(10, table.length); | |
204 let i2 = new WebAssembly.Instance(m2, {base: i, table: table, | |
205 js_div: js_div}); | |
206 let main = i2.exports.main; | |
207 | |
208 for (var j = 0; j < i; j++) { | |
209 assertThrows(() => main(0, j)); | |
210 assertSame(null, table.get(j)); | |
211 } | |
212 | |
213 // mul | |
214 assertEquals("function", typeof table.get(i+0)); | |
215 assertEquals(0, main(0, i+0)); | |
216 assertEquals(110, main(2, i+0)); | |
217 | |
218 // add | |
219 assertEquals("function", typeof table.get(i+1)); | |
220 assertEquals(55, main(0, i+1)); | |
221 assertEquals(60, main(5, i+1)); | |
222 | |
223 // sub | |
224 assertEquals("function", typeof table.get(i+2)); | |
225 assertEquals(54, main(1, i+2)); | |
226 assertEquals(50, main(5, i+2)); | |
227 | |
228 // div | |
229 assertEquals("function", typeof table.get(i+3)); | |
230 assertEquals(13, main(4, i+3)); | |
231 assertEquals(5, main(11, i+3)); | |
232 | |
233 for (var j = i + 4; j < (kTableSize + 5); j++) { | |
234 assertThrows(x => main(0, j)); | |
235 if (j < kTableSize) assertSame(null, table.get(j)); | |
236 } | |
237 } | |
238 })(); | |
239 | |
240 | |
241 (function CumulativeTest() { | |
242 print("CumulativeTest..."); | |
243 | |
244 let kTableSize = 10; | |
245 let table = new WebAssembly.Table({element: "anyfunc", initial: 10}); | |
246 | |
247 var builder = new WasmModuleBuilder(); | |
248 | |
249 builder.addImportedTable("table", undefined, kTableSize, kTableSize); | |
250 let g = builder.addImportedGlobal("base", undefined, kAstI32); | |
251 let sig_index = builder.addType(kSig_i_v); | |
252 builder.addFunction("g", sig_index) | |
253 .addBody([ | |
254 kExprGetGlobal, g | |
255 ]); | |
256 builder.addFunction("main", kSig_i_ii) | |
257 .addBody([ | |
258 kExprGetLocal, 0, | |
259 kExprCallIndirect, sig_index, kTableZero]) // -- | |
260 .exportAs("main"); | |
261 builder.addFunctionTableInit(g, true, [g]); | |
262 | |
263 let module = new WebAssembly.Module(builder.toBuffer()); | |
264 | |
265 for (var i = 0; i < kTableSize; i++) { | |
266 print(" base = " + i); | |
267 let instance = new WebAssembly.Instance(module, {base: i, table: table}); | |
268 | |
269 for (var j = 0; j < kTableSize; j++) { | |
270 let func = table.get(j); | |
271 if (j > i) { | |
272 assertSame(null, func); | |
273 assertTraps(kTrapFuncSigMismatch, () => instance.exports.main(j)); | |
274 } else { | |
275 assertEquals("function", typeof func); | |
276 assertEquals(j, func()); | |
277 assertEquals(j, instance.exports.main(j)); | |
278 } | |
279 } | |
280 } | |
281 })(); | |
282 | |
283 (function TwoWayTest() { | |
284 print("TwoWayTest..."); | |
285 let kTableSize = 3; | |
286 | |
287 // Module {m1} defines the table and exports it. | |
288 var builder = new WasmModuleBuilder(); | |
289 builder.addType(kSig_i_i); | |
290 builder.addType(kSig_i_ii); | |
291 var sig_index1 = builder.addType(kSig_i_v); | |
292 var f1 = builder.addFunction("f1", sig_index1) | |
293 .addBody([kExprI32Const, 11]); | |
294 | |
295 builder.addFunction("main", kSig_i_ii) | |
296 .addBody([ | |
297 kExprGetLocal, 0, // -- | |
298 kExprCallIndirect, sig_index1, kTableZero]) // -- | |
299 .exportAs("main"); | |
300 | |
301 builder.setFunctionTableLength(kTableSize); | |
302 builder.addFunctionTableInit(0, false, [f1.index]); | |
303 builder.addExportOfKind("table", kExternalTable, 0); | |
304 | |
305 var m1 = new WebAssembly.Module(builder.toBuffer()); | |
306 | |
307 // Module {m2} imports the table and adds {f2}. | |
308 var builder = new WasmModuleBuilder(); | |
309 builder.addType(kSig_i_ii); | |
310 var sig_index2 = builder.addType(kSig_i_v); | |
311 var f2 = builder.addFunction("f2", sig_index2) | |
312 .addBody([kExprI32Const, 22]); | |
313 | |
314 builder.addFunction("main", kSig_i_ii) | |
315 .addBody([ | |
316 kExprGetLocal, 0, // -- | |
317 kExprCallIndirect, sig_index2, kTableZero]) // -- | |
318 .exportAs("main"); | |
319 | |
320 builder.setFunctionTableLength(kTableSize); | |
321 builder.addFunctionTableInit(1, false, [f2.index]); | |
322 builder.addImportedTable("table", undefined, kTableSize, kTableSize); | |
323 | |
324 var m2 = new WebAssembly.Module(builder.toBuffer()); | |
325 | |
326 assertFalse(sig_index1 == sig_index2); | |
327 | |
328 var i1 = new WebAssembly.Instance(m1); | |
329 var i2 = new WebAssembly.Instance(m2, {table: i1.exports.table}); | |
330 | |
331 assertEquals(11, i1.exports.main(0)); | |
332 assertEquals(11, i2.exports.main(0)); | |
333 | |
334 assertEquals(22, i1.exports.main(1)); | |
335 assertEquals(22, i2.exports.main(1)); | |
336 | |
337 assertThrows(() => i1.exports.main(2)); | |
338 assertThrows(() => i2.exports.main(2)); | |
339 assertThrows(() => i1.exports.main(3)); | |
340 assertThrows(() => i2.exports.main(3)); | |
341 | |
342 })(); | |
343 | |
344 (function MismatchedTableSize() { | |
345 print("MismatchedTableSize..."); | |
346 let kTableSize = 5; | |
347 | |
348 for (var expsize = 1; expsize < 4; expsize++) { | |
349 for (var impsize = 1; impsize < 4; impsize++) { | |
350 print(" expsize = " + expsize + ", impsize = " + impsize); | |
351 var builder = new WasmModuleBuilder(); | |
352 builder.setFunctionTableLength(expsize); | |
353 builder.addExportOfKind("expfoo", kExternalTable, 0); | |
354 | |
355 let m1 = new WebAssembly.Module(builder.toBuffer()); | |
356 | |
357 var builder = new WasmModuleBuilder(); | |
358 builder.addImportedTable("impfoo", undefined, impsize, impsize); | |
359 | |
360 let m2 = new WebAssembly.Module(builder.toBuffer()); | |
361 | |
362 var i1 = new WebAssembly.Instance(m1); | |
363 | |
364 // TODO(titzer): v8 currently requires import table size to match | |
365 // export table size. | |
366 var ffi = {impfoo: i1.exports.expfoo}; | |
367 if (expsize == impsize) { | |
368 var i2 = new WebAssembly.Instance(m2, ffi); | |
369 } else { | |
370 assertThrows(() => new WebAssembly.Instance(m2, ffi)); | |
371 } | |
372 } | |
373 } | |
374 | |
375 | |
376 | |
377 })(); | |
OLD | NEW |