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 |