• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// 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");
8load("test/mjsunit/wasm/wasm-module-builder.js");
9
10function testCallFFI(func, check) {
11  var builder = new WasmModuleBuilder();
12
13  var sig_index = builder.addType(kSig_i_dd);
14  builder.addImport("func", sig_index);
15  builder.addFunction("main", sig_index)
16    .addBody([
17      kExprGetLocal, 0,            // --
18      kExprGetLocal, 1,            // --
19      kExprCallImport, kArity2, 0  // --
20    ])        // --
21    .exportFunc();
22
23  var main = builder.instantiate({func: func}).exports.main;
24
25  for (var i = 0; i < 100000; i += 10003) {
26    var a = 22.5 + i, b = 10.5 + i;
27    var r = main(a, b);
28    check(r, a, b);
29  }
30}
31
32var global = (function() { return this; })();
33var params = [-99, -99, -99, -99, -99];
34var was_called = false;
35var length = -1;
36
37function FOREIGN_SUB(a, b) {
38  print("FOREIGN_SUB(" + a + ", " + b + ")");
39  was_called = true;
40  params[0] = this;
41  params[1] = a;
42  params[2] = b;
43  return (a - b) | 0;
44}
45
46function check_FOREIGN_SUB(r, a, b) {
47    assertEquals(a - b | 0, r);
48    assertTrue(was_called);
49//    assertEquals(global, params[0]);  // sloppy mode
50    assertEquals(a, params[1]);
51    assertEquals(b, params[2]);
52    was_called = false;
53}
54
55testCallFFI(FOREIGN_SUB, check_FOREIGN_SUB);
56
57
58function FOREIGN_ABCD(a, b, c, d) {
59  print("FOREIGN_ABCD(" + a + ", " + b + ", " + c + ", " + d + ")");
60  was_called = true;
61  params[0] = this;
62  params[1] = a;
63  params[2] = b;
64  params[3] = c;
65  params[4] = d;
66  return (a * b * 6) | 0;
67}
68
69function check_FOREIGN_ABCD(r, a, b) {
70    assertEquals((a * b * 6) | 0, r);
71    assertTrue(was_called);
72//    assertEquals(global, params[0]);  // sloppy mode.
73    assertEquals(a, params[1]);
74    assertEquals(b, params[2]);
75    assertEquals(undefined, params[3]);
76    assertEquals(undefined, params[4]);
77    was_called = false;
78}
79
80testCallFFI(FOREIGN_ABCD, check_FOREIGN_ABCD);
81
82function FOREIGN_ARGUMENTS0() {
83  print("FOREIGN_ARGUMENTS0");
84  was_called = true;
85  length = arguments.length;
86  for (var i = 0; i < arguments.length; i++) {
87    params[i] = arguments[i];
88  }
89  return (arguments[0] * arguments[1] * 7) | 0;
90}
91
92function FOREIGN_ARGUMENTS1(a) {
93  print("FOREIGN_ARGUMENTS1", a);
94  was_called = true;
95  length = arguments.length;
96  for (var i = 0; i < arguments.length; i++) {
97    params[i] = arguments[i];
98  }
99  return (arguments[0] * arguments[1] * 7) | 0;
100}
101
102function FOREIGN_ARGUMENTS2(a, b) {
103  print("FOREIGN_ARGUMENTS2", a, b);
104  was_called = true;
105  length = arguments.length;
106  for (var i = 0; i < arguments.length; i++) {
107    params[i] = arguments[i];
108  }
109  return (a * b * 7) | 0;
110}
111
112function FOREIGN_ARGUMENTS3(a, b, c) {
113  print("FOREIGN_ARGUMENTS3", a, b, c);
114  was_called = true;
115  length = arguments.length;
116  for (var i = 0; i < arguments.length; i++) {
117    params[i] = arguments[i];
118  }
119  return (a * b * 7) | 0;
120}
121
122function FOREIGN_ARGUMENTS4(a, b, c, d) {
123  print("FOREIGN_ARGUMENTS4", a, b, c, d);
124  was_called = true;
125  length = arguments.length;
126  for (var i = 0; i < arguments.length; i++) {
127    params[i] = arguments[i];
128  }
129  return (a * b * 7) | 0;
130}
131
132function check_FOREIGN_ARGUMENTS(r, a, b) {
133  assertEquals((a * b * 7) | 0, r);
134  assertTrue(was_called);
135  assertEquals(2, length);
136  assertEquals(a, params[0]);
137  assertEquals(b, params[1]);
138  was_called = false;
139}
140
141// Check a bunch of uses of the arguments object.
142testCallFFI(FOREIGN_ARGUMENTS0, check_FOREIGN_ARGUMENTS);
143testCallFFI(FOREIGN_ARGUMENTS1, check_FOREIGN_ARGUMENTS);
144testCallFFI(FOREIGN_ARGUMENTS2, check_FOREIGN_ARGUMENTS);
145testCallFFI(FOREIGN_ARGUMENTS3, check_FOREIGN_ARGUMENTS);
146testCallFFI(FOREIGN_ARGUMENTS4, check_FOREIGN_ARGUMENTS);
147
148function returnValue(val) {
149  return function(a, b) {
150    print("RETURN_VALUE ", val);
151    return val;
152  }
153}
154
155
156function checkReturn(expected) {
157  return function(r, a, b) { assertEquals(expected, r); }
158}
159
160// Check that returning weird values doesn't crash
161testCallFFI(returnValue(undefined), checkReturn(0));
162testCallFFI(returnValue(null), checkReturn(0));
163testCallFFI(returnValue("0"), checkReturn(0));
164testCallFFI(returnValue("-77"), checkReturn(-77));
165
166var objWithValueOf = {valueOf: function() { return 198; }}
167
168testCallFFI(returnValue(objWithValueOf), checkReturn(198));
169
170
171function testCallBinopVoid(type, func, check) {
172  var passed_length = -1;
173  var passed_a = -1;
174  var passed_b = -1;
175  var args_a = -1;
176  var args_b = -1;
177
178  ffi = {func: function(a, b) {
179    passed_length = arguments.length;
180    passed_a = a;
181    passed_b = b;
182    args_a = arguments[0];
183    args_b = arguments[1];
184  }};
185
186  var builder = new WasmModuleBuilder();
187
188  builder.addImport("func", makeSig_v_xx(type));
189  builder.addFunction("main", makeSig_r_xx(kAstI32, type))
190    .addBody([
191      kExprGetLocal, 0,            // --
192      kExprGetLocal, 1,            // --
193      kExprCallImport, kArity2, 0, // --
194      kExprI8Const, 99             // --
195    ])                             // --
196    .exportFunc()
197
198  var main = builder.instantiate(ffi).exports.main;
199
200  print("testCallBinopVoid", type);
201
202  for (var i = 0; i < 100000; i += 10003.1) {
203    var a = 22.5 + i, b = 10.5 + i;
204    var r = main(a, b);
205    assertEquals(99, r);
206    assertEquals(2, passed_length);
207    var expected_a, expected_b;
208    switch (type) {
209      case kAstI32: {
210        expected_a = a | 0;
211        expected_b = b | 0;
212        break;
213      }
214      case kAstF32: {
215        expected_a = Math.fround(a);
216        expected_b = Math.fround(b);
217        break;
218      }
219      case kAstF64: {
220        expected_a = a;
221        expected_b = b;
222        break;
223      }
224    }
225
226    assertEquals(expected_a, args_a);
227    assertEquals(expected_b, args_b);
228    assertEquals(expected_a, passed_a);
229    assertEquals(expected_b, passed_b);
230  }
231}
232
233
234testCallBinopVoid(kAstI32);
235// TODO testCallBinopVoid(kAstI64);
236testCallBinopVoid(kAstF32);
237testCallBinopVoid(kAstF64);
238
239
240
241function testCallPrint() {
242  var builder = new WasmModuleBuilder();
243
244  builder.addImport("print", makeSig_v_x(kAstI32));
245  builder.addImport("print", makeSig_v_x(kAstF64));
246  builder.addFunction("main", makeSig_v_x(kAstF64))
247    .addBody([
248      kExprI8Const, 97,             // --
249      kExprCallImport, kArity1, 0,  // --
250      kExprGetLocal, 0,             // --
251      kExprCallImport, kArity1, 1   // --
252    ])        // --
253    .exportFunc()
254
255  var main = builder.instantiate({print: print}).exports.main;
256  for (var i = -9; i < 900; i += 6.125) main(i);
257}
258
259testCallPrint();
260testCallPrint();
261