OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdint.h> | 5 #include <stdint.h> |
6 #include <stdio.h> | 6 #include <stdio.h> |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 #include <string.h> | 8 #include <string.h> |
9 | 9 |
10 #include "src/wasm/wasm-macro-gen.h" | 10 #include "src/wasm/wasm-macro-gen.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 explicit PredictableInputValues(int base) : base_(base) {} | 42 explicit PredictableInputValues(int base) : base_(base) {} |
43 double arg_d(int which) { return base_ * which + ((which & 1) * 0.5); } | 43 double arg_d(int which) { return base_ * which + ((which & 1) * 0.5); } |
44 float arg_f(int which) { return base_ * which + ((which & 1) * 0.25); } | 44 float arg_f(int which) { return base_ * which + ((which & 1) * 0.25); } |
45 int32_t arg_i(int which) { return base_ * which + ((which & 1) * kMinInt); } | 45 int32_t arg_i(int which) { return base_ * which + ((which & 1) * kMinInt); } |
46 int64_t arg_l(int which) { | 46 int64_t arg_l(int which) { |
47 return base_ * which + ((which & 1) * (0x04030201LL << 32)); | 47 return base_ * which + ((which & 1) * (0x04030201LL << 32)); |
48 } | 48 } |
49 }; | 49 }; |
50 | 50 |
51 | 51 |
52 uint32_t AddJsFunction(TestingModule* module, FunctionSig* sig, | |
53 const char* source) { | |
54 Handle<JSFunction> jsfunc = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | |
55 *v8::Local<v8::Function>::Cast(CompileRun(source)))); | |
56 module->AddFunction(sig, Handle<Code>::null()); | |
57 uint32_t index = static_cast<uint32_t>(module->module->functions.size() - 1); | |
58 Isolate* isolate = CcTest::InitIsolateOnce(); | |
59 WasmName module_name = {"test", 4}; | |
60 WasmName function_name = {nullptr, 0}; | |
61 Handle<Code> code = CompileWasmToJSWrapper(isolate, module, jsfunc, sig, | |
62 module_name, function_name); | |
63 module->instance->function_code[index] = code; | |
64 return index; | |
65 } | |
66 | |
67 | |
68 uint32_t AddJSSelector(TestingModule* module, FunctionSig* sig, int which) { | 52 uint32_t AddJSSelector(TestingModule* module, FunctionSig* sig, int which) { |
69 const int kMaxParams = 11; | 53 const int kMaxParams = 11; |
70 static const char* formals[kMaxParams] = {"", | 54 static const char* formals[kMaxParams] = {"", |
71 "a", | 55 "a", |
72 "a,b", | 56 "a,b", |
73 "a,b,c", | 57 "a,b,c", |
74 "a,b,c,d", | 58 "a,b,c,d", |
75 "a,b,c,d,e", | 59 "a,b,c,d,e", |
76 "a,b,c,d,e,f", | 60 "a,b,c,d,e,f", |
77 "a,b,c,d,e,f,g", | 61 "a,b,c,d,e,f,g", |
78 "a,b,c,d,e,f,g,h", | 62 "a,b,c,d,e,f,g,h", |
79 "a,b,c,d,e,f,g,h,i", | 63 "a,b,c,d,e,f,g,h,i", |
80 "a,b,c,d,e,f,g,h,i,j"}; | 64 "a,b,c,d,e,f,g,h,i,j"}; |
81 CHECK_LT(which, static_cast<int>(sig->parameter_count())); | 65 CHECK_LT(which, static_cast<int>(sig->parameter_count())); |
82 CHECK_LT(static_cast<int>(sig->parameter_count()), kMaxParams); | 66 CHECK_LT(static_cast<int>(sig->parameter_count()), kMaxParams); |
83 | 67 |
84 i::EmbeddedVector<char, 256> source; | 68 i::EmbeddedVector<char, 256> source; |
85 char param = 'a' + which; | 69 char param = 'a' + which; |
86 SNPrintF(source, "(function(%s) { return %c; })", | 70 SNPrintF(source, "(function(%s) { return %c; })", |
87 formals[sig->parameter_count()], param); | 71 formals[sig->parameter_count()], param); |
88 | 72 |
89 return AddJsFunction(module, sig, source.start()); | 73 return module->AddJsFunction(sig, source.start()); |
90 } | 74 } |
91 | 75 |
92 | 76 |
93 Handle<JSFunction> WrapCode(ModuleEnv* module, uint32_t index) { | |
94 Isolate* isolate = module->module->shared_isolate; | |
95 // Wrap the code so it can be called as a JS function. | |
96 Handle<String> name = isolate->factory()->NewStringFromStaticChars("main"); | |
97 Handle<JSObject> module_object = Handle<JSObject>(0, isolate); | |
98 Handle<Code> code = module->instance->function_code[index]; | |
99 WasmJs::InstallWasmFunctionMap(isolate, isolate->native_context()); | |
100 return compiler::CompileJSToWasmWrapper(isolate, module, name, code, | |
101 module_object, index); | |
102 } | |
103 | |
104 | |
105 void EXPECT_CALL(double expected, Handle<JSFunction> jsfunc, | 77 void EXPECT_CALL(double expected, Handle<JSFunction> jsfunc, |
106 Handle<Object>* buffer, int count) { | 78 Handle<Object>* buffer, int count) { |
107 Isolate* isolate = jsfunc->GetIsolate(); | 79 Isolate* isolate = jsfunc->GetIsolate(); |
108 Handle<Object> global(isolate->context()->global_object(), isolate); | 80 Handle<Object> global(isolate->context()->global_object(), isolate); |
109 MaybeHandle<Object> retval = | 81 MaybeHandle<Object> retval = |
110 Execution::Call(isolate, jsfunc, global, count, buffer); | 82 Execution::Call(isolate, jsfunc, global, count, buffer); |
111 | 83 |
112 CHECK(!retval.is_null()); | 84 CHECK(!retval.is_null()); |
113 Handle<Object> result = retval.ToHandleChecked(); | 85 Handle<Object> result = retval.ToHandleChecked(); |
114 if (result->IsSmi()) { | 86 if (result->IsSmi()) { |
(...skipping 12 matching lines...) Expand all Loading... |
127 isolate->factory()->NewNumber(b)}; | 99 isolate->factory()->NewNumber(b)}; |
128 EXPECT_CALL(expected, jsfunc, buffer, 2); | 100 EXPECT_CALL(expected, jsfunc, buffer, 2); |
129 } | 101 } |
130 } // namespace | 102 } // namespace |
131 | 103 |
132 TEST(Run_Int32Sub_jswrapped) { | 104 TEST(Run_Int32Sub_jswrapped) { |
133 TestSignatures sigs; | 105 TestSignatures sigs; |
134 TestingModule module; | 106 TestingModule module; |
135 WasmFunctionCompiler t(sigs.i_ii(), &module); | 107 WasmFunctionCompiler t(sigs.i_ii(), &module); |
136 BUILD(t, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 108 BUILD(t, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
137 Handle<JSFunction> jsfunc = WrapCode(&module, t.CompileAndAdd()); | 109 Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd()); |
138 | 110 |
139 EXPECT_CALL(33, jsfunc, 44, 11); | 111 EXPECT_CALL(33, jsfunc, 44, 11); |
140 EXPECT_CALL(-8723487, jsfunc, -8000000, 723487); | 112 EXPECT_CALL(-8723487, jsfunc, -8000000, 723487); |
141 } | 113 } |
142 | 114 |
143 | 115 |
144 TEST(Run_Float32Div_jswrapped) { | 116 TEST(Run_Float32Div_jswrapped) { |
145 TestSignatures sigs; | 117 TestSignatures sigs; |
146 TestingModule module; | 118 TestingModule module; |
147 WasmFunctionCompiler t(sigs.f_ff(), &module); | 119 WasmFunctionCompiler t(sigs.f_ff(), &module); |
148 BUILD(t, WASM_F32_DIV(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 120 BUILD(t, WASM_F32_DIV(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
149 Handle<JSFunction> jsfunc = WrapCode(&module, t.CompileAndAdd()); | 121 Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd()); |
150 | 122 |
151 EXPECT_CALL(92, jsfunc, 46, 0.5); | 123 EXPECT_CALL(92, jsfunc, 46, 0.5); |
152 EXPECT_CALL(64, jsfunc, -16, -0.25); | 124 EXPECT_CALL(64, jsfunc, -16, -0.25); |
153 } | 125 } |
154 | 126 |
155 | 127 |
156 TEST(Run_Float64Add_jswrapped) { | 128 TEST(Run_Float64Add_jswrapped) { |
157 TestSignatures sigs; | 129 TestSignatures sigs; |
158 TestingModule module; | 130 TestingModule module; |
159 WasmFunctionCompiler t(sigs.d_dd(), &module); | 131 WasmFunctionCompiler t(sigs.d_dd(), &module); |
160 BUILD(t, WASM_F64_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 132 BUILD(t, WASM_F64_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
161 Handle<JSFunction> jsfunc = WrapCode(&module, t.CompileAndAdd()); | 133 Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd()); |
162 | 134 |
163 EXPECT_CALL(3, jsfunc, 2, 1); | 135 EXPECT_CALL(3, jsfunc, 2, 1); |
164 EXPECT_CALL(-5.5, jsfunc, -5.25, -0.25); | 136 EXPECT_CALL(-5.5, jsfunc, -5.25, -0.25); |
165 } | 137 } |
166 | 138 |
167 | 139 |
168 TEST(Run_I32Popcount_jswrapped) { | 140 TEST(Run_I32Popcount_jswrapped) { |
169 TestSignatures sigs; | 141 TestSignatures sigs; |
170 TestingModule module; | 142 TestingModule module; |
171 WasmFunctionCompiler t(sigs.i_i(), &module); | 143 WasmFunctionCompiler t(sigs.i_i(), &module); |
172 BUILD(t, WASM_I32_POPCNT(WASM_GET_LOCAL(0))); | 144 BUILD(t, WASM_I32_POPCNT(WASM_GET_LOCAL(0))); |
173 Handle<JSFunction> jsfunc = WrapCode(&module, t.CompileAndAdd()); | 145 Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd()); |
174 | 146 |
175 EXPECT_CALL(2, jsfunc, 9, 0); | 147 EXPECT_CALL(2, jsfunc, 9, 0); |
176 EXPECT_CALL(3, jsfunc, 11, 0); | 148 EXPECT_CALL(3, jsfunc, 11, 0); |
177 EXPECT_CALL(6, jsfunc, 0x3F, 0); | 149 EXPECT_CALL(6, jsfunc, 0x3F, 0); |
178 | |
179 USE(AddJsFunction); | |
180 } | 150 } |
181 | 151 |
182 | 152 |
183 TEST(Run_CallJS_Add_jswrapped) { | 153 TEST(Run_CallJS_Add_jswrapped) { |
184 TestSignatures sigs; | 154 TestSignatures sigs; |
185 TestingModule module; | 155 TestingModule module; |
186 WasmFunctionCompiler t(sigs.i_i(), &module); | 156 WasmFunctionCompiler t(sigs.i_i(), &module); |
187 uint32_t js_index = | 157 uint32_t js_index = |
188 AddJsFunction(&module, sigs.i_i(), "(function(a) { return a + 99; })"); | 158 module.AddJsFunction(sigs.i_i(), "(function(a) { return a + 99; })"); |
189 BUILD(t, WASM_CALL_FUNCTION(js_index, WASM_GET_LOCAL(0))); | 159 BUILD(t, WASM_CALL_FUNCTION(js_index, WASM_GET_LOCAL(0))); |
190 | 160 |
191 Handle<JSFunction> jsfunc = WrapCode(&module, t.CompileAndAdd()); | 161 Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd()); |
192 | 162 |
193 EXPECT_CALL(101, jsfunc, 2, -8); | 163 EXPECT_CALL(101, jsfunc, 2, -8); |
194 EXPECT_CALL(199, jsfunc, 100, -1); | 164 EXPECT_CALL(199, jsfunc, 100, -1); |
195 EXPECT_CALL(-666666801, jsfunc, -666666900, -1); | 165 EXPECT_CALL(-666666801, jsfunc, -666666900, -1); |
196 } | 166 } |
197 | 167 |
198 | 168 |
199 void RunJSSelectTest(int which) { | 169 void RunJSSelectTest(int which) { |
200 const int kMaxParams = 8; | 170 const int kMaxParams = 8; |
201 PredictableInputValues inputs(0x100); | 171 PredictableInputValues inputs(0x100); |
(...skipping 14 matching lines...) Expand all Loading... |
216 | 186 |
217 for (int i = 0; i < num_params; i++) { | 187 for (int i = 0; i < num_params; i++) { |
218 ADD_CODE(code, WASM_F64(inputs.arg_d(i))); | 188 ADD_CODE(code, WASM_F64(inputs.arg_d(i))); |
219 } | 189 } |
220 | 190 |
221 size_t end = code.size(); | 191 size_t end = code.size(); |
222 code.push_back(0); | 192 code.push_back(0); |
223 t.Build(&code[0], &code[end]); | 193 t.Build(&code[0], &code[end]); |
224 } | 194 } |
225 | 195 |
226 Handle<JSFunction> jsfunc = WrapCode(&module, t.CompileAndAdd()); | 196 Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd()); |
227 double expected = inputs.arg_d(which); | 197 double expected = inputs.arg_d(which); |
228 EXPECT_CALL(expected, jsfunc, 0.0, 0.0); | 198 EXPECT_CALL(expected, jsfunc, 0.0, 0.0); |
229 } | 199 } |
230 } | 200 } |
231 | 201 |
232 | 202 |
233 TEST(Run_JSSelect_0) { RunJSSelectTest(0); } | 203 TEST(Run_JSSelect_0) { RunJSSelectTest(0); } |
234 | 204 |
235 TEST(Run_JSSelect_1) { RunJSSelectTest(1); } | 205 TEST(Run_JSSelect_1) { RunJSSelectTest(1); } |
236 | 206 |
(...skipping 16 matching lines...) Expand all Loading... |
253 const int kMaxParams = 8; | 223 const int kMaxParams = 8; |
254 for (int num_params = which + 1; num_params < kMaxParams; num_params++) { | 224 for (int num_params = which + 1; num_params < kMaxParams; num_params++) { |
255 LocalType type = kAstF64; | 225 LocalType type = kAstF64; |
256 LocalType types[kMaxParams + 1] = {type, type, type, type, type, | 226 LocalType types[kMaxParams + 1] = {type, type, type, type, type, |
257 type, type, type, type}; | 227 type, type, type, type}; |
258 FunctionSig sig(1, num_params, types); | 228 FunctionSig sig(1, num_params, types); |
259 | 229 |
260 TestingModule module; | 230 TestingModule module; |
261 WasmFunctionCompiler t(&sig, &module); | 231 WasmFunctionCompiler t(&sig, &module); |
262 BUILD(t, WASM_GET_LOCAL(which)); | 232 BUILD(t, WASM_GET_LOCAL(which)); |
263 Handle<JSFunction> jsfunc = WrapCode(&module, t.CompileAndAdd()); | 233 Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd()); |
264 | 234 |
265 Handle<Object> args[] = { | 235 Handle<Object> args[] = { |
266 isolate->factory()->NewNumber(inputs.arg_d(0)), | 236 isolate->factory()->NewNumber(inputs.arg_d(0)), |
267 isolate->factory()->NewNumber(inputs.arg_d(1)), | 237 isolate->factory()->NewNumber(inputs.arg_d(1)), |
268 isolate->factory()->NewNumber(inputs.arg_d(2)), | 238 isolate->factory()->NewNumber(inputs.arg_d(2)), |
269 isolate->factory()->NewNumber(inputs.arg_d(3)), | 239 isolate->factory()->NewNumber(inputs.arg_d(3)), |
270 isolate->factory()->NewNumber(inputs.arg_d(4)), | 240 isolate->factory()->NewNumber(inputs.arg_d(4)), |
271 isolate->factory()->NewNumber(inputs.arg_d(5)), | 241 isolate->factory()->NewNumber(inputs.arg_d(5)), |
272 isolate->factory()->NewNumber(inputs.arg_d(6)), | 242 isolate->factory()->NewNumber(inputs.arg_d(6)), |
273 isolate->factory()->NewNumber(inputs.arg_d(7)), | 243 isolate->factory()->NewNumber(inputs.arg_d(7)), |
(...skipping 29 matching lines...) Expand all Loading... |
303 DCHECK_LE(num_args, kMaxParams); | 273 DCHECK_LE(num_args, kMaxParams); |
304 LocalType type = kAstF64; | 274 LocalType type = kAstF64; |
305 LocalType types[kMaxParams + 1] = {type, type, type, type, type, type, | 275 LocalType types[kMaxParams + 1] = {type, type, type, type, type, type, |
306 type, type, type, type, type}; | 276 type, type, type, type, type}; |
307 FunctionSig sig(1, num_params, types); | 277 FunctionSig sig(1, num_params, types); |
308 | 278 |
309 for (int which = 0; which < num_params; which++) { | 279 for (int which = 0; which < num_params; which++) { |
310 TestingModule module; | 280 TestingModule module; |
311 WasmFunctionCompiler t(&sig, &module); | 281 WasmFunctionCompiler t(&sig, &module); |
312 BUILD(t, WASM_GET_LOCAL(which)); | 282 BUILD(t, WASM_GET_LOCAL(which)); |
313 Handle<JSFunction> jsfunc = WrapCode(&module, t.CompileAndAdd()); | 283 Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd()); |
314 | 284 |
315 Handle<Object> args[] = {isolate->factory()->NewNumber(inputs.arg_d(0)), | 285 Handle<Object> args[] = {isolate->factory()->NewNumber(inputs.arg_d(0)), |
316 isolate->factory()->NewNumber(inputs.arg_d(1)), | 286 isolate->factory()->NewNumber(inputs.arg_d(1)), |
317 isolate->factory()->NewNumber(inputs.arg_d(2)), | 287 isolate->factory()->NewNumber(inputs.arg_d(2)), |
318 isolate->factory()->NewNumber(inputs.arg_d(3)), | 288 isolate->factory()->NewNumber(inputs.arg_d(3)), |
319 isolate->factory()->NewNumber(inputs.arg_d(4)), | 289 isolate->factory()->NewNumber(inputs.arg_d(4)), |
320 isolate->factory()->NewNumber(inputs.arg_d(5)), | 290 isolate->factory()->NewNumber(inputs.arg_d(5)), |
321 isolate->factory()->NewNumber(inputs.arg_d(6)), | 291 isolate->factory()->NewNumber(inputs.arg_d(6)), |
322 isolate->factory()->NewNumber(inputs.arg_d(7)), | 292 isolate->factory()->NewNumber(inputs.arg_d(7)), |
323 isolate->factory()->NewNumber(inputs.arg_d(8)), | 293 isolate->factory()->NewNumber(inputs.arg_d(8)), |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 | 381 |
412 // Call different select JS functions. | 382 // Call different select JS functions. |
413 for (int which = 0; which < num_params; which++) { | 383 for (int which = 0; which < num_params; which++) { |
414 HandleScope scope(isolate); | 384 HandleScope scope(isolate); |
415 TestingModule module; | 385 TestingModule module; |
416 uint32_t js_index = AddJSSelector(&module, &sig, which); | 386 uint32_t js_index = AddJSSelector(&module, &sig, which); |
417 CHECK_EQ(0, js_index); | 387 CHECK_EQ(0, js_index); |
418 WasmFunctionCompiler t(&sig, &module); | 388 WasmFunctionCompiler t(&sig, &module); |
419 t.Build(&code[0], &code[end]); | 389 t.Build(&code[0], &code[end]); |
420 | 390 |
421 Handle<JSFunction> jsfunc = WrapCode(&module, t.CompileAndAdd()); | 391 Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd()); |
422 | 392 |
423 Handle<Object> args[] = { | 393 Handle<Object> args[] = { |
424 factory->NewNumber(inputs.arg_d(0)), | 394 factory->NewNumber(inputs.arg_d(0)), |
425 factory->NewNumber(inputs.arg_d(1)), | 395 factory->NewNumber(inputs.arg_d(1)), |
426 factory->NewNumber(inputs.arg_d(2)), | 396 factory->NewNumber(inputs.arg_d(2)), |
427 factory->NewNumber(inputs.arg_d(3)), | 397 factory->NewNumber(inputs.arg_d(3)), |
428 factory->NewNumber(inputs.arg_d(4)), | 398 factory->NewNumber(inputs.arg_d(4)), |
429 factory->NewNumber(inputs.arg_d(5)), | 399 factory->NewNumber(inputs.arg_d(5)), |
430 factory->NewNumber(inputs.arg_d(6)), | 400 factory->NewNumber(inputs.arg_d(6)), |
431 factory->NewNumber(inputs.arg_d(7)), | 401 factory->NewNumber(inputs.arg_d(7)), |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 RunJSSelectAlignTest(9, 8); | 455 RunJSSelectAlignTest(9, 8); |
486 RunJSSelectAlignTest(9, 9); | 456 RunJSSelectAlignTest(9, 9); |
487 } | 457 } |
488 | 458 |
489 TEST(Run_JSSelectAlign_10) { | 459 TEST(Run_JSSelectAlign_10) { |
490 RunJSSelectAlignTest(10, 7); | 460 RunJSSelectAlignTest(10, 7); |
491 RunJSSelectAlignTest(10, 8); | 461 RunJSSelectAlignTest(10, 8); |
492 RunJSSelectAlignTest(10, 9); | 462 RunJSSelectAlignTest(10, 9); |
493 RunJSSelectAlignTest(10, 10); | 463 RunJSSelectAlignTest(10, 10); |
494 } | 464 } |
OLD | NEW |