blob: 33d1c3551ccc79a14243f90d05c792ace75d54b5 [file] [log] [blame]
Ben Murdoch097c5b22016-05-18 11:27:45 +01001// Copyright 2015 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
6
7load("test/mjsunit/wasm/wasm-constants.js");
8
9function testCallImport(func, check) {
10 var kBodySize = 6;
11 var kNameFunOffset = 29 + kBodySize + 1;
12 var kNameMainOffset = kNameFunOffset + 4;
13
14 var ffi = new Object();
15 ffi.fun = func;
16
17 var data = bytes(
18 // signatures
19 kDeclSignatures, 1,
20 2, kAstI32, kAstF64, kAstF64, // (f64,f64) -> int
21 // -- main function
22 kDeclFunctions,
23 1,
24 kDeclFunctionName | kDeclFunctionExport,
25 0, 0,
26 kNameMainOffset, 0, 0, 0, // name offset
27 kBodySize, 0,
28 // main body
29 kExprCallImport, 0, // --
30 kExprGetLocal, 0, // --
31 kExprGetLocal, 1, // --
32 // imports
33 kDeclImportTable,
34 1,
35 0, 0, // sig index
36 0, 0, 0, 0, // module name offset
37 kNameFunOffset, 0, 0, 0, // function name offset
38 // names
39 kDeclEnd,
40 'f', 'u', 'n', 0, // --
41 'm', 'a', 'i', 'n', 0 // --
42 );
43
44 var module = _WASMEXP_.instantiateModule(data, ffi);
45
46 assertEquals("function", typeof module.main);
47
48 for (var i = 0; i < 100000; i += 10003) {
49 var a = 22.5 + i, b = 10.5 + i;
50 var r = module.main(a, b);
51 check(r, a, b);
52 }
53}
54
55var global = (function() { return this; })();
56var params = [-99, -99, -99, -99];
57var was_called = false;
58var length = -1;
59
60function FOREIGN_SUB(a, b) {
61 print("FOREIGN_SUB(" + a + ", " + b + ")");
62 was_called = true;
63 params[0] = this;
64 params[1] = a;
65 params[2] = b;
66 return (a - b) | 0;
67}
68
69function check_FOREIGN_SUB(r, a, b) {
70 assertEquals(a - b | 0, r);
71 assertTrue(was_called);
72// assertEquals(global, params[0]); // sloppy mode
73 assertEquals(a, params[1]);
74 assertEquals(b, params[2]);
75 was_called = false;
76}
77
78testCallImport(FOREIGN_SUB, check_FOREIGN_SUB);
79
80
81function FOREIGN_ABCD(a, b, c, d) {
82 print("FOREIGN_ABCD(" + a + ", " + b + ", " + c + ", " + d + ")");
83 was_called = true;
84 params[0] = this;
85 params[1] = a;
86 params[2] = b;
87 params[3] = c;
88 params[4] = d;
89 return (a * b * 6) | 0;
90}
91
92function check_FOREIGN_ABCD(r, a, b) {
93 assertEquals((a * b * 6) | 0, r);
94 assertTrue(was_called);
95// assertEquals(global, params[0]); // sloppy mode.
96 assertEquals(a, params[1]);
97 assertEquals(b, params[2]);
98 assertEquals(undefined, params[3]);
99 assertEquals(undefined, params[4]);
100 was_called = false;
101}
102
103testCallImport(FOREIGN_ABCD, check_FOREIGN_ABCD);
104
105function FOREIGN_ARGUMENTS0() {
106 print("FOREIGN_ARGUMENTS0");
107 was_called = true;
108 length = arguments.length;
109 for (var i = 0; i < arguments.length; i++) {
110 params[i] = arguments[i];
111 }
112 return (arguments[0] * arguments[1] * 7) | 0;
113}
114
115function FOREIGN_ARGUMENTS1(a) {
116 print("FOREIGN_ARGUMENTS1", a);
117 was_called = true;
118 length = arguments.length;
119 for (var i = 0; i < arguments.length; i++) {
120 params[i] = arguments[i];
121 }
122 return (arguments[0] * arguments[1] * 7) | 0;
123}
124
125function FOREIGN_ARGUMENTS2(a, b) {
126 print("FOREIGN_ARGUMENTS2", a, b);
127 was_called = true;
128 length = arguments.length;
129 for (var i = 0; i < arguments.length; i++) {
130 params[i] = arguments[i];
131 }
132 return (a * b * 7) | 0;
133}
134
135function FOREIGN_ARGUMENTS3(a, b, c) {
136 print("FOREIGN_ARGUMENTS3", a, b, c);
137 was_called = true;
138 length = arguments.length;
139 for (var i = 0; i < arguments.length; i++) {
140 params[i] = arguments[i];
141 }
142 return (a * b * 7) | 0;
143}
144
145function FOREIGN_ARGUMENTS4(a, b, c, d) {
146 print("FOREIGN_ARGUMENTS4", a, b, c, d);
147 was_called = true;
148 length = arguments.length;
149 for (var i = 0; i < arguments.length; i++) {
150 params[i] = arguments[i];
151 }
152 return (a * b * 7) | 0;
153}
154
155function check_FOREIGN_ARGUMENTS(r, a, b) {
156 assertEquals((a * b * 7) | 0, r);
157 assertTrue(was_called);
158 assertEquals(2, length);
159 assertEquals(a, params[0]);
160 assertEquals(b, params[1]);
161 was_called = false;
162}
163
164// Check a bunch of uses of the arguments object.
165testCallImport(FOREIGN_ARGUMENTS0, check_FOREIGN_ARGUMENTS);
166testCallImport(FOREIGN_ARGUMENTS1, check_FOREIGN_ARGUMENTS);
167testCallImport(FOREIGN_ARGUMENTS2, check_FOREIGN_ARGUMENTS);
168testCallImport(FOREIGN_ARGUMENTS3, check_FOREIGN_ARGUMENTS);
169testCallImport(FOREIGN_ARGUMENTS4, check_FOREIGN_ARGUMENTS);
170
171function returnValue(val) {
172 return function(a, b) {
173 print("RETURN_VALUE ", val);
174 return val;
175 }
176}
177
178
179function checkReturn(expected) {
180 return function(r, a, b) { assertEquals(expected, r); }
181}
182
183// Check that returning weird values doesn't crash
184testCallImport(returnValue(undefined), checkReturn(0));
185testCallImport(returnValue(null), checkReturn(0));
186testCallImport(returnValue("0"), checkReturn(0));
187testCallImport(returnValue("-77"), checkReturn(-77));
188
189var objWithValueOf = {valueOf: function() { return 198; }}
190
191testCallImport(returnValue(objWithValueOf), checkReturn(198));
192
193
194function testCallBinopVoid(type, func, check) {
195 var kBodySize = 10;
196 var kNameFunOffset = 28 + kBodySize + 1;
197 var kNameMainOffset = kNameFunOffset + 4;
198
199 var ffi = new Object();
200
201 var passed_length = -1;
202 var passed_a = -1;
203 var passed_b = -1;
204 var args_a = -1;
205 var args_b = -1;
206
207 ffi.fun = function(a, b) {
208 passed_length = arguments.length;
209 passed_a = a;
210 passed_b = b;
211 args_a = arguments[0];
212 args_b = arguments[1];
213 }
214
215 var data = bytes(
216 // -- signatures
217 kDeclSignatures, 2,
218 2, kAstStmt, type, type, // (type,type)->void
219 2, kAstI32, type, type, // (type,type)->int
220 // -- foreign function
221 kDeclFunctions, 2,
222 kDeclFunctionName | kDeclFunctionImport,
223 0, 0, // signature index
224 kNameFunOffset, 0, 0, 0, // name offset
225 // -- main function
226 kDeclFunctionName | kDeclFunctionExport,
227 1, 0, // signature index
228 kNameMainOffset, 0, 0, 0, // name offset
229 kBodySize, 0, // body size
230 // main body
231 kExprBlock, 2, // --
232 kExprCallFunction, 0, // --
233 kExprGetLocal, 0, // --
234 kExprGetLocal, 1, // --
235 kExprI8Const, 99, // --
236 // names
237 kDeclEnd,
238 'f', 'u', 'n', 0, // --
239 'm', 'a', 'i', 'n', 0 // --
240 );
241
242 var module = _WASMEXP_.instantiateModule(data, ffi);
243
244 assertEquals("function", typeof module.main);
245
246 print("testCallBinopVoid", type);
247
248 for (var i = 0; i < 100000; i += 10003.1) {
249 var a = 22.5 + i, b = 10.5 + i;
250 var r = module.main(a, b);
251 assertEquals(99, r);
252 assertEquals(2, passed_length);
253 var expected_a, expected_b;
254 switch (type) {
255 case kAstI32: {
256 expected_a = a | 0;
257 expected_b = b | 0;
258 break;
259 }
260 case kAstF32: {
261 expected_a = Math.fround(a);
262 expected_b = Math.fround(b);
263 break;
264 }
265 case kAstF64: {
266 expected_a = a;
267 expected_b = b;
268 break;
269 }
270 }
271
272 assertEquals(expected_a, args_a);
273 assertEquals(expected_b, args_b);
274 assertEquals(expected_a, passed_a);
275 assertEquals(expected_b, passed_b);
276 }
277}
278
279
280testCallBinopVoid(kAstI32);
281// TODO testCallBinopVoid(kAstI64);
282testCallBinopVoid(kAstF32);
283testCallBinopVoid(kAstF64);
284
285
286
287function testCallPrint() {
288 var kBodySize = 10;
289 var kNamePrintOffset = 10 + 7 + 7 + 9 + kBodySize + 1;
290 var kNameMainOffset = kNamePrintOffset + 6;
291
292 var ffi = new Object();
293 ffi.print = print;
294
295 var data = bytes(
296 // -- signatures
297 kDeclSignatures, 2,
298 1, kAstStmt, kAstI32, // i32->void
299 1, kAstStmt, kAstF64, // f64->int
300 kDeclFunctions, 3,
301 // -- import print i32
302 kDeclFunctionName | kDeclFunctionImport,
303 0, 0, // signature index
304 kNamePrintOffset, 0, 0, 0, // name offset
305 // -- import print f64
306 kDeclFunctionName | kDeclFunctionImport,
307 1, 0, // signature index
308 kNamePrintOffset, 0, 0, 0, // name offset
309 // -- decl main
310 kDeclFunctionName | kDeclFunctionExport,
311 1, 0, // signature index
312 kNameMainOffset, 0, 0, 0, // name offset
313 kBodySize, 0, // body size
314 // main body
315 kExprBlock, 2, // --
316 kExprCallFunction, 0, // --
317 kExprI8Const, 97, // --
318 kExprCallFunction, 1, // --
319 kExprGetLocal, 0, // --
320 // names
321 kDeclEnd,
322 'p', 'r', 'i', 'n', 't', 0, // --
323 'm', 'a', 'i', 'n', 0 // --
324 );
325
326 var module = _WASMEXP_.instantiateModule(data, ffi);
327
328 assertEquals("function", typeof module.main);
329
330 for (var i = -9; i < 900; i += 6.125) {
331 module.main(i);
332 }
333}
334
335testCallPrint();
336testCallPrint();
337
338
339function testCallImport2(foo, bar, expected) {
340 var kBodySize = 5;
341 var kNameFooOffset = 37 + kBodySize + 1;
342 var kNameBarOffset = kNameFooOffset + 4;
343 var kNameMainOffset = kNameBarOffset + 4;
344
345 var ffi = new Object();
346 ffi.foo = foo;
347 ffi.bar = bar;
348
349 var data = bytes(
350 // signatures
351 kDeclSignatures, 1,
352 0, kAstI32, // void -> i32
353 // -- main function
354 kDeclFunctions,
355 1,
356 kDeclFunctionName | kDeclFunctionExport,
357 0, 0,
358 kNameMainOffset, 0, 0, 0, // name offset
359 kBodySize, 0,
360 // main body
361 kExprI32Add, // --
362 kExprCallImport, 0, // --
363 kExprCallImport, 1, // --
364 // imports
365 kDeclImportTable,
366 2,
367 0, 0, // sig index
368 0, 0, 0, 0, // module name offset
369 kNameFooOffset, 0, 0, 0, // function name offset
370 0, 0, // sig index
371 0, 0, 0, 0, // module name offset
372 kNameBarOffset, 0, 0, 0, // function name offset
373 // names
374 kDeclEnd,
375 'f', 'o', 'o', 0, // --
376 'b', 'a', 'r', 0, // --
377 'm', 'a', 'i', 'n', 0 // --
378 );
379
380 var module = _WASMEXP_.instantiateModule(data, ffi);
381
382 assertEquals("function", typeof module.main);
383
384 assertEquals(expected, module.main());
385}
386
387testCallImport2(function() { return 33; }, function () { return 44; }, 77);