91b102c763
The opcodes were renamed long ago, but the macros were still using the old syntax. This CL was created using the following command (for WASM_GET_LOCAL, WASM_SET_LOCAL, and WASM_TEE_LOCAL): ag -l WASM_GET_LOCAL | xargs -L 1 sed -i 's/\bWASM_SET_LOCAL\b/WASM_LOCAL_SET/g' R=ahaas@chromium.org Bug: v8:11074 Change-Id: I0018bea185030be29344e66e59706fed183cc2f1 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2595446 Reviewed-by: Andreas Haas <ahaas@chromium.org> Commit-Queue: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/master@{#71835}
578 lines
19 KiB
C++
578 lines
19 KiB
C++
// Copyright 2015 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "src/api/api-inl.h"
|
|
#include "src/codegen/assembler-inl.h"
|
|
#include "src/objects/heap-number-inl.h"
|
|
#include "test/cctest/cctest.h"
|
|
#include "test/cctest/compiler/value-helper.h"
|
|
#include "test/cctest/wasm/wasm-run-utils.h"
|
|
#include "test/common/wasm/test-signatures.h"
|
|
#include "test/common/wasm/wasm-macro-gen.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
namespace wasm {
|
|
|
|
#define ADD_CODE(vec, ...) \
|
|
do { \
|
|
byte __buf[] = {__VA_ARGS__}; \
|
|
for (size_t i = 0; i < sizeof(__buf); i++) vec.push_back(__buf[i]); \
|
|
} while (false)
|
|
|
|
namespace {
|
|
// A helper for generating predictable but unique argument values that
|
|
// are easy to debug (e.g. with misaligned stacks).
|
|
class PredictableInputValues {
|
|
public:
|
|
int base_;
|
|
explicit PredictableInputValues(int base) : base_(base) {}
|
|
double arg_d(int which) { return base_ * which + ((which & 1) * 0.5); }
|
|
float arg_f(int which) { return base_ * which + ((which & 1) * 0.25); }
|
|
int32_t arg_i(int which) { return base_ * which + ((which & 1) * kMinInt); }
|
|
int64_t arg_l(int which) {
|
|
return base_ * which + ((which & 1) * (0x04030201LL << 32));
|
|
}
|
|
};
|
|
|
|
ManuallyImportedJSFunction CreateJSSelector(FunctionSig* sig, int which) {
|
|
const int kMaxParams = 11;
|
|
static const char* formals[kMaxParams] = {"",
|
|
"a",
|
|
"a,b",
|
|
"a,b,c",
|
|
"a,b,c,d",
|
|
"a,b,c,d,e",
|
|
"a,b,c,d,e,f",
|
|
"a,b,c,d,e,f,g",
|
|
"a,b,c,d,e,f,g,h",
|
|
"a,b,c,d,e,f,g,h,i",
|
|
"a,b,c,d,e,f,g,h,i,j"};
|
|
CHECK_LT(which, static_cast<int>(sig->parameter_count()));
|
|
CHECK_LT(static_cast<int>(sig->parameter_count()), kMaxParams);
|
|
|
|
i::EmbeddedVector<char, 256> source;
|
|
char param = 'a' + which;
|
|
SNPrintF(source, "(function(%s) { return %c; })",
|
|
formals[sig->parameter_count()], param);
|
|
|
|
Handle<JSFunction> js_function =
|
|
Handle<JSFunction>::cast(v8::Utils::OpenHandle(
|
|
*v8::Local<v8::Function>::Cast(CompileRun(source.begin()))));
|
|
ManuallyImportedJSFunction import = {sig, js_function};
|
|
|
|
return import;
|
|
}
|
|
} // namespace
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_Int32Sub_jswrapped) {
|
|
WasmRunner<int, int, int> r(execution_tier);
|
|
BUILD(r, WASM_I32_SUB(WASM_LOCAL_GET(0), WASM_LOCAL_GET(1)));
|
|
|
|
r.CheckCallViaJS(33, 44, 11);
|
|
r.CheckCallViaJS(-8723487, -8000000, 723487);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_Float32Div_jswrapped) {
|
|
WasmRunner<float, float, float> r(execution_tier);
|
|
BUILD(r, WASM_F32_DIV(WASM_LOCAL_GET(0), WASM_LOCAL_GET(1)));
|
|
|
|
r.CheckCallViaJS(92, 46, 0.5);
|
|
r.CheckCallViaJS(64, -16, -0.25);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_Float64Add_jswrapped) {
|
|
WasmRunner<double, double, double> r(execution_tier);
|
|
BUILD(r, WASM_F64_ADD(WASM_LOCAL_GET(0), WASM_LOCAL_GET(1)));
|
|
|
|
r.CheckCallViaJS(3, 2, 1);
|
|
r.CheckCallViaJS(-5.5, -5.25, -0.25);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_I32Popcount_jswrapped) {
|
|
WasmRunner<int, int> r(execution_tier);
|
|
BUILD(r, WASM_I32_POPCNT(WASM_LOCAL_GET(0)));
|
|
|
|
r.CheckCallViaJS(2, 9);
|
|
r.CheckCallViaJS(3, 11);
|
|
r.CheckCallViaJS(6, 0x3F);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_CallJS_Add_jswrapped) {
|
|
TestSignatures sigs;
|
|
HandleScope scope(CcTest::InitIsolateOnce());
|
|
const char* source = "(function(a) { return a + 99; })";
|
|
Handle<JSFunction> js_function =
|
|
Handle<JSFunction>::cast(v8::Utils::OpenHandle(
|
|
*v8::Local<v8::Function>::Cast(CompileRun(source))));
|
|
ManuallyImportedJSFunction import = {sigs.i_i(), js_function};
|
|
WasmRunner<int, int> r(execution_tier, &import);
|
|
uint32_t js_index = 0;
|
|
BUILD(r, WASM_CALL_FUNCTION(js_index, WASM_LOCAL_GET(0)));
|
|
|
|
r.CheckCallViaJS(101, 2);
|
|
r.CheckCallViaJS(199, 100);
|
|
r.CheckCallViaJS(-666666801, -666666900);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_IndirectCallJSFunction) {
|
|
Isolate* isolate = CcTest::InitIsolateOnce();
|
|
HandleScope scope(isolate);
|
|
TestSignatures sigs;
|
|
|
|
const char* source = "(function(a, b, c) { if(c) return a; return b; })";
|
|
Handle<JSFunction> js_function =
|
|
Handle<JSFunction>::cast(v8::Utils::OpenHandle(
|
|
*v8::Local<v8::Function>::Cast(CompileRun(source))));
|
|
|
|
ManuallyImportedJSFunction import = {sigs.i_iii(), js_function};
|
|
|
|
WasmRunner<int32_t, int32_t> r(execution_tier, &import);
|
|
|
|
const uint32_t js_index = 0;
|
|
const int32_t left = -2;
|
|
const int32_t right = 3;
|
|
|
|
WasmFunctionCompiler& rc_fn = r.NewFunction(sigs.i_i(), "rc");
|
|
|
|
byte sig_index = r.builder().AddSignature(sigs.i_iii());
|
|
uint16_t indirect_function_table[] = {static_cast<uint16_t>(js_index)};
|
|
|
|
r.builder().AddIndirectFunctionTable(indirect_function_table,
|
|
arraysize(indirect_function_table));
|
|
|
|
BUILD(rc_fn, WASM_CALL_INDIRECT(sig_index, WASM_I32V(left), WASM_I32V(right),
|
|
WASM_LOCAL_GET(0), WASM_I32V(js_index)));
|
|
|
|
Handle<Object> args_left[] = {isolate->factory()->NewNumber(1)};
|
|
r.CheckCallApplyViaJS(left, rc_fn.function_index(), args_left, 1);
|
|
|
|
Handle<Object> args_right[] = {isolate->factory()->NewNumber(0)};
|
|
r.CheckCallApplyViaJS(right, rc_fn.function_index(), args_right, 1);
|
|
}
|
|
|
|
void RunJSSelectTest(TestExecutionTier tier, int which) {
|
|
const int kMaxParams = 8;
|
|
PredictableInputValues inputs(0x100);
|
|
ValueType type = kWasmF64;
|
|
ValueType types[kMaxParams + 1] = {type, type, type, type, type,
|
|
type, type, type, type};
|
|
for (int num_params = which + 1; num_params < kMaxParams; num_params++) {
|
|
HandleScope scope(CcTest::InitIsolateOnce());
|
|
FunctionSig sig(1, num_params, types);
|
|
|
|
ManuallyImportedJSFunction import = CreateJSSelector(&sig, which);
|
|
WasmRunner<void> r(tier, &import);
|
|
uint32_t js_index = 0;
|
|
|
|
WasmFunctionCompiler& t = r.NewFunction(&sig);
|
|
|
|
{
|
|
std::vector<byte> code;
|
|
|
|
for (int i = 0; i < num_params; i++) {
|
|
ADD_CODE(code, WASM_F64(inputs.arg_d(i)));
|
|
}
|
|
|
|
ADD_CODE(code, kExprCallFunction, static_cast<byte>(js_index));
|
|
|
|
size_t end = code.size();
|
|
code.push_back(0);
|
|
t.Build(&code[0], &code[end]);
|
|
}
|
|
|
|
double expected = inputs.arg_d(which);
|
|
r.CheckCallApplyViaJS(expected, t.function_index(), nullptr, 0);
|
|
}
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_JSSelect_0) {
|
|
CcTest::InitializeVM();
|
|
RunJSSelectTest(execution_tier, 0);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_JSSelect_1) {
|
|
CcTest::InitializeVM();
|
|
RunJSSelectTest(execution_tier, 1);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_JSSelect_2) {
|
|
CcTest::InitializeVM();
|
|
RunJSSelectTest(execution_tier, 2);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_JSSelect_3) {
|
|
CcTest::InitializeVM();
|
|
RunJSSelectTest(execution_tier, 3);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_JSSelect_4) {
|
|
CcTest::InitializeVM();
|
|
RunJSSelectTest(execution_tier, 4);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_JSSelect_5) {
|
|
CcTest::InitializeVM();
|
|
RunJSSelectTest(execution_tier, 5);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_JSSelect_6) {
|
|
CcTest::InitializeVM();
|
|
RunJSSelectTest(execution_tier, 6);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_JSSelect_7) {
|
|
CcTest::InitializeVM();
|
|
RunJSSelectTest(execution_tier, 7);
|
|
}
|
|
|
|
void RunWASMSelectTest(TestExecutionTier tier, int which) {
|
|
PredictableInputValues inputs(0x200);
|
|
Isolate* isolate = CcTest::InitIsolateOnce();
|
|
const int kMaxParams = 8;
|
|
for (int num_params = which + 1; num_params < kMaxParams; num_params++) {
|
|
ValueType type = kWasmF64;
|
|
ValueType types[kMaxParams + 1] = {type, type, type, type, type,
|
|
type, type, type, type};
|
|
FunctionSig sig(1, num_params, types);
|
|
|
|
WasmRunner<void> r(tier);
|
|
WasmFunctionCompiler& t = r.NewFunction(&sig);
|
|
BUILD(t, WASM_LOCAL_GET(which));
|
|
|
|
Handle<Object> args[] = {
|
|
isolate->factory()->NewNumber(inputs.arg_d(0)),
|
|
isolate->factory()->NewNumber(inputs.arg_d(1)),
|
|
isolate->factory()->NewNumber(inputs.arg_d(2)),
|
|
isolate->factory()->NewNumber(inputs.arg_d(3)),
|
|
isolate->factory()->NewNumber(inputs.arg_d(4)),
|
|
isolate->factory()->NewNumber(inputs.arg_d(5)),
|
|
isolate->factory()->NewNumber(inputs.arg_d(6)),
|
|
isolate->factory()->NewNumber(inputs.arg_d(7)),
|
|
};
|
|
|
|
double expected = inputs.arg_d(which);
|
|
r.CheckCallApplyViaJS(expected, t.function_index(), args, kMaxParams);
|
|
}
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_0) {
|
|
CcTest::InitializeVM();
|
|
RunWASMSelectTest(execution_tier, 0);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_1) {
|
|
CcTest::InitializeVM();
|
|
RunWASMSelectTest(execution_tier, 1);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_2) {
|
|
CcTest::InitializeVM();
|
|
RunWASMSelectTest(execution_tier, 2);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_3) {
|
|
CcTest::InitializeVM();
|
|
RunWASMSelectTest(execution_tier, 3);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_4) {
|
|
CcTest::InitializeVM();
|
|
RunWASMSelectTest(execution_tier, 4);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_5) {
|
|
CcTest::InitializeVM();
|
|
RunWASMSelectTest(execution_tier, 5);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_6) {
|
|
CcTest::InitializeVM();
|
|
RunWASMSelectTest(execution_tier, 6);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_WASMSelect_7) {
|
|
CcTest::InitializeVM();
|
|
RunWASMSelectTest(execution_tier, 7);
|
|
}
|
|
|
|
void RunWASMSelectAlignTest(TestExecutionTier tier, int num_args,
|
|
int num_params) {
|
|
PredictableInputValues inputs(0x300);
|
|
Isolate* isolate = CcTest::InitIsolateOnce();
|
|
const int kMaxParams = 10;
|
|
DCHECK_LE(num_args, kMaxParams);
|
|
ValueType type = kWasmF64;
|
|
ValueType types[kMaxParams + 1] = {type, type, type, type, type, type,
|
|
type, type, type, type, type};
|
|
FunctionSig sig(1, num_params, types);
|
|
|
|
for (int which = 0; which < num_params; which++) {
|
|
WasmRunner<void> r(tier);
|
|
WasmFunctionCompiler& t = r.NewFunction(&sig);
|
|
BUILD(t, WASM_LOCAL_GET(which));
|
|
|
|
Handle<Object> args[] = {isolate->factory()->NewNumber(inputs.arg_d(0)),
|
|
isolate->factory()->NewNumber(inputs.arg_d(1)),
|
|
isolate->factory()->NewNumber(inputs.arg_d(2)),
|
|
isolate->factory()->NewNumber(inputs.arg_d(3)),
|
|
isolate->factory()->NewNumber(inputs.arg_d(4)),
|
|
isolate->factory()->NewNumber(inputs.arg_d(5)),
|
|
isolate->factory()->NewNumber(inputs.arg_d(6)),
|
|
isolate->factory()->NewNumber(inputs.arg_d(7)),
|
|
isolate->factory()->NewNumber(inputs.arg_d(8)),
|
|
isolate->factory()->NewNumber(inputs.arg_d(9))};
|
|
|
|
double nan = std::numeric_limits<double>::quiet_NaN();
|
|
double expected = which < num_args ? inputs.arg_d(which) : nan;
|
|
r.CheckCallApplyViaJS(expected, t.function_index(), args, num_args);
|
|
}
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_0) {
|
|
CcTest::InitializeVM();
|
|
RunWASMSelectAlignTest(execution_tier, 0, 1);
|
|
RunWASMSelectAlignTest(execution_tier, 0, 2);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_1) {
|
|
CcTest::InitializeVM();
|
|
RunWASMSelectAlignTest(execution_tier, 1, 2);
|
|
RunWASMSelectAlignTest(execution_tier, 1, 3);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_2) {
|
|
CcTest::InitializeVM();
|
|
RunWASMSelectAlignTest(execution_tier, 2, 3);
|
|
RunWASMSelectAlignTest(execution_tier, 2, 4);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_3) {
|
|
CcTest::InitializeVM();
|
|
RunWASMSelectAlignTest(execution_tier, 3, 3);
|
|
RunWASMSelectAlignTest(execution_tier, 3, 4);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_4) {
|
|
CcTest::InitializeVM();
|
|
RunWASMSelectAlignTest(execution_tier, 4, 3);
|
|
RunWASMSelectAlignTest(execution_tier, 4, 4);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_7) {
|
|
CcTest::InitializeVM();
|
|
RunWASMSelectAlignTest(execution_tier, 7, 5);
|
|
RunWASMSelectAlignTest(execution_tier, 7, 6);
|
|
RunWASMSelectAlignTest(execution_tier, 7, 7);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_8) {
|
|
CcTest::InitializeVM();
|
|
RunWASMSelectAlignTest(execution_tier, 8, 5);
|
|
RunWASMSelectAlignTest(execution_tier, 8, 6);
|
|
RunWASMSelectAlignTest(execution_tier, 8, 7);
|
|
RunWASMSelectAlignTest(execution_tier, 8, 8);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_9) {
|
|
CcTest::InitializeVM();
|
|
RunWASMSelectAlignTest(execution_tier, 9, 6);
|
|
RunWASMSelectAlignTest(execution_tier, 9, 7);
|
|
RunWASMSelectAlignTest(execution_tier, 9, 8);
|
|
RunWASMSelectAlignTest(execution_tier, 9, 9);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_WASMSelectAlign_10) {
|
|
CcTest::InitializeVM();
|
|
RunWASMSelectAlignTest(execution_tier, 10, 7);
|
|
RunWASMSelectAlignTest(execution_tier, 10, 8);
|
|
RunWASMSelectAlignTest(execution_tier, 10, 9);
|
|
RunWASMSelectAlignTest(execution_tier, 10, 10);
|
|
}
|
|
|
|
void RunJSSelectAlignTest(TestExecutionTier tier, int num_args,
|
|
int num_params) {
|
|
PredictableInputValues inputs(0x400);
|
|
Isolate* isolate = CcTest::InitIsolateOnce();
|
|
Factory* factory = isolate->factory();
|
|
const int kMaxParams = 10;
|
|
CHECK_LE(num_args, kMaxParams);
|
|
CHECK_LE(num_params, kMaxParams);
|
|
ValueType type = kWasmF64;
|
|
ValueType types[kMaxParams + 1] = {type, type, type, type, type, type,
|
|
type, type, type, type, type};
|
|
FunctionSig sig(1, num_params, types);
|
|
i::AccountingAllocator allocator;
|
|
Zone zone(&allocator, ZONE_NAME);
|
|
|
|
// Build the calling code.
|
|
std::vector<byte> code;
|
|
|
|
for (int i = 0; i < num_params; i++) {
|
|
ADD_CODE(code, WASM_LOCAL_GET(i));
|
|
}
|
|
|
|
uint8_t imported_js_index = 0;
|
|
ADD_CODE(code, kExprCallFunction, imported_js_index);
|
|
|
|
size_t end = code.size();
|
|
code.push_back(0);
|
|
|
|
// Call different select JS functions.
|
|
for (int which = 0; which < num_params; which++) {
|
|
HandleScope scope(isolate);
|
|
ManuallyImportedJSFunction import = CreateJSSelector(&sig, which);
|
|
WasmRunner<void> r(tier, &import);
|
|
WasmFunctionCompiler& t = r.NewFunction(&sig);
|
|
t.Build(&code[0], &code[end]);
|
|
|
|
Handle<Object> args[] = {
|
|
factory->NewNumber(inputs.arg_d(0)),
|
|
factory->NewNumber(inputs.arg_d(1)),
|
|
factory->NewNumber(inputs.arg_d(2)),
|
|
factory->NewNumber(inputs.arg_d(3)),
|
|
factory->NewNumber(inputs.arg_d(4)),
|
|
factory->NewNumber(inputs.arg_d(5)),
|
|
factory->NewNumber(inputs.arg_d(6)),
|
|
factory->NewNumber(inputs.arg_d(7)),
|
|
factory->NewNumber(inputs.arg_d(8)),
|
|
factory->NewNumber(inputs.arg_d(9)),
|
|
};
|
|
|
|
double nan = std::numeric_limits<double>::quiet_NaN();
|
|
double expected = which < num_args ? inputs.arg_d(which) : nan;
|
|
r.CheckCallApplyViaJS(expected, t.function_index(), args, num_args);
|
|
}
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_0) {
|
|
CcTest::InitializeVM();
|
|
RunJSSelectAlignTest(execution_tier, 0, 1);
|
|
RunJSSelectAlignTest(execution_tier, 0, 2);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_1) {
|
|
CcTest::InitializeVM();
|
|
RunJSSelectAlignTest(execution_tier, 1, 2);
|
|
RunJSSelectAlignTest(execution_tier, 1, 3);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_2) {
|
|
CcTest::InitializeVM();
|
|
RunJSSelectAlignTest(execution_tier, 2, 3);
|
|
RunJSSelectAlignTest(execution_tier, 2, 4);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_3) {
|
|
CcTest::InitializeVM();
|
|
RunJSSelectAlignTest(execution_tier, 3, 3);
|
|
RunJSSelectAlignTest(execution_tier, 3, 4);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_4) {
|
|
CcTest::InitializeVM();
|
|
RunJSSelectAlignTest(execution_tier, 4, 3);
|
|
RunJSSelectAlignTest(execution_tier, 4, 4);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_7) {
|
|
CcTest::InitializeVM();
|
|
RunJSSelectAlignTest(execution_tier, 7, 3);
|
|
RunJSSelectAlignTest(execution_tier, 7, 4);
|
|
RunJSSelectAlignTest(execution_tier, 7, 4);
|
|
RunJSSelectAlignTest(execution_tier, 7, 4);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_8) {
|
|
CcTest::InitializeVM();
|
|
RunJSSelectAlignTest(execution_tier, 8, 5);
|
|
RunJSSelectAlignTest(execution_tier, 8, 6);
|
|
RunJSSelectAlignTest(execution_tier, 8, 7);
|
|
RunJSSelectAlignTest(execution_tier, 8, 8);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_9) {
|
|
CcTest::InitializeVM();
|
|
RunJSSelectAlignTest(execution_tier, 9, 6);
|
|
RunJSSelectAlignTest(execution_tier, 9, 7);
|
|
RunJSSelectAlignTest(execution_tier, 9, 8);
|
|
RunJSSelectAlignTest(execution_tier, 9, 9);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_JSSelectAlign_10) {
|
|
CcTest::InitializeVM();
|
|
RunJSSelectAlignTest(execution_tier, 10, 7);
|
|
RunJSSelectAlignTest(execution_tier, 10, 8);
|
|
RunJSSelectAlignTest(execution_tier, 10, 9);
|
|
RunJSSelectAlignTest(execution_tier, 10, 10);
|
|
}
|
|
|
|
// Set up a test with an import, so we can return call it.
|
|
// Create a javascript function that returns left or right arguments
|
|
// depending on the value of the third argument
|
|
// function (a,b,c){ if(c)return a; return b; }
|
|
|
|
void RunPickerTest(TestExecutionTier tier, bool indirect) {
|
|
EXPERIMENTAL_FLAG_SCOPE(return_call);
|
|
Isolate* isolate = CcTest::InitIsolateOnce();
|
|
HandleScope scope(isolate);
|
|
TestSignatures sigs;
|
|
|
|
const char* source = "(function(a,b,c) { if(c)return a; return b; })";
|
|
Handle<JSFunction> js_function =
|
|
Handle<JSFunction>::cast(v8::Utils::OpenHandle(
|
|
*v8::Local<v8::Function>::Cast(CompileRun(source))));
|
|
|
|
ManuallyImportedJSFunction import = {sigs.i_iii(), js_function};
|
|
|
|
WasmRunner<int32_t, int32_t> r(tier, &import);
|
|
|
|
const uint32_t js_index = 0;
|
|
const int32_t left = -2;
|
|
const int32_t right = 3;
|
|
|
|
WasmFunctionCompiler& rc_fn = r.NewFunction(sigs.i_i(), "rc");
|
|
|
|
if (indirect) {
|
|
byte sig_index = r.builder().AddSignature(sigs.i_iii());
|
|
uint16_t indirect_function_table[] = {static_cast<uint16_t>(js_index)};
|
|
|
|
r.builder().AddIndirectFunctionTable(indirect_function_table,
|
|
arraysize(indirect_function_table));
|
|
|
|
BUILD(rc_fn, WASM_RETURN_CALL_INDIRECT(sig_index, WASM_I32V(left),
|
|
WASM_I32V(right), WASM_LOCAL_GET(0),
|
|
WASM_I32V(js_index)));
|
|
} else {
|
|
BUILD(rc_fn,
|
|
WASM_RETURN_CALL_FUNCTION(js_index, WASM_I32V(left), WASM_I32V(right),
|
|
WASM_LOCAL_GET(0)));
|
|
}
|
|
|
|
Handle<Object> args_left[] = {isolate->factory()->NewNumber(1)};
|
|
r.CheckCallApplyViaJS(left, rc_fn.function_index(), args_left, 1);
|
|
|
|
Handle<Object> args_right[] = {isolate->factory()->NewNumber(0)};
|
|
r.CheckCallApplyViaJS(right, rc_fn.function_index(), args_right, 1);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_ReturnCallImportedFunction) {
|
|
RunPickerTest(execution_tier, false);
|
|
}
|
|
|
|
WASM_COMPILED_EXEC_TEST(Run_ReturnCallIndirectImportedFunction) {
|
|
RunPickerTest(execution_tier, true);
|
|
}
|
|
|
|
#undef ADD_CODE
|
|
|
|
} // namespace wasm
|
|
} // namespace internal
|
|
} // namespace v8
|