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