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

Side by Side Diff: test/cctest/wasm/test-wasm-interpreter-entry.cc

Issue 2651793003: [wasm] Test argument passing in the interpreter entry (Closed)
Patch Set: Naming Created 3 years, 10 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 unified diff | Download patch
« no previous file with comments | « test/cctest/cctest.gyp ('k') | test/cctest/wasm/wasm-run-utils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 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 <cstdint>
6
7 #include "src/wasm/wasm-macro-gen.h"
8 #include "src/wasm/wasm-objects.h"
9
10 #include "test/cctest/cctest.h"
11 #include "test/cctest/compiler/value-helper.h"
12 #include "test/cctest/wasm/wasm-run-utils.h"
13
14 using namespace v8::internal;
15 using namespace v8::internal::wasm;
16 namespace debug = v8::debug;
17
18 /**
19 * We test the interface from Wasm compiled code to the Wasm interpreter by
20 * building a module with two functions. The external function is called from
21 * this test, and will be compiled code. It takes its arguments and passes them
22 * on to the internal function, which will be redirected to the interpreter.
23 * If the internal function has an i64 parameter, is has to be replaced by two
24 * i32 parameters on the external function.
25 * The internal function just converts all its arguments to f64, sums them up
26 * and returns the sum.
27 */
28 namespace {
29
30 template <typename T>
31 class ArgPassingHelper {
32 public:
33 ArgPassingHelper(WasmRunnerBase& runner, WasmFunctionCompiler& inner_compiler,
34 std::initializer_list<uint8_t> bytes_inner_function,
35 std::initializer_list<uint8_t> bytes_outer_function,
36 const T& expected_lambda)
37 : isolate_(runner.main_isolate()),
38 expected_lambda_(expected_lambda),
39 debug_info_(WasmInstanceObject::GetOrCreateDebugInfo(
40 runner.module().instance_object())) {
41 std::vector<uint8_t> inner_code{bytes_inner_function};
42 inner_compiler.Build(inner_code.data(),
43 inner_code.data() + inner_code.size());
44
45 std::vector<uint8_t> outer_code{bytes_outer_function};
46 runner.Build(outer_code.data(), outer_code.data() + outer_code.size());
47
48 WasmDebugInfo::RedirectToInterpreter(debug_info_,
49 inner_compiler.function_index());
50 main_fun_wrapper_ = runner.module().WrapCode(runner.function_index());
51 }
52
53 template <typename... Args>
54 void CheckCall(Args... args) {
55 Handle<Object> arg_objs[] = {isolate_->factory()->NewNumber(args)...};
56
57 uint64_t num_interpreted_before = debug_info_->NumInterpretedCalls();
58 Handle<Object> global(isolate_->context()->global_object(), isolate_);
59 MaybeHandle<Object> retval = Execution::Call(
60 isolate_, main_fun_wrapper_, global, arraysize(arg_objs), arg_objs);
61 uint64_t num_interpreted_after = debug_info_->NumInterpretedCalls();
62 // Check that we really went through the interpreter.
63 CHECK_EQ(num_interpreted_before + 1, num_interpreted_after);
64 // Check the result.
65 double result = retval.ToHandleChecked()->Number();
66 double expected = expected_lambda_(args...);
67 CHECK_DOUBLE_EQ(expected, result);
68 }
69
70 private:
71 Isolate* isolate_;
72 T expected_lambda_;
73 Handle<WasmDebugInfo> debug_info_;
74 Handle<JSFunction> main_fun_wrapper_;
75 };
76
77 template <typename T>
78 static ArgPassingHelper<T> GetHelper(
79 WasmRunnerBase& runner, WasmFunctionCompiler& inner_compiler,
80 std::initializer_list<uint8_t> bytes_inner_function,
81 std::initializer_list<uint8_t> bytes_outer_function,
82 const T& expected_lambda) {
83 return ArgPassingHelper<T>(runner, inner_compiler, bytes_inner_function,
84 bytes_outer_function, expected_lambda);
85 }
86
87 } // namespace
88
89 TEST(TestArgumentPassing_int32) {
90 WasmRunner<int32_t, int32_t> runner(kExecuteCompiled);
91 WasmFunctionCompiler& f2 = runner.NewFunction<int32_t, int32_t>();
92
93 auto helper = GetHelper(
94 runner, f2,
95 {// Return 2*<0> + 1.
96 WASM_I32_ADD(WASM_I32_MUL(WASM_I32V_1(2), WASM_GET_LOCAL(0)), WASM_ONE)},
97 {// Call f2 with param <0>.
98 WASM_GET_LOCAL(0), WASM_CALL_FUNCTION0(f2.function_index())},
99 [](int32_t a) { return 2 * a + 1; });
100
101 std::vector<int32_t> test_values = compiler::ValueHelper::int32_vector();
102 for (int32_t v : test_values) helper.CheckCall(v);
103 }
104
105 TEST(TestArgumentPassing_int64) {
106 WasmRunner<double, int32_t, int32_t> runner(kExecuteCompiled);
107 WasmFunctionCompiler& f2 = runner.NewFunction<double, int64_t>();
108
109 auto helper = GetHelper(
110 runner, f2,
111 {// Return (double)<0>.
112 WASM_F64_SCONVERT_I64(WASM_GET_LOCAL(0))},
113 {// Call f2 with param (<0> | (<1> << 32)).
114 WASM_I64_IOR(WASM_I64_UCONVERT_I32(WASM_GET_LOCAL(0)),
115 WASM_I64_SHL(WASM_I64_UCONVERT_I32(WASM_GET_LOCAL(1)),
116 WASM_I64V_1(32))),
117 WASM_CALL_FUNCTION0(f2.function_index())},
118 [](int32_t a, int32_t b) {
119 int64_t a64 = static_cast<int64_t>(a) & 0xffffffff;
120 int64_t b64 = static_cast<int64_t>(b) << 32;
121 return static_cast<double>(a64 | b64);
122 });
123
124 std::vector<int32_t> test_values_i32 = compiler::ValueHelper::int32_vector();
125 for (int32_t v1 : test_values_i32) {
126 for (int32_t v2 : test_values_i32) {
127 helper.CheckCall(v1, v2);
128 }
129 }
130
131 std::vector<int64_t> test_values_i64 = compiler::ValueHelper::int64_vector();
132 for (int64_t v : test_values_i64) {
133 int32_t v1 = static_cast<int32_t>(v);
134 int32_t v2 = static_cast<int32_t>(v >> 32);
135 helper.CheckCall(v1, v2);
136 helper.CheckCall(v2, v1);
137 }
138 }
139
140 TEST(TestArgumentPassing_float_double) {
141 WasmRunner<double, float> runner(kExecuteCompiled);
142 WasmFunctionCompiler& f2 = runner.NewFunction<double, float>();
143
144 auto helper = GetHelper(
145 runner, f2,
146 {// Return 2*(double)<0> + 1.
147 WASM_F64_ADD(
148 WASM_F64_MUL(WASM_F64(2), WASM_F64_CONVERT_F32(WASM_GET_LOCAL(0))),
149 WASM_F64(1))},
150 {// Call f2 with param <0>.
151 WASM_GET_LOCAL(0), WASM_CALL_FUNCTION0(f2.function_index())},
152 [](float f) { return 2. * static_cast<double>(f) + 1.; });
153
154 std::vector<float> test_values = compiler::ValueHelper::float32_vector();
155 for (float f : test_values) helper.CheckCall(f);
156 }
157
158 TEST(TestArgumentPassing_double_double) {
159 WasmRunner<double, double, double> runner(kExecuteCompiled);
160 WasmFunctionCompiler& f2 = runner.NewFunction<double, double, double>();
161
162 auto helper = GetHelper(runner, f2,
163 {// Return <0> + <1>.
164 WASM_F64_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))},
165 {// Call f2 with params <0>, <1>.
166 WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
167 WASM_CALL_FUNCTION0(f2.function_index())},
168 [](double a, double b) { return a + b; });
169
170 std::vector<double> test_values = compiler::ValueHelper::float64_vector();
171 for (double d1 : test_values) {
172 for (double d2 : test_values) {
173 helper.CheckCall(d1, d2);
174 }
175 }
176 }
177
178 TEST(TestArgumentPassing_AllTypes) {
179 // The second and third argument will be combined to an i64.
180 WasmRunner<double, int, int, int, float, double> runner(kExecuteCompiled);
181 WasmFunctionCompiler& f2 =
182 runner.NewFunction<double, int, int64_t, float, double>();
183
184 auto helper = GetHelper(
185 runner, f2,
186 {
187 // Convert all arguments to double, add them and return the sum.
188 WASM_F64_ADD( // <0+1+2> + <3>
189 WASM_F64_ADD( // <0+1> + <2>
190 WASM_F64_ADD( // <0> + <1>
191 WASM_F64_SCONVERT_I32(
192 WASM_GET_LOCAL(0)), // <0> to double
193 WASM_F64_SCONVERT_I64(
194 WASM_GET_LOCAL(1))), // <1> to double
195 WASM_F64_CONVERT_F32(WASM_GET_LOCAL(2))), // <2> to double
196 WASM_GET_LOCAL(3)) // <3>
197 },
198 {WASM_GET_LOCAL(0), // first arg
199 WASM_I64_IOR(WASM_I64_UCONVERT_I32(WASM_GET_LOCAL(1)), // second arg
200 WASM_I64_SHL(WASM_I64_UCONVERT_I32(WASM_GET_LOCAL(2)),
201 WASM_I64V_1(32))),
202 WASM_GET_LOCAL(3), // third arg
203 WASM_GET_LOCAL(4), // fourth arg
204 WASM_CALL_FUNCTION0(f2.function_index())},
205 [](int32_t a, int32_t b, int32_t c, float d, double e) {
206 return 0. + a + (static_cast<int64_t>(b) & 0xffffffff) +
207 ((static_cast<int64_t>(c) & 0xffffffff) << 32) + d + e;
208 });
209
210 auto CheckCall = [&](int32_t a, int64_t b, float c, double d) {
211 int32_t b0 = static_cast<int32_t>(b);
212 int32_t b1 = static_cast<int32_t>(b >> 32);
213 helper.CheckCall(a, b0, b1, c, d);
214 helper.CheckCall(a, b1, b0, c, d);
215 };
216
217 std::vector<int32_t> test_values_i32 = compiler::ValueHelper::int32_vector();
218 std::vector<int64_t> test_values_i64 = compiler::ValueHelper::int64_vector();
219 std::vector<float> test_values_f32 = compiler::ValueHelper::float32_vector();
220 std::vector<double> test_values_f64 = compiler::ValueHelper::float64_vector();
221 size_t max_len =
222 std::max(std::max(test_values_i32.size(), test_values_i64.size()),
223 std::max(test_values_f32.size(), test_values_f64.size()));
224 for (size_t i = 0; i < max_len; ++i) {
225 int32_t i32 = test_values_i32[i % test_values_i32.size()];
226 int64_t i64 = test_values_i64[i % test_values_i64.size()];
227 float f32 = test_values_f32[i % test_values_f32.size()];
228 double f64 = test_values_f64[i % test_values_f64.size()];
229 CheckCall(i32, i64, f32, f64);
230 }
231 }
OLDNEW
« no previous file with comments | « test/cctest/cctest.gyp ('k') | test/cctest/wasm/wasm-run-utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698