| 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 "src/compiler/wasm-compiler.h" | 5 #include "src/compiler/wasm-compiler.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "src/isolate-inl.h" | 9 #include "src/isolate-inl.h" |
| 10 | 10 |
| (...skipping 2523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2534 graph()->start()); | 2534 graph()->start()); |
| 2535 } | 2535 } |
| 2536 Node* jsval = ToJS( | 2536 Node* jsval = ToJS( |
| 2537 retval, sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); | 2537 retval, sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); |
| 2538 Node* ret = | 2538 Node* ret = |
| 2539 graph()->NewNode(jsgraph()->common()->Return(), jsval, call, start); | 2539 graph()->NewNode(jsgraph()->common()->Return(), jsval, call, start); |
| 2540 | 2540 |
| 2541 MergeControlToEnd(jsgraph(), ret); | 2541 MergeControlToEnd(jsgraph(), ret); |
| 2542 } | 2542 } |
| 2543 | 2543 |
| 2544 int WasmGraphBuilder::AddParameterNodes(Node** args, int pos, int param_count, |
| 2545 wasm::FunctionSig* sig) { |
| 2546 // Convert WASM numbers to JS values. |
| 2547 int param_index = 0; |
| 2548 for (int i = 0; i < param_count; ++i) { |
| 2549 Node* param = graph()->NewNode( |
| 2550 jsgraph()->common()->Parameter(param_index++), graph()->start()); |
| 2551 args[pos++] = ToJS(param, sig->GetParam(i)); |
| 2552 if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kAstI64) { |
| 2553 // On 32 bit platforms we have to skip the high word of int64 |
| 2554 // parameters. |
| 2555 param_index++; |
| 2556 } |
| 2557 } |
| 2558 return pos; |
| 2559 } |
| 2560 |
| 2544 void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target, | 2561 void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target, |
| 2545 wasm::FunctionSig* sig) { | 2562 wasm::FunctionSig* sig) { |
| 2546 DCHECK(target->IsCallable()); | 2563 DCHECK(target->IsCallable()); |
| 2547 | 2564 |
| 2548 int wasm_count = static_cast<int>(sig->parameter_count()); | 2565 int wasm_count = static_cast<int>(sig->parameter_count()); |
| 2549 int param_count; | 2566 int param_count; |
| 2550 if (jsgraph()->machine()->Is64()) { | 2567 if (jsgraph()->machine()->Is64()) { |
| 2551 param_count = wasm_count; | 2568 param_count = wasm_count; |
| 2552 } else { | 2569 } else { |
| 2553 param_count = Int64Lowering::GetParameterCountAfterLowering(sig); | 2570 param_count = Int64Lowering::GetParameterCountAfterLowering(sig); |
| 2554 } | 2571 } |
| 2555 | 2572 |
| 2556 // Build the start and the parameter nodes. | 2573 // Build the start and the parameter nodes. |
| 2557 Isolate* isolate = jsgraph()->isolate(); | 2574 Isolate* isolate = jsgraph()->isolate(); |
| 2558 CallDescriptor* desc; | 2575 CallDescriptor* desc; |
| 2559 Node* start = Start(param_count + 3); | 2576 Node* start = Start(param_count + 3); |
| 2560 *effect_ = start; | 2577 *effect_ = start; |
| 2561 *control_ = start; | 2578 *control_ = start; |
| 2562 Node** args = Buffer(wasm_count + 7); | 2579 Node** args = Buffer(wasm_count + 7); |
| 2563 | 2580 |
| 2564 // The default context of the target. | 2581 Node* call; |
| 2565 Handle<Context> target_context = isolate->native_context(); | 2582 bool direct_call = false; |
| 2566 | 2583 |
| 2567 // Optimization: check if the target is a JSFunction with the right arity so | |
| 2568 // that we can call it directly. | |
| 2569 bool call_direct = false; | |
| 2570 int pos = 0; | |
| 2571 if (target->IsJSFunction()) { | 2584 if (target->IsJSFunction()) { |
| 2572 Handle<JSFunction> function = Handle<JSFunction>::cast(target); | 2585 Handle<JSFunction> function = Handle<JSFunction>::cast(target); |
| 2573 if (function->shared()->internal_formal_parameter_count() == wasm_count) { | 2586 if (function->shared()->internal_formal_parameter_count() == wasm_count) { |
| 2574 call_direct = true; | 2587 direct_call = true; |
| 2575 | 2588 int pos = 0; |
| 2576 args[pos++] = jsgraph()->Constant(target); // target callable. | 2589 args[pos++] = jsgraph()->Constant(target); // target callable. |
| 2577 // Receiver. | 2590 // Receiver. |
| 2578 if (is_sloppy(function->shared()->language_mode()) && | 2591 if (is_sloppy(function->shared()->language_mode()) && |
| 2579 !function->shared()->native()) { | 2592 !function->shared()->native()) { |
| 2580 args[pos++] = | 2593 args[pos++] = |
| 2581 HeapConstant(handle(function->context()->global_proxy(), isolate)); | 2594 HeapConstant(handle(function->context()->global_proxy(), isolate)); |
| 2582 } else { | 2595 } else { |
| 2583 args[pos++] = jsgraph()->Constant( | 2596 args[pos++] = jsgraph()->Constant( |
| 2584 handle(isolate->heap()->undefined_value(), isolate)); | 2597 handle(isolate->heap()->undefined_value(), isolate)); |
| 2585 } | 2598 } |
| 2586 | 2599 |
| 2587 desc = Linkage::GetJSCallDescriptor( | 2600 desc = Linkage::GetJSCallDescriptor( |
| 2588 graph()->zone(), false, wasm_count + 1, CallDescriptor::kNoFlags); | 2601 graph()->zone(), false, wasm_count + 1, CallDescriptor::kNoFlags); |
| 2589 | 2602 |
| 2590 // For a direct call we have to use the context of the JSFunction. | 2603 // Convert WASM numbers to JS values. |
| 2591 target_context = handle(function->context()); | 2604 pos = AddParameterNodes(args, pos, wasm_count, sig); |
| 2605 |
| 2606 args[pos++] = jsgraph()->UndefinedConstant(); // new target |
| 2607 args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count |
| 2608 args[pos++] = HeapConstant(handle(function->context())); |
| 2609 args[pos++] = *effect_; |
| 2610 args[pos++] = *control_; |
| 2611 |
| 2612 call = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args); |
| 2592 } | 2613 } |
| 2593 } | 2614 } |
| 2594 | 2615 |
| 2595 // We cannot call the target directly, we have to use the Call builtin. | 2616 // We cannot call the target directly, we have to use the Call builtin. |
| 2596 if (!call_direct) { | 2617 if (!direct_call) { |
| 2618 int pos = 0; |
| 2597 Callable callable = CodeFactory::Call(isolate); | 2619 Callable callable = CodeFactory::Call(isolate); |
| 2598 args[pos++] = jsgraph()->HeapConstant(callable.code()); | 2620 args[pos++] = jsgraph()->HeapConstant(callable.code()); |
| 2599 args[pos++] = jsgraph()->Constant(target); // target callable | 2621 args[pos++] = jsgraph()->Constant(target); // target callable |
| 2600 args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count | 2622 args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count |
| 2601 args[pos++] = jsgraph()->Constant( | 2623 args[pos++] = jsgraph()->Constant( |
| 2602 handle(isolate->heap()->undefined_value(), isolate)); // receiver | 2624 handle(isolate->heap()->undefined_value(), isolate)); // receiver |
| 2603 | 2625 |
| 2604 desc = Linkage::GetStubCallDescriptor(isolate, graph()->zone(), | 2626 desc = Linkage::GetStubCallDescriptor(isolate, graph()->zone(), |
| 2605 callable.descriptor(), wasm_count + 1, | 2627 callable.descriptor(), wasm_count + 1, |
| 2606 CallDescriptor::kNoFlags); | 2628 CallDescriptor::kNoFlags); |
| 2629 |
| 2630 // Convert WASM numbers to JS values. |
| 2631 pos = AddParameterNodes(args, pos, wasm_count, sig); |
| 2632 |
| 2633 // The native_context is sufficient here, because all kind of callables |
| 2634 // which depend on the context provide their own context. The context here |
| 2635 // is only needed if the target is a constructor to throw a TypeError, if |
| 2636 // the target is a native function, or if the target is a callable JSObject, |
| 2637 // which can only be constructed by the runtime. |
| 2638 args[pos++] = HeapConstant(isolate->native_context()); |
| 2639 args[pos++] = *effect_; |
| 2640 args[pos++] = *control_; |
| 2641 |
| 2642 call = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args); |
| 2607 } | 2643 } |
| 2608 | 2644 |
| 2609 // Convert WASM numbers to JS values. | |
| 2610 int param_index = 0; | |
| 2611 for (int i = 0; i < wasm_count; ++i) { | |
| 2612 Node* param = | |
| 2613 graph()->NewNode(jsgraph()->common()->Parameter(param_index++), start); | |
| 2614 args[pos++] = ToJS(param, sig->GetParam(i)); | |
| 2615 if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kAstI64) { | |
| 2616 // On 32 bit platforms we have to skip the high word of int64 parameters. | |
| 2617 param_index++; | |
| 2618 } | |
| 2619 } | |
| 2620 | |
| 2621 if (call_direct) { | |
| 2622 args[pos++] = jsgraph()->UndefinedConstant(); // new target | |
| 2623 args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count | |
| 2624 } | |
| 2625 | |
| 2626 args[pos++] = HeapConstant(target_context); | |
| 2627 args[pos++] = *effect_; | |
| 2628 args[pos++] = *control_; | |
| 2629 | |
| 2630 Node* call = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args); | |
| 2631 | |
| 2632 // Convert the return value back. | 2645 // Convert the return value back. |
| 2633 Node* ret; | 2646 Node* ret; |
| 2634 Node* val = | 2647 Node* val = |
| 2635 FromJS(call, HeapConstant(isolate->native_context()), | 2648 FromJS(call, HeapConstant(isolate->native_context()), |
| 2636 sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); | 2649 sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); |
| 2637 if (jsgraph()->machine()->Is32() && sig->return_count() > 0 && | 2650 if (jsgraph()->machine()->Is32() && sig->return_count() > 0 && |
| 2638 sig->GetReturn() == wasm::kAstI64) { | 2651 sig->GetReturn() == wasm::kAstI64) { |
| 2639 ret = graph()->NewNode(jsgraph()->common()->Return(), val, | 2652 ret = graph()->NewNode(jsgraph()->common()->Return(), val, |
| 2640 graph()->NewNode(jsgraph()->machine()->Word32Sar(), | 2653 graph()->NewNode(jsgraph()->machine()->Word32Sar(), |
| 2641 val, jsgraph()->Int32Constant(31)), | 2654 val, jsgraph()->Int32Constant(31)), |
| (...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3249 function_->code_start_offset), | 3262 function_->code_start_offset), |
| 3250 compile_ms); | 3263 compile_ms); |
| 3251 } | 3264 } |
| 3252 | 3265 |
| 3253 return code; | 3266 return code; |
| 3254 } | 3267 } |
| 3255 | 3268 |
| 3256 } // namespace compiler | 3269 } // namespace compiler |
| 3257 } // namespace internal | 3270 } // namespace internal |
| 3258 } // namespace v8 | 3271 } // namespace v8 |
| OLD | NEW |