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 #include <stdint.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9
10 #include "include/v8-function.h"
11 #include "src/api/api-inl.h"
12 #include "src/codegen/assembler-inl.h"
13 #include "src/objects/heap-number-inl.h"
14 #include "test/cctest/cctest.h"
15 #include "test/cctest/compiler/value-helper.h"
16 #include "test/cctest/wasm/wasm-run-utils.h"
17 #include "test/common/wasm/test-signatures.h"
18 #include "test/common/wasm/wasm-macro-gen.h"
19
20 namespace v8 {
21 namespace internal {
22 namespace wasm {
23
24 namespace {
25 // A helper for generating predictable but unique argument values that
26 // are easy to debug (e.g. with misaligned stacks).
27 class PredictableInputValues {
28 public:
29 int base_;
PredictableInputValues(int base)30 explicit PredictableInputValues(int base) : base_(base) {}
arg_d(int which)31 double arg_d(int which) { return base_ * which + ((which & 1) * 0.5); }
arg_f(int which)32 float arg_f(int which) { return base_ * which + ((which & 1) * 0.25); }
arg_i(int which)33 int32_t arg_i(int which) { return base_ * which + ((which & 1) * kMinInt); }
arg_l(int which)34 int64_t arg_l(int which) {
35 return base_ * which + ((which & 1) * (0x04030201LL << 32));
36 }
37 };
38
CreateJSSelector(FunctionSig * sig,int which)39 ManuallyImportedJSFunction CreateJSSelector(FunctionSig* sig, int which) {
40 const int kMaxParams = 11;
41 static const char* formals[kMaxParams] = {"",
42 "a",
43 "a,b",
44 "a,b,c",
45 "a,b,c,d",
46 "a,b,c,d,e",
47 "a,b,c,d,e,f",
48 "a,b,c,d,e,f,g",
49 "a,b,c,d,e,f,g,h",
50 "a,b,c,d,e,f,g,h,i",
51 "a,b,c,d,e,f,g,h,i,j"};
52 CHECK_LT(which, static_cast<int>(sig->parameter_count()));
53 CHECK_LT(static_cast<int>(sig->parameter_count()), kMaxParams);
54
55 base::EmbeddedVector<char, 256> source;
56 char param = 'a' + which;
57 SNPrintF(source, "(function(%s) { return %c; })",
58 formals[sig->parameter_count()], param);
59
60 Handle<JSFunction> js_function =
61 Handle<JSFunction>::cast(v8::Utils::OpenHandle(
62 *v8::Local<v8::Function>::Cast(CompileRun(source.begin()))));
63 ManuallyImportedJSFunction import = {sig, js_function};
64
65 return import;
66 }
67 } // namespace
68
WASM_COMPILED_EXEC_TEST(Run_Int32Sub_jswrapped)69 WASM_COMPILED_EXEC_TEST(Run_Int32Sub_jswrapped) {
70 WasmRunner<int, int, int> r(execution_tier);
71 BUILD(r, WASM_I32_SUB(WASM_LOCAL_GET(0), WASM_LOCAL_GET(1)));
72
73 r.CheckCallViaJS(33, 44, 11);
74 r.CheckCallViaJS(-8723487, -8000000, 723487);
75 }
76
WASM_COMPILED_EXEC_TEST(Run_Float32Div_jswrapped)77 WASM_COMPILED_EXEC_TEST(Run_Float32Div_jswrapped) {
78 WasmRunner<float, float, float> r(execution_tier);
79 BUILD(r, WASM_F32_DIV(WASM_LOCAL_GET(0), WASM_LOCAL_GET(1)));
80
81 r.CheckCallViaJS(92, 46, 0.5);
82 r.CheckCallViaJS(64, -16, -0.25);
83 }
84
WASM_COMPILED_EXEC_TEST(Run_Float64Add_jswrapped)85 WASM_COMPILED_EXEC_TEST(Run_Float64Add_jswrapped) {
86 WasmRunner<double, double, double> r(execution_tier);
87 BUILD(r, WASM_F64_ADD(WASM_LOCAL_GET(0), WASM_LOCAL_GET(1)));
88
89 r.CheckCallViaJS(3, 2, 1);
90 r.CheckCallViaJS(-5.5, -5.25, -0.25);
91 }
92
WASM_COMPILED_EXEC_TEST(Run_I32Popcount_jswrapped)93 WASM_COMPILED_EXEC_TEST(Run_I32Popcount_jswrapped) {
94 WasmRunner<int, int> r(execution_tier);
95 BUILD(r, WASM_I32_POPCNT(WASM_LOCAL_GET(0)));
96
97 r.CheckCallViaJS(2, 9);
98 r.CheckCallViaJS(3, 11);
99 r.CheckCallViaJS(6, 0x3F);
100 }
101
WASM_COMPILED_EXEC_TEST(Run_CallJS_Add_jswrapped)102 WASM_COMPILED_EXEC_TEST(Run_CallJS_Add_jswrapped) {
103 TestSignatures sigs;
104 HandleScope scope(CcTest::InitIsolateOnce());
105 const char* source = "(function(a) { return a + 99; })";
106 Handle<JSFunction> js_function =
107 Handle<JSFunction>::cast(v8::Utils::OpenHandle(
108 *v8::Local<v8::Function>::Cast(CompileRun(source))));
109 ManuallyImportedJSFunction import = {sigs.i_i(), js_function};
110 WasmRunner<int, int> r(execution_tier, &import);
111 uint32_t js_index = 0;
112 BUILD(r, WASM_CALL_FUNCTION(js_index, WASM_LOCAL_GET(0)));
113
114 r.CheckCallViaJS(101, 2);
115 r.CheckCallViaJS(199, 100);
116 r.CheckCallViaJS(-666666801, -666666900);
117 }
118
WASM_COMPILED_EXEC_TEST(Run_IndirectCallJSFunction)119 WASM_COMPILED_EXEC_TEST(Run_IndirectCallJSFunction) {
120 Isolate* isolate = CcTest::InitIsolateOnce();
121 HandleScope scope(isolate);
122 TestSignatures sigs;
123
124 const char* source = "(function(a, b, c) { if(c) return a; return b; })";
125 Handle<JSFunction> js_function =
126 Handle<JSFunction>::cast(v8::Utils::OpenHandle(
127 *v8::Local<v8::Function>::Cast(CompileRun(source))));
128
129 ManuallyImportedJSFunction import = {sigs.i_iii(), js_function};
130
131 WasmRunner<int32_t, int32_t> r(execution_tier, &import);
132
133 const uint32_t js_index = 0;
134 const int32_t left = -2;
135 const int32_t right = 3;
136
137 WasmFunctionCompiler& rc_fn = r.NewFunction(sigs.i_i(), "rc");
138
139 byte sig_index = r.builder().AddSignature(sigs.i_iii());
140 uint16_t indirect_function_table[] = {static_cast<uint16_t>(js_index)};
141
142 r.builder().AddIndirectFunctionTable(indirect_function_table,
143 arraysize(indirect_function_table));
144
145 BUILD(rc_fn, WASM_CALL_INDIRECT(sig_index, WASM_I32V(left), WASM_I32V(right),
146 WASM_LOCAL_GET(0), WASM_I32V(js_index)));
147
148 Handle<Object> args_left[] = {isolate->factory()->NewNumber(1)};
149 r.CheckCallApplyViaJS(left, rc_fn.function_index(), args_left, 1);
150
151 Handle<Object> args_right[] = {isolate->factory()->NewNumber(0)};
152 r.CheckCallApplyViaJS(right, rc_fn.function_index(), args_right, 1);
153 }
154
RunJSSelectTest(TestExecutionTier tier,int which)155 void RunJSSelectTest(TestExecutionTier tier, int which) {
156 const int kMaxParams = 8;
157 PredictableInputValues inputs(0x100);
158 ValueType type = kWasmF64;
159 ValueType types[kMaxParams + 1] = {type, type, type, type, type,
160 type, type, type, type};
161 for (int num_params = which + 1; num_params < kMaxParams; num_params++) {
162 HandleScope scope(CcTest::InitIsolateOnce());
163 FunctionSig sig(1, num_params, types);
164
165 ManuallyImportedJSFunction import = CreateJSSelector(&sig, which);
166 WasmRunner<void> r(tier, &import);
167 uint32_t js_index = 0;
168
169 WasmFunctionCompiler& t = r.NewFunction(&sig);
170
171 {
172 std::vector<byte> code;
173
174 for (int i = 0; i < num_params; i++) {
175 ADD_CODE(code, WASM_F64(inputs.arg_d(i)));
176 }
177
178 ADD_CODE(code, kExprCallFunction, static_cast<byte>(js_index));
179
180 size_t end = code.size();
181 code.push_back(0);
182 t.Build(&code[0], &code[end]);
183 }
184
185 double expected = inputs.arg_d(which);
186 r.CheckCallApplyViaJS(expected, t.function_index(), nullptr, 0);
187 }
188 }
189
WASM_COMPILED_EXEC_TEST(Run_JSSelect_0)190 WASM_COMPILED_EXEC_TEST(Run_JSSelect_0) {
191 CcTest::InitializeVM();
192 RunJSSelectTest(execution_tier, 0);
193 }
194
WASM_COMPILED_EXEC_TEST(Run_JSSelect_1)195 WASM_COMPILED_EXEC_TEST(Run_JSSelect_1) {
196 CcTest::InitializeVM();
197 RunJSSelectTest(execution_tier, 1);
198 }
199
WASM_COMPILED_EXEC_TEST(Run_JSSelect_2)200 WASM_COMPILED_EXEC_TEST(Run_JSSelect_2) {
201 CcTest::InitializeVM();
202 RunJSSelectTest(execution_tier, 2);
203 }
204
WASM_COMPILED_EXEC_TEST(Run_JSSelect_3)205 WASM_COMPILED_EXEC_TEST(Run_JSSelect_3) {
206 CcTest::InitializeVM();
207 RunJSSelectTest(execution_tier, 3);
208 }
209
WASM_COMPILED_EXEC_TEST(Run_JSSelect_4)210 WASM_COMPILED_EXEC_TEST(Run_JSSelect_4) {
211 CcTest::InitializeVM();
212 RunJSSelectTest(execution_tier, 4);
213 }
214
WASM_COMPILED_EXEC_TEST(Run_JSSelect_5)215 WASM_COMPILED_EXEC_TEST(Run_JSSelect_5) {
216 CcTest::InitializeVM();
217 RunJSSelectTest(execution_tier, 5);
218 }
219
WASM_COMPILED_EXEC_TEST(Run_JSSelect_6)220 WASM_COMPILED_EXEC_TEST(Run_JSSelect_6) {
221 CcTest::InitializeVM();
222 RunJSSelectTest(execution_tier, 6);
223 }
224
WASM_COMPILED_EXEC_TEST(Run_JSSelect_7)225 WASM_COMPILED_EXEC_TEST(Run_JSSelect_7) {
226 CcTest::InitializeVM();
227 RunJSSelectTest(execution_tier, 7);
228 }
229
RunWASMSelectTest(TestExecutionTier tier,int which)230 void RunWASMSelectTest(TestExecutionTier tier, int which) {
231 PredictableInputValues inputs(0x200);
232 Isolate* isolate = CcTest::InitIsolateOnce();
233 const int kMaxParams = 8;
234 for (int num_params = which + 1; num_params < kMaxParams; num_params++) {
235 ValueType type = kWasmF64;
236 ValueType types[kMaxParams + 1] = {type, type, type, type, type,
237 type, type, type, type};
238 FunctionSig sig(1, num_params, types);
239
240 WasmRunner<void> r(tier);
241 WasmFunctionCompiler& t = r.NewFunction(&sig);
242 BUILD(t, WASM_LOCAL_GET(which));
243
244 Handle<Object> args[] = {
245 isolate->factory()->NewNumber(inputs.arg_d(0)),
246 isolate->factory()->NewNumber(inputs.arg_d(1)),
247 isolate->factory()->NewNumber(inputs.arg_d(2)),
248 isolate->factory()->NewNumber(inputs.arg_d(3)),
249 isolate->factory()->NewNumber(inputs.arg_d(4)),
250 isolate->factory()->NewNumber(inputs.arg_d(5)),
251 isolate->factory()->NewNumber(inputs.arg_d(6)),
252 isolate->factory()->NewNumber(inputs.arg_d(7)),
253 };
254
255 double expected = inputs.arg_d(which);
256 r.CheckCallApplyViaJS(expected, t.function_index(), args, kMaxParams);
257 }
258 }
259
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_0)260 WASM_COMPILED_EXEC_TEST(Run_WASMSelect_0) {
261 CcTest::InitializeVM();
262 RunWASMSelectTest(execution_tier, 0);
263 }
264
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_1)265 WASM_COMPILED_EXEC_TEST(Run_WASMSelect_1) {
266 CcTest::InitializeVM();
267 RunWASMSelectTest(execution_tier, 1);
268 }
269
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_2)270 WASM_COMPILED_EXEC_TEST(Run_WASMSelect_2) {
271 CcTest::InitializeVM();
272 RunWASMSelectTest(execution_tier, 2);
273 }
274
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_3)275 WASM_COMPILED_EXEC_TEST(Run_WASMSelect_3) {
276 CcTest::InitializeVM();
277 RunWASMSelectTest(execution_tier, 3);
278 }
279
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_4)280 WASM_COMPILED_EXEC_TEST(Run_WASMSelect_4) {
281 CcTest::InitializeVM();
282 RunWASMSelectTest(execution_tier, 4);
283 }
284
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_5)285 WASM_COMPILED_EXEC_TEST(Run_WASMSelect_5) {
286 CcTest::InitializeVM();
287 RunWASMSelectTest(execution_tier, 5);
288 }
289
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_6)290 WASM_COMPILED_EXEC_TEST(Run_WASMSelect_6) {
291 CcTest::InitializeVM();
292 RunWASMSelectTest(execution_tier, 6);
293 }
294
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_7)295 WASM_COMPILED_EXEC_TEST(Run_WASMSelect_7) {
296 CcTest::InitializeVM();
297 RunWASMSelectTest(execution_tier, 7);
298 }
299
RunWASMSelectAlignTest(TestExecutionTier tier,int num_args,int num_params)300 void RunWASMSelectAlignTest(TestExecutionTier tier, int num_args,
301 int num_params) {
302 PredictableInputValues inputs(0x300);
303 Isolate* isolate = CcTest::InitIsolateOnce();
304 const int kMaxParams = 10;
305 DCHECK_LE(num_args, kMaxParams);
306 ValueType type = kWasmF64;
307 ValueType types[kMaxParams + 1] = {type, type, type, type, type, type,
308 type, type, type, type, type};
309 FunctionSig sig(1, num_params, types);
310
311 for (int which = 0; which < num_params; which++) {
312 WasmRunner<void> r(tier);
313 WasmFunctionCompiler& t = r.NewFunction(&sig);
314 BUILD(t, WASM_LOCAL_GET(which));
315
316 Handle<Object> args[] = {isolate->factory()->NewNumber(inputs.arg_d(0)),
317 isolate->factory()->NewNumber(inputs.arg_d(1)),
318 isolate->factory()->NewNumber(inputs.arg_d(2)),
319 isolate->factory()->NewNumber(inputs.arg_d(3)),
320 isolate->factory()->NewNumber(inputs.arg_d(4)),
321 isolate->factory()->NewNumber(inputs.arg_d(5)),
322 isolate->factory()->NewNumber(inputs.arg_d(6)),
323 isolate->factory()->NewNumber(inputs.arg_d(7)),
324 isolate->factory()->NewNumber(inputs.arg_d(8)),
325 isolate->factory()->NewNumber(inputs.arg_d(9))};
326
327 double nan = std::numeric_limits<double>::quiet_NaN();
328 double expected = which < num_args ? inputs.arg_d(which) : nan;
329 r.CheckCallApplyViaJS(expected, t.function_index(), args, num_args);
330 }
331 }
332
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_0)333 WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_0) {
334 CcTest::InitializeVM();
335 RunWASMSelectAlignTest(execution_tier, 0, 1);
336 RunWASMSelectAlignTest(execution_tier, 0, 2);
337 }
338
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_1)339 WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_1) {
340 CcTest::InitializeVM();
341 RunWASMSelectAlignTest(execution_tier, 1, 2);
342 RunWASMSelectAlignTest(execution_tier, 1, 3);
343 }
344
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_2)345 WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_2) {
346 CcTest::InitializeVM();
347 RunWASMSelectAlignTest(execution_tier, 2, 3);
348 RunWASMSelectAlignTest(execution_tier, 2, 4);
349 }
350
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_3)351 WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_3) {
352 CcTest::InitializeVM();
353 RunWASMSelectAlignTest(execution_tier, 3, 3);
354 RunWASMSelectAlignTest(execution_tier, 3, 4);
355 }
356
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_4)357 WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_4) {
358 CcTest::InitializeVM();
359 RunWASMSelectAlignTest(execution_tier, 4, 3);
360 RunWASMSelectAlignTest(execution_tier, 4, 4);
361 }
362
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_7)363 WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_7) {
364 CcTest::InitializeVM();
365 RunWASMSelectAlignTest(execution_tier, 7, 5);
366 RunWASMSelectAlignTest(execution_tier, 7, 6);
367 RunWASMSelectAlignTest(execution_tier, 7, 7);
368 }
369
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_8)370 WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_8) {
371 CcTest::InitializeVM();
372 RunWASMSelectAlignTest(execution_tier, 8, 5);
373 RunWASMSelectAlignTest(execution_tier, 8, 6);
374 RunWASMSelectAlignTest(execution_tier, 8, 7);
375 RunWASMSelectAlignTest(execution_tier, 8, 8);
376 }
377
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_9)378 WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_9) {
379 CcTest::InitializeVM();
380 RunWASMSelectAlignTest(execution_tier, 9, 6);
381 RunWASMSelectAlignTest(execution_tier, 9, 7);
382 RunWASMSelectAlignTest(execution_tier, 9, 8);
383 RunWASMSelectAlignTest(execution_tier, 9, 9);
384 }
385
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_10)386 WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_10) {
387 CcTest::InitializeVM();
388 RunWASMSelectAlignTest(execution_tier, 10, 7);
389 RunWASMSelectAlignTest(execution_tier, 10, 8);
390 RunWASMSelectAlignTest(execution_tier, 10, 9);
391 RunWASMSelectAlignTest(execution_tier, 10, 10);
392 }
393
RunJSSelectAlignTest(TestExecutionTier tier,int num_args,int num_params)394 void RunJSSelectAlignTest(TestExecutionTier tier, int num_args,
395 int num_params) {
396 PredictableInputValues inputs(0x400);
397 Isolate* isolate = CcTest::InitIsolateOnce();
398 Factory* factory = isolate->factory();
399 const int kMaxParams = 10;
400 CHECK_LE(num_args, kMaxParams);
401 CHECK_LE(num_params, kMaxParams);
402 ValueType type = kWasmF64;
403 ValueType types[kMaxParams + 1] = {type, type, type, type, type, type,
404 type, type, type, type, type};
405 FunctionSig sig(1, num_params, types);
406 i::AccountingAllocator allocator;
407 Zone zone(&allocator, ZONE_NAME);
408
409 // Build the calling code.
410 std::vector<byte> code;
411
412 for (int i = 0; i < num_params; i++) {
413 ADD_CODE(code, WASM_LOCAL_GET(i));
414 }
415
416 uint8_t imported_js_index = 0;
417 ADD_CODE(code, kExprCallFunction, imported_js_index);
418
419 size_t end = code.size();
420 code.push_back(0);
421
422 // Call different select JS functions.
423 for (int which = 0; which < num_params; which++) {
424 HandleScope scope(isolate);
425 ManuallyImportedJSFunction import = CreateJSSelector(&sig, which);
426 WasmRunner<void> r(tier, &import);
427 WasmFunctionCompiler& t = r.NewFunction(&sig);
428 t.Build(&code[0], &code[end]);
429
430 Handle<Object> args[] = {
431 factory->NewNumber(inputs.arg_d(0)),
432 factory->NewNumber(inputs.arg_d(1)),
433 factory->NewNumber(inputs.arg_d(2)),
434 factory->NewNumber(inputs.arg_d(3)),
435 factory->NewNumber(inputs.arg_d(4)),
436 factory->NewNumber(inputs.arg_d(5)),
437 factory->NewNumber(inputs.arg_d(6)),
438 factory->NewNumber(inputs.arg_d(7)),
439 factory->NewNumber(inputs.arg_d(8)),
440 factory->NewNumber(inputs.arg_d(9)),
441 };
442
443 double nan = std::numeric_limits<double>::quiet_NaN();
444 double expected = which < num_args ? inputs.arg_d(which) : nan;
445 r.CheckCallApplyViaJS(expected, t.function_index(), args, num_args);
446 }
447 }
448
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_0)449 WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_0) {
450 CcTest::InitializeVM();
451 RunJSSelectAlignTest(execution_tier, 0, 1);
452 RunJSSelectAlignTest(execution_tier, 0, 2);
453 }
454
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_1)455 WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_1) {
456 CcTest::InitializeVM();
457 RunJSSelectAlignTest(execution_tier, 1, 2);
458 RunJSSelectAlignTest(execution_tier, 1, 3);
459 }
460
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_2)461 WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_2) {
462 CcTest::InitializeVM();
463 RunJSSelectAlignTest(execution_tier, 2, 3);
464 RunJSSelectAlignTest(execution_tier, 2, 4);
465 }
466
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_3)467 WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_3) {
468 CcTest::InitializeVM();
469 RunJSSelectAlignTest(execution_tier, 3, 3);
470 RunJSSelectAlignTest(execution_tier, 3, 4);
471 }
472
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_4)473 WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_4) {
474 CcTest::InitializeVM();
475 RunJSSelectAlignTest(execution_tier, 4, 3);
476 RunJSSelectAlignTest(execution_tier, 4, 4);
477 }
478
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_7)479 WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_7) {
480 CcTest::InitializeVM();
481 RunJSSelectAlignTest(execution_tier, 7, 3);
482 RunJSSelectAlignTest(execution_tier, 7, 4);
483 RunJSSelectAlignTest(execution_tier, 7, 4);
484 RunJSSelectAlignTest(execution_tier, 7, 4);
485 }
486
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_8)487 WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_8) {
488 CcTest::InitializeVM();
489 RunJSSelectAlignTest(execution_tier, 8, 5);
490 RunJSSelectAlignTest(execution_tier, 8, 6);
491 RunJSSelectAlignTest(execution_tier, 8, 7);
492 RunJSSelectAlignTest(execution_tier, 8, 8);
493 }
494
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_9)495 WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_9) {
496 CcTest::InitializeVM();
497 RunJSSelectAlignTest(execution_tier, 9, 6);
498 RunJSSelectAlignTest(execution_tier, 9, 7);
499 RunJSSelectAlignTest(execution_tier, 9, 8);
500 RunJSSelectAlignTest(execution_tier, 9, 9);
501 }
502
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_10)503 WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_10) {
504 CcTest::InitializeVM();
505 RunJSSelectAlignTest(execution_tier, 10, 7);
506 RunJSSelectAlignTest(execution_tier, 10, 8);
507 RunJSSelectAlignTest(execution_tier, 10, 9);
508 RunJSSelectAlignTest(execution_tier, 10, 10);
509 }
510
511 // Set up a test with an import, so we can return call it.
512 // Create a javascript function that returns left or right arguments
513 // depending on the value of the third argument
514 // function (a,b,c){ if(c)return a; return b; }
515
RunPickerTest(TestExecutionTier tier,bool indirect)516 void RunPickerTest(TestExecutionTier tier, bool indirect) {
517 EXPERIMENTAL_FLAG_SCOPE(return_call);
518 Isolate* isolate = CcTest::InitIsolateOnce();
519 HandleScope scope(isolate);
520 TestSignatures sigs;
521
522 const char* source = "(function(a,b,c) { if(c)return a; return b; })";
523 Handle<JSFunction> js_function =
524 Handle<JSFunction>::cast(v8::Utils::OpenHandle(
525 *v8::Local<v8::Function>::Cast(CompileRun(source))));
526
527 ManuallyImportedJSFunction import = {sigs.i_iii(), js_function};
528
529 WasmRunner<int32_t, int32_t> r(tier, &import);
530
531 const uint32_t js_index = 0;
532 const int32_t left = -2;
533 const int32_t right = 3;
534
535 WasmFunctionCompiler& rc_fn = r.NewFunction(sigs.i_i(), "rc");
536
537 if (indirect) {
538 byte sig_index = r.builder().AddSignature(sigs.i_iii());
539 uint16_t indirect_function_table[] = {static_cast<uint16_t>(js_index)};
540
541 r.builder().AddIndirectFunctionTable(indirect_function_table,
542 arraysize(indirect_function_table));
543
544 BUILD(rc_fn, WASM_RETURN_CALL_INDIRECT(sig_index, WASM_I32V(left),
545 WASM_I32V(right), WASM_LOCAL_GET(0),
546 WASM_I32V(js_index)));
547 } else {
548 BUILD(rc_fn,
549 WASM_RETURN_CALL_FUNCTION(js_index, WASM_I32V(left), WASM_I32V(right),
550 WASM_LOCAL_GET(0)));
551 }
552
553 Handle<Object> args_left[] = {isolate->factory()->NewNumber(1)};
554 r.CheckCallApplyViaJS(left, rc_fn.function_index(), args_left, 1);
555
556 Handle<Object> args_right[] = {isolate->factory()->NewNumber(0)};
557 r.CheckCallApplyViaJS(right, rc_fn.function_index(), args_right, 1);
558 }
559
WASM_COMPILED_EXEC_TEST(Run_ReturnCallImportedFunction)560 WASM_COMPILED_EXEC_TEST(Run_ReturnCallImportedFunction) {
561 RunPickerTest(execution_tier, false);
562 }
563
WASM_COMPILED_EXEC_TEST(Run_ReturnCallIndirectImportedFunction)564 WASM_COMPILED_EXEC_TEST(Run_ReturnCallIndirectImportedFunction) {
565 RunPickerTest(execution_tier, true);
566 }
567
568 } // namespace wasm
569 } // namespace internal
570 } // namespace v8
571