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 |