Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(376)

Unified Diff: test/cctest/wasm/test-run-wasm-js.cc

Issue 1603533002: [wasm] Add more thorough tests for WASM->JS and JS->WASM parameters. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: signedness Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/linkage.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/wasm/test-run-wasm-js.cc
diff --git a/test/cctest/wasm/test-run-wasm-js.cc b/test/cctest/wasm/test-run-wasm-js.cc
index 6fcde645cb43e25127e746f1d984453f4fe0c55e..bafeb25e3bf89865399b7d3e1703c16af4118503 100644
--- a/test/cctest/wasm/test-run-wasm-js.cc
+++ b/test/cctest/wasm/test-run-wasm-js.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include <stdint.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -24,8 +25,31 @@ using namespace v8::internal::wasm;
} while (false)
-static uint32_t AddJsFunction(TestingModule* module, FunctionSig* sig,
- const char* source) {
+#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));
+ }
+};
+
+
+uint32_t AddJsFunction(TestingModule* module, FunctionSig* sig,
+ const char* source) {
Handle<JSFunction> jsfunc = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
*v8::Local<v8::Function>::Cast(CompileRun(source))));
module->AddFunction(sig, Handle<Code>::null());
@@ -37,7 +61,25 @@ static uint32_t AddJsFunction(TestingModule* module, FunctionSig* sig,
}
-static Handle<JSFunction> WrapCode(ModuleEnv* module, uint32_t index) {
+uint32_t AddJSSelector(TestingModule* module, FunctionSig* sig, int which) {
+ const int kMaxParams = 8;
+ 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",
+ };
+ 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);
+
+ return AddJsFunction(module, sig, source.start());
+}
+
+
+Handle<JSFunction> WrapCode(ModuleEnv* module, uint32_t index) {
Isolate* isolate = module->module->shared_isolate;
// Wrap the code so it can be called as a JS function.
Handle<String> name = isolate->factory()->NewStringFromStaticChars("main");
@@ -49,14 +91,12 @@ static Handle<JSFunction> WrapCode(ModuleEnv* module, uint32_t index) {
}
-static void EXPECT_CALL(double expected, Handle<JSFunction> jsfunc, double a,
- double b) {
+void EXPECT_CALL(double expected, Handle<JSFunction> jsfunc,
+ Handle<Object>* buffer, int count) {
Isolate* isolate = jsfunc->GetIsolate();
- Handle<Object> buffer[] = {isolate->factory()->NewNumber(a),
- isolate->factory()->NewNumber(b)};
Handle<Object> global(isolate->context()->global_object(), isolate);
MaybeHandle<Object> retval =
- Execution::Call(isolate, jsfunc, global, 2, buffer);
+ Execution::Call(isolate, jsfunc, global, count, buffer);
CHECK(!retval.is_null());
Handle<Object> result = retval.ToHandleChecked();
@@ -64,11 +104,20 @@ static void EXPECT_CALL(double expected, Handle<JSFunction> jsfunc, double a,
CHECK_EQ(expected, Smi::cast(*result)->value());
} else {
CHECK(result->IsHeapNumber());
- CHECK_EQ(expected, HeapNumber::cast(*result)->value());
+ CheckFloatEq(expected, HeapNumber::cast(*result)->value());
}
}
+void EXPECT_CALL(double expected, Handle<JSFunction> jsfunc, double a,
+ double b) {
+ Isolate* isolate = jsfunc->GetIsolate();
+ Handle<Object> buffer[] = {isolate->factory()->NewNumber(a),
+ isolate->factory()->NewNumber(b)};
+ EXPECT_CALL(expected, jsfunc, buffer, 2);
+}
+} // namespace
+
TEST(Run_Int32Sub_jswrapped) {
TestSignatures sigs;
TestingModule module;
@@ -121,8 +170,7 @@ TEST(Run_I32Popcount_jswrapped) {
#if !V8_TARGET_ARCH_ARM64
-// TODO(titzer): fix wasm->JS calls on arm64 (wrapper issues)
-
+// TODO(titzer): dynamic frame alignment on arm64
TEST(Run_CallJS_Add_jswrapped) {
TestSignatures sigs;
TestingModule module;
@@ -137,5 +185,243 @@ TEST(Run_CallJS_Add_jswrapped) {
EXPECT_CALL(199, jsfunc, 100, -1);
EXPECT_CALL(-666666801, jsfunc, -666666900, -1);
}
+#endif
+
+
+void RunJSSelectTest(int which) {
+ const int kMaxParams = 8;
+ PredictableInputValues inputs(0x100);
+ LocalType type = kAstF64;
+ LocalType 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);
+
+ TestingModule module;
+ uint32_t js_index = AddJSSelector(&module, &sig, which);
+ WasmFunctionCompiler t(&sig, &module);
+
+ {
+ std::vector<byte> code;
+ ADD_CODE(code, kExprCallFunction, static_cast<byte>(js_index));
+
+ for (int i = 0; i < num_params; i++) {
+ ADD_CODE(code, WASM_F64(inputs.arg_d(i)));
+ }
+
+ size_t end = code.size();
+ code.push_back(0);
+ t.Build(&code[0], &code[end]);
+ }
+
+ Handle<JSFunction> jsfunc = WrapCode(&module, t.CompileAndAdd(&module));
+ double expected = inputs.arg_d(which);
+ EXPECT_CALL(expected, jsfunc, 0.0, 0.0);
+ }
+}
+
+
+TEST(Run_JSSelect_0) { RunJSSelectTest(0); }
+
+TEST(Run_JSSelect_1) { RunJSSelectTest(1); }
+
+TEST(Run_JSSelect_2) { RunJSSelectTest(2); }
+
+TEST(Run_JSSelect_3) { RunJSSelectTest(3); }
+
+TEST(Run_JSSelect_4) { RunJSSelectTest(4); }
+
+TEST(Run_JSSelect_5) { RunJSSelectTest(5); }
+
+TEST(Run_JSSelect_6) { RunJSSelectTest(6); }
+
+TEST(Run_JSSelect_7) { RunJSSelectTest(7); }
+
+
+void RunWASMSelectTest(int which) {
+ PredictableInputValues inputs(0x200);
+ Isolate* isolate = CcTest::InitIsolateOnce();
+ const int kMaxParams = 8;
+ for (int num_params = which + 1; num_params < kMaxParams; num_params++) {
+ LocalType type = kAstF64;
+ LocalType types[kMaxParams + 1] = {type, type, type, type, type,
+ type, type, type, type};
+ FunctionSig sig(1, num_params, types);
+
+ TestingModule module;
+ WasmFunctionCompiler t(&sig, &module);
+ BUILD(t, WASM_GET_LOCAL(which));
+ Handle<JSFunction> jsfunc = WrapCode(&module, t.CompileAndAdd(&module));
+
+ 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);
+ EXPECT_CALL(expected, jsfunc, args, kMaxParams);
+ }
+}
+
+
+TEST(Run_WASMSelect_0) { RunWASMSelectTest(0); }
+
+TEST(Run_WASMSelect_1) { RunWASMSelectTest(1); }
+
+TEST(Run_WASMSelect_2) { RunWASMSelectTest(2); }
+
+TEST(Run_WASMSelect_3) { RunWASMSelectTest(3); }
+
+TEST(Run_WASMSelect_4) { RunWASMSelectTest(4); }
+
+TEST(Run_WASMSelect_5) { RunWASMSelectTest(5); }
+
+TEST(Run_WASMSelect_6) { RunWASMSelectTest(6); }
+
+TEST(Run_WASMSelect_7) { RunWASMSelectTest(7); }
+
+
+void RunWASMSelectAlignTest(int num_args, int num_params) {
+ PredictableInputValues inputs(0x300);
+ Isolate* isolate = CcTest::InitIsolateOnce();
+ const int kMaxParams = 4;
+ DCHECK_LE(num_args, kMaxParams);
+ LocalType type = kAstF64;
+ LocalType types[kMaxParams + 1] = {type, type, type, type, type};
+ FunctionSig sig(1, num_params, types);
+
+ for (int which = 0; which < num_params; which++) {
+ TestingModule module;
+ WasmFunctionCompiler t(&sig, &module);
+ BUILD(t, WASM_GET_LOCAL(which));
+ Handle<JSFunction> jsfunc = WrapCode(&module, t.CompileAndAdd(&module));
+
+ 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)),
+ };
+
+ double nan = std::numeric_limits<double>::quiet_NaN();
+ double expected = which < num_args ? inputs.arg_d(which) : nan;
+ EXPECT_CALL(expected, jsfunc, args, num_args);
+ }
+}
+
+
+TEST(Run_WASMSelectAlign_0) {
+ RunWASMSelectAlignTest(0, 1);
+ RunWASMSelectAlignTest(0, 2);
+}
+
+TEST(Run_WASMSelectAlign_1) {
+ RunWASMSelectAlignTest(1, 2);
+ RunWASMSelectAlignTest(1, 3);
+}
+
+
+TEST(Run_WASMSelectAlign_2) {
+ RunWASMSelectAlignTest(2, 3);
+ RunWASMSelectAlignTest(2, 4);
+}
+
+
+TEST(Run_WASMSelectAlign_3) {
+ RunWASMSelectAlignTest(3, 3);
+ RunWASMSelectAlignTest(3, 4);
+}
+
+
+TEST(Run_WASMSelectAlign_4) {
+ RunWASMSelectAlignTest(4, 3);
+ RunWASMSelectAlignTest(4, 4);
+}
+
+
+void RunJSSelectAlignTest(int num_args, int num_params) {
+ PredictableInputValues inputs(0x400);
+ Isolate* isolate = CcTest::InitIsolateOnce();
+ Factory* factory = isolate->factory();
+ const int kMaxParams = 4;
+ CHECK_LE(num_args, kMaxParams);
+ CHECK_LE(num_params, kMaxParams);
+ LocalType type = kAstF64;
+ LocalType types[kMaxParams + 1] = {type, type, type, type, type};
+ FunctionSig sig(1, num_params, types);
+
+ // Build the calling code.
+ std::vector<byte> code;
+ ADD_CODE(code, kExprCallFunction, 0);
+
+ for (int i = 0; i < num_params; i++) {
+ ADD_CODE(code, WASM_GET_LOCAL(i));
+ }
+
+ 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);
+ TestingModule module;
+ uint32_t js_index = AddJSSelector(&module, &sig, which);
+ CHECK_EQ(0, js_index);
+ WasmFunctionCompiler t(&sig, &module);
+ t.Build(&code[0], &code[end]);
+
+ Handle<JSFunction> jsfunc = WrapCode(&module, t.CompileAndAdd(&module));
+
+ 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)),
+ };
+
+ double nan = std::numeric_limits<double>::quiet_NaN();
+ double expected = which < num_args ? inputs.arg_d(which) : nan;
+ EXPECT_CALL(expected, jsfunc, args, num_args);
+ }
+}
+
+
+TEST(Run_JSSelectAlign_0) {
+ RunJSSelectAlignTest(0, 1);
+ RunJSSelectAlignTest(0, 2);
+}
+
+
+TEST(Run_JSSelectAlign_2) {
+ RunJSSelectAlignTest(2, 3);
+ RunJSSelectAlignTest(2, 4);
+}
+
+
+TEST(Run_JSSelectAlign_4) {
+ RunJSSelectAlignTest(4, 3);
+ RunJSSelectAlignTest(4, 4);
+}
+
+
+#if !V8_TARGET_ARCH_ARM64
+// TODO(titzer): dynamic frame alignment on arm64
+TEST(Run_JSSelectAlign_1) {
+ RunJSSelectAlignTest(1, 2);
+ RunJSSelectAlignTest(1, 3);
+}
+
+
+TEST(Run_JSSelectAlign_3) {
+ RunJSSelectAlignTest(3, 3);
+ RunJSSelectAlignTest(3, 4);
+}
#endif
« no previous file with comments | « src/compiler/linkage.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698