| 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 |