| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 #ifndef WASM_RUN_UTILS_H | 5 #ifndef WASM_RUN_UTILS_H |
| 6 #define WASM_RUN_UTILS_H | 6 #define WASM_RUN_UTILS_H |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <stdlib.h> | 9 #include <stdlib.h> |
| 10 #include <string.h> | 10 #include <string.h> |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 // TODO(titzer): check traps more robustly in tests. | 39 // TODO(titzer): check traps more robustly in tests. |
| 40 // Currently, in tests, we just return 0xdeadbeef from the function in which | 40 // Currently, in tests, we just return 0xdeadbeef from the function in which |
| 41 // the trap occurs if the runtime context is not available to throw a JavaScript | 41 // the trap occurs if the runtime context is not available to throw a JavaScript |
| 42 // exception. | 42 // exception. |
| 43 #define CHECK_TRAP32(x) \ | 43 #define CHECK_TRAP32(x) \ |
| 44 CHECK_EQ(0xdeadbeef, (bit_cast<uint32_t>(x)) & 0xFFFFFFFF) | 44 CHECK_EQ(0xdeadbeef, (bit_cast<uint32_t>(x)) & 0xFFFFFFFF) |
| 45 #define CHECK_TRAP64(x) \ | 45 #define CHECK_TRAP64(x) \ |
| 46 CHECK_EQ(0xdeadbeefdeadbeef, (bit_cast<uint64_t>(x)) & 0xFFFFFFFFFFFFFFFF) | 46 CHECK_EQ(0xdeadbeefdeadbeef, (bit_cast<uint64_t>(x)) & 0xFFFFFFFFFFFFFFFF) |
| 47 #define CHECK_TRAP(x) CHECK_TRAP32(x) | 47 #define CHECK_TRAP(x) CHECK_TRAP32(x) |
| 48 | 48 |
| 49 #define WASM_RUNNER_MAX_NUM_PARAMETERS 4 |
| 49 #define WASM_WRAPPER_RETURN_VALUE 8754 | 50 #define WASM_WRAPPER_RETURN_VALUE 8754 |
| 50 | 51 |
| 51 namespace { | 52 namespace { |
| 52 using namespace v8::base; | 53 using namespace v8::base; |
| 53 using namespace v8::internal; | 54 using namespace v8::internal; |
| 54 using namespace v8::internal::compiler; | 55 using namespace v8::internal::compiler; |
| 55 using namespace v8::internal::wasm; | 56 using namespace v8::internal::wasm; |
| 56 | 57 |
| 57 inline void init_env(FunctionEnv* env, FunctionSig* sig) { | 58 inline void init_env(FunctionEnv* env, FunctionSig* sig) { |
| 58 env->module = nullptr; | 59 env->module = nullptr; |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 } | 254 } |
| 254 | 255 |
| 255 template <typename ReturnType> | 256 template <typename ReturnType> |
| 256 class WasmFunctionWrapper : public HandleAndZoneScope, | 257 class WasmFunctionWrapper : public HandleAndZoneScope, |
| 257 private GraphAndBuilders { | 258 private GraphAndBuilders { |
| 258 public: | 259 public: |
| 259 WasmFunctionWrapper() | 260 WasmFunctionWrapper() |
| 260 : GraphAndBuilders(main_zone()), | 261 : GraphAndBuilders(main_zone()), |
| 261 inner_code_node_(nullptr), | 262 inner_code_node_(nullptr), |
| 262 signature_(nullptr) { | 263 signature_(nullptr) { |
| 263 Signature<MachineType>::Builder sig_builder(zone(), 1, 5); | 264 // One additional parameter for the pointer to the return value memory. |
| 265 Signature<MachineType>::Builder sig_builder( |
| 266 zone(), 1, WASM_RUNNER_MAX_NUM_PARAMETERS + 1); |
| 264 | 267 |
| 265 sig_builder.AddReturn(MachineType::Int32()); | 268 sig_builder.AddReturn(MachineType::Int32()); |
| 266 for (int i = 0; i < 5; i++) { | 269 for (int i = 0; i < WASM_RUNNER_MAX_NUM_PARAMETERS + 1; i++) { |
| 267 sig_builder.AddParam(MachineType::Pointer()); | 270 sig_builder.AddParam(MachineType::Pointer()); |
| 268 } | 271 } |
| 269 signature_ = sig_builder.Build(); | 272 signature_ = sig_builder.Build(); |
| 270 } | 273 } |
| 271 | 274 |
| 272 void Init(CallDescriptor* descriptor, MachineType p0 = MachineType::None(), | 275 void Init(CallDescriptor* descriptor, MachineType p0 = MachineType::None(), |
| 273 MachineType p1 = MachineType::None(), | 276 MachineType p1 = MachineType::None(), |
| 274 MachineType p2 = MachineType::None(), | 277 MachineType p2 = MachineType::None(), |
| 275 MachineType p3 = MachineType::None()) { | 278 MachineType p3 = MachineType::None()) { |
| 276 // Create the TF graph for the wrapper. The wrapper always takes four | 279 // Create the TF graph for the wrapper. The wrapper always takes four |
| 277 // pointers as parameters, but may not pass the values of all pointers to | 280 // pointers as parameters, but may not pass the values of all pointers to |
| 278 // the actual test function. | 281 // the actual test function. |
| 279 | 282 |
| 280 // Function, effect, and control. | 283 // Function, effect, and control. |
| 281 Node** parameters = zone()->template NewArray<Node*>(4 + 3); | 284 Node** parameters = |
| 285 zone()->template NewArray<Node*>(WASM_RUNNER_MAX_NUM_PARAMETERS + 3); |
| 282 graph()->SetStart(graph()->NewNode(common()->Start(6))); | 286 graph()->SetStart(graph()->NewNode(common()->Start(6))); |
| 283 Node* effect = graph()->start(); | 287 Node* effect = graph()->start(); |
| 284 int parameter_count = 0; | 288 int parameter_count = 0; |
| 285 | 289 |
| 286 // Dummy node which gets replaced in SetInnerCode. | 290 // Dummy node which gets replaced in SetInnerCode. |
| 287 inner_code_node_ = graph()->NewNode(common()->Int32Constant(0)); | 291 inner_code_node_ = graph()->NewNode(common()->Int32Constant(0)); |
| 288 parameters[parameter_count++] = inner_code_node_; | 292 parameters[parameter_count++] = inner_code_node_; |
| 289 | 293 |
| 290 if (p0 != MachineType::None()) { | 294 if (p0 != MachineType::None()) { |
| 291 parameters[parameter_count] = graph()->NewNode( | 295 parameters[parameter_count] = graph()->NewNode( |
| (...skipping 30 matching lines...) Expand all Loading... |
| 322 | 326 |
| 323 parameters[parameter_count++] = effect; | 327 parameters[parameter_count++] = effect; |
| 324 parameters[parameter_count++] = graph()->start(); | 328 parameters[parameter_count++] = graph()->start(); |
| 325 Node* call = graph()->NewNode(common()->Call(descriptor), parameter_count, | 329 Node* call = graph()->NewNode(common()->Call(descriptor), parameter_count, |
| 326 parameters); | 330 parameters); |
| 327 | 331 |
| 328 effect = graph()->NewNode( | 332 effect = graph()->NewNode( |
| 329 machine()->Store( | 333 machine()->Store( |
| 330 StoreRepresentation(MachineTypeForC<ReturnType>().representation(), | 334 StoreRepresentation(MachineTypeForC<ReturnType>().representation(), |
| 331 WriteBarrierKind::kNoWriteBarrier)), | 335 WriteBarrierKind::kNoWriteBarrier)), |
| 332 graph()->NewNode(common()->Parameter(4), graph()->start()), | 336 graph()->NewNode(common()->Parameter(WASM_RUNNER_MAX_NUM_PARAMETERS), |
| 337 graph()->start()), |
| 333 graph()->NewNode(common()->Int32Constant(0)), call, effect, | 338 graph()->NewNode(common()->Int32Constant(0)), call, effect, |
| 334 graph()->start()); | 339 graph()->start()); |
| 335 Node* r = graph()->NewNode( | 340 Node* r = graph()->NewNode( |
| 336 common()->Return(), | 341 common()->Return(), |
| 337 graph()->NewNode(common()->Int32Constant(WASM_WRAPPER_RETURN_VALUE)), | 342 graph()->NewNode(common()->Int32Constant(WASM_WRAPPER_RETURN_VALUE)), |
| 338 effect, graph()->start()); | 343 effect, graph()->start()); |
| 339 graph()->SetEnd(graph()->NewNode(common()->End(2), r, graph()->start())); | 344 graph()->SetEnd(graph()->NewNode(common()->End(2), r, graph()->start())); |
| 340 } | 345 } |
| 341 | 346 |
| 342 void SetInnerCode(Handle<Code> code_handle) { | 347 void SetInnerCode(Handle<Code> code_handle) { |
| 343 NodeProperties::ChangeOp(inner_code_node_, | 348 NodeProperties::ChangeOp(inner_code_node_, |
| 344 common()->HeapConstant(code_handle)); | 349 common()->HeapConstant(code_handle)); |
| 345 } | 350 } |
| 346 | 351 |
| 347 Handle<Code> GetWrapperCode() { | 352 Handle<Code> GetWrapperCode() { |
| 348 if (code_.is_null()) { | 353 if (code_.is_null()) { |
| 349 Isolate* isolate = CcTest::InitIsolateOnce(); | 354 Isolate* isolate = CcTest::InitIsolateOnce(); |
| 350 | 355 |
| 351 CallDescriptor* descriptor = | 356 CallDescriptor* descriptor = |
| 352 Linkage::GetSimplifiedCDescriptor(zone(), signature_, true); | 357 Linkage::GetSimplifiedCDescriptor(zone(), signature_, true); |
| 353 | 358 |
| 359 if (kPointerSize == 4) { |
| 360 // One additional parameter for the pointer of the return value. |
| 361 Signature<MachineRepresentation>::Builder rep_builder( |
| 362 zone(), 1, WASM_RUNNER_MAX_NUM_PARAMETERS + 1); |
| 363 |
| 364 rep_builder.AddReturn(MachineRepresentation::kWord32); |
| 365 for (int i = 0; i < WASM_RUNNER_MAX_NUM_PARAMETERS + 1; i++) { |
| 366 rep_builder.AddParam(MachineRepresentation::kWord32); |
| 367 } |
| 368 Int64Lowering r(graph(), machine(), common(), zone(), |
| 369 rep_builder.Build()); |
| 370 r.LowerGraph(); |
| 371 } |
| 372 |
| 354 CompilationInfo info("testing", isolate, graph()->zone()); | 373 CompilationInfo info("testing", isolate, graph()->zone()); |
| 355 code_ = | 374 code_ = |
| 356 Pipeline::GenerateCodeForTesting(&info, descriptor, graph(), nullptr); | 375 Pipeline::GenerateCodeForTesting(&info, descriptor, graph(), nullptr); |
| 357 CHECK(!code_.is_null()); | 376 CHECK(!code_.is_null()); |
| 358 #ifdef ENABLE_DISASSEMBLER | 377 #ifdef ENABLE_DISASSEMBLER |
| 359 if (FLAG_print_opt_code) { | 378 if (FLAG_print_opt_code) { |
| 360 OFStream os(stdout); | 379 OFStream os(stdout); |
| 361 code_->Disassemble("wasm wrapper", os); | 380 code_->Disassemble("wasm wrapper", os); |
| 362 } | 381 } |
| 363 #endif | 382 #endif |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 byte AllocateLocal(LocalType type) { | 430 byte AllocateLocal(LocalType type) { |
| 412 int result = static_cast<int>(env.total_locals); | 431 int result = static_cast<int>(env.total_locals); |
| 413 env.AddLocals(type, 1); | 432 env.AddLocals(type, 1); |
| 414 byte b = static_cast<byte>(result); | 433 byte b = static_cast<byte>(result); |
| 415 CHECK_EQ(result, b); | 434 CHECK_EQ(result, b); |
| 416 return b; | 435 return b; |
| 417 } | 436 } |
| 418 | 437 |
| 419 Handle<Code> Compile(ModuleEnv* module) { | 438 Handle<Code> Compile(ModuleEnv* module) { |
| 420 InitializeDescriptor(); | 439 InitializeDescriptor(); |
| 440 CallDescriptor* desc = descriptor_; |
| 441 if (kPointerSize == 4) { |
| 442 desc = module->GetI32WasmCallDescriptor(this->zone(), desc); |
| 443 } |
| 421 CompilationInfo info("wasm compile", this->isolate(), this->zone()); | 444 CompilationInfo info("wasm compile", this->isolate(), this->zone()); |
| 422 Handle<Code> result = | 445 Handle<Code> result = |
| 423 Pipeline::GenerateCodeForTesting(&info, descriptor_, this->graph()); | 446 Pipeline::GenerateCodeForTesting(&info, desc, this->graph()); |
| 424 #ifdef ENABLE_DISASSEMBLER | 447 #ifdef ENABLE_DISASSEMBLER |
| 425 if (!result.is_null() && FLAG_print_opt_code) { | 448 if (!result.is_null() && FLAG_print_opt_code) { |
| 426 OFStream os(stdout); | 449 OFStream os(stdout); |
| 427 result->Disassemble("wasm code", os); | 450 result->Disassemble("wasm code", os); |
| 428 } | 451 } |
| 429 #endif | 452 #endif |
| 430 | 453 |
| 431 return result; | 454 return result; |
| 432 } | 455 } |
| 433 | 456 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 | 545 |
| 523 byte AllocateLocal(LocalType type) { | 546 byte AllocateLocal(LocalType type) { |
| 524 int result = static_cast<int>(env()->total_locals); | 547 int result = static_cast<int>(env()->total_locals); |
| 525 env()->AddLocals(type, 1); | 548 env()->AddLocals(type, 1); |
| 526 byte b = static_cast<byte>(result); | 549 byte b = static_cast<byte>(result); |
| 527 CHECK_EQ(result, b); | 550 CHECK_EQ(result, b); |
| 528 return b; | 551 return b; |
| 529 } | 552 } |
| 530 | 553 |
| 531 private: | 554 private: |
| 532 LocalType storage_[5]; | 555 LocalType storage_[WASM_RUNNER_MAX_NUM_PARAMETERS]; |
| 533 FunctionSig signature_; | 556 FunctionSig signature_; |
| 534 WasmFunctionCompiler compiler_; | 557 WasmFunctionCompiler compiler_; |
| 535 WasmFunctionWrapper<ReturnType> wrapper_; | 558 WasmFunctionWrapper<ReturnType> wrapper_; |
| 536 bool compilation_done_; | 559 bool compilation_done_; |
| 537 | 560 |
| 538 static size_t GetParameterCount(MachineType p0, MachineType p1, | 561 static size_t GetParameterCount(MachineType p0, MachineType p1, |
| 539 MachineType p2, MachineType p3) { | 562 MachineType p2, MachineType p3) { |
| 540 if (p0 == MachineType::None()) return 0; | 563 if (p0 == MachineType::None()) return 0; |
| 541 if (p1 == MachineType::None()) return 1; | 564 if (p1 == MachineType::None()) return 1; |
| 542 if (p2 == MachineType::None()) return 2; | 565 if (p2 == MachineType::None()) return 2; |
| 543 if (p3 == MachineType::None()) return 3; | 566 if (p3 == MachineType::None()) return 3; |
| 544 return 4; | 567 return 4; |
| 545 } | 568 } |
| 546 }; | 569 }; |
| 547 | 570 |
| 548 } // namespace | 571 } // namespace |
| 549 | 572 |
| 550 #endif | 573 #endif |
| OLD | NEW |