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 2530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2541 } | 2541 } |
2542 | 2542 |
2543 // Build the start and the parameter nodes. | 2543 // Build the start and the parameter nodes. |
2544 Isolate* isolate = jsgraph()->isolate(); | 2544 Isolate* isolate = jsgraph()->isolate(); |
2545 CallDescriptor* desc; | 2545 CallDescriptor* desc; |
2546 Node* start = Start(param_count + 3); | 2546 Node* start = Start(param_count + 3); |
2547 *effect_ = start; | 2547 *effect_ = start; |
2548 *control_ = start; | 2548 *control_ = start; |
2549 Node** args = Buffer(wasm_count + 7); | 2549 Node** args = Buffer(wasm_count + 7); |
2550 | 2550 |
2551 // The default context of the target. | 2551 Node* call; |
2552 Handle<Context> target_context = isolate->native_context(); | 2552 bool direct_call = false; |
2553 | 2553 |
2554 // Optimization: check if the target is a JSFunction with the right arity so | |
2555 // that we can call it directly. | |
2556 bool call_direct = false; | |
2557 int pos = 0; | |
2558 if (target->IsJSFunction()) { | 2554 if (target->IsJSFunction()) { |
2559 Handle<JSFunction> function = Handle<JSFunction>::cast(target); | 2555 Handle<JSFunction> function = Handle<JSFunction>::cast(target); |
2560 if (function->shared()->internal_formal_parameter_count() == wasm_count) { | 2556 if (function->shared()->internal_formal_parameter_count() == wasm_count) { |
2561 call_direct = true; | 2557 direct_call = true; |
2562 | 2558 int pos = 0; |
2563 args[pos++] = jsgraph()->Constant(target); // target callable. | 2559 args[pos++] = jsgraph()->Constant(target); // target callable. |
2564 // Receiver. | 2560 // Receiver. |
2565 if (is_sloppy(function->shared()->language_mode()) && | 2561 if (is_sloppy(function->shared()->language_mode()) && |
2566 !function->shared()->native()) { | 2562 !function->shared()->native()) { |
2567 args[pos++] = | 2563 args[pos++] = |
2568 HeapConstant(handle(function->context()->global_proxy(), isolate)); | 2564 HeapConstant(handle(function->context()->global_proxy(), isolate)); |
2569 } else { | 2565 } else { |
2570 args[pos++] = jsgraph()->Constant( | 2566 args[pos++] = jsgraph()->Constant( |
2571 handle(isolate->heap()->undefined_value(), isolate)); | 2567 handle(isolate->heap()->undefined_value(), isolate)); |
2572 } | 2568 } |
2573 | 2569 |
2574 desc = Linkage::GetJSCallDescriptor( | 2570 desc = Linkage::GetJSCallDescriptor( |
2575 graph()->zone(), false, wasm_count + 1, CallDescriptor::kNoFlags); | 2571 graph()->zone(), false, wasm_count + 1, CallDescriptor::kNoFlags); |
2576 | 2572 |
2577 // For a direct call we have to use the context of the JSFunction. | 2573 // Convert WASM numbers to JS values. |
titzer
2016/09/01 14:35:17
Is it possible to factor this loop out with its ca
ahaas
2016/09/01 17:17:52
Done.
| |
2578 target_context = handle(function->context()); | 2574 int param_index = 0; |
2575 for (int i = 0; i < wasm_count; ++i) { | |
2576 Node* param = graph()->NewNode( | |
2577 jsgraph()->common()->Parameter(param_index++), start); | |
2578 args[pos++] = ToJS(param, sig->GetParam(i)); | |
2579 if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kAstI64) { | |
2580 // On 32 bit platforms we have to skip the high word of int64 | |
2581 // parameters. | |
2582 param_index++; | |
2583 } | |
2584 } | |
2585 | |
2586 args[pos++] = jsgraph()->UndefinedConstant(); // new target | |
2587 args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count | |
2588 args[pos++] = HeapConstant(handle(function->context())); | |
2589 args[pos++] = *effect_; | |
2590 args[pos++] = *control_; | |
2591 | |
2592 call = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args); | |
2579 } | 2593 } |
2580 } | 2594 } |
2581 | 2595 |
2582 // We cannot call the target directly, we have to use the Call builtin. | 2596 // We cannot call the target directly, we have to use the Call builtin. |
2583 if (!call_direct) { | 2597 if (!direct_call) { |
2598 int pos = 0; | |
2584 Callable callable = CodeFactory::Call(isolate); | 2599 Callable callable = CodeFactory::Call(isolate); |
2585 args[pos++] = jsgraph()->HeapConstant(callable.code()); | 2600 args[pos++] = jsgraph()->HeapConstant(callable.code()); |
2586 args[pos++] = jsgraph()->Constant(target); // target callable | 2601 args[pos++] = jsgraph()->Constant(target); // target callable |
2587 args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count | 2602 args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count |
2588 args[pos++] = jsgraph()->Constant( | 2603 args[pos++] = jsgraph()->Constant( |
2589 handle(isolate->heap()->undefined_value(), isolate)); // receiver | 2604 handle(isolate->heap()->undefined_value(), isolate)); // receiver |
2590 | 2605 |
2591 desc = Linkage::GetStubCallDescriptor(isolate, graph()->zone(), | 2606 desc = Linkage::GetStubCallDescriptor(isolate, graph()->zone(), |
2592 callable.descriptor(), wasm_count + 1, | 2607 callable.descriptor(), wasm_count + 1, |
2593 CallDescriptor::kNoFlags); | 2608 CallDescriptor::kNoFlags); |
2609 | |
2610 // Convert WASM numbers to JS values. | |
2611 int param_index = 0; | |
2612 for (int i = 0; i < wasm_count; ++i) { | |
2613 Node* param = graph()->NewNode( | |
2614 jsgraph()->common()->Parameter(param_index++), start); | |
2615 args[pos++] = ToJS(param, sig->GetParam(i)); | |
2616 if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kAstI64) { | |
2617 // On 32 bit platforms we have to skip the high word of int64 | |
2618 // parameters. | |
2619 param_index++; | |
2620 } | |
2621 } | |
2622 | |
2623 // The native_context is sufficient here, because all kind of callables | |
2624 // which depend on the context provide their own context. The context here | |
2625 // is only needed if the target is a constructor to throw a TypeError, if | |
2626 // the target is a native function, or if the target is a callable JSObject, | |
2627 // which can only be constructed by the runtime. | |
2628 args[pos++] = HeapConstant(isolate->native_context()); | |
2629 args[pos++] = *effect_; | |
2630 args[pos++] = *control_; | |
2631 | |
2632 call = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args); | |
2594 } | 2633 } |
2595 | 2634 |
2596 // Convert WASM numbers to JS values. | |
2597 int param_index = 0; | |
2598 for (int i = 0; i < wasm_count; ++i) { | |
2599 Node* param = | |
2600 graph()->NewNode(jsgraph()->common()->Parameter(param_index++), start); | |
2601 args[pos++] = ToJS(param, sig->GetParam(i)); | |
2602 if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kAstI64) { | |
2603 // On 32 bit platforms we have to skip the high word of int64 parameters. | |
2604 param_index++; | |
2605 } | |
2606 } | |
2607 | |
2608 if (call_direct) { | |
2609 args[pos++] = jsgraph()->UndefinedConstant(); // new target | |
2610 args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count | |
2611 } | |
2612 | |
2613 args[pos++] = HeapConstant(target_context); | |
2614 args[pos++] = *effect_; | |
2615 args[pos++] = *control_; | |
2616 | |
2617 Node* call = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args); | |
2618 | |
2619 // Convert the return value back. | 2635 // Convert the return value back. |
2620 Node* ret; | 2636 Node* ret; |
2621 Node* val = | 2637 Node* val = |
2622 FromJS(call, HeapConstant(isolate->native_context()), | 2638 FromJS(call, HeapConstant(isolate->native_context()), |
2623 sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); | 2639 sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); |
2624 if (jsgraph()->machine()->Is32() && sig->return_count() > 0 && | 2640 if (jsgraph()->machine()->Is32() && sig->return_count() > 0 && |
2625 sig->GetReturn() == wasm::kAstI64) { | 2641 sig->GetReturn() == wasm::kAstI64) { |
2626 ret = graph()->NewNode(jsgraph()->common()->Return(), val, | 2642 ret = graph()->NewNode(jsgraph()->common()->Return(), val, |
2627 graph()->NewNode(jsgraph()->machine()->Word32Sar(), | 2643 graph()->NewNode(jsgraph()->machine()->Word32Sar(), |
2628 val, jsgraph()->Int32Constant(31)), | 2644 val, jsgraph()->Int32Constant(31)), |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3236 function_->code_start_offset), | 3252 function_->code_start_offset), |
3237 compile_ms); | 3253 compile_ms); |
3238 } | 3254 } |
3239 | 3255 |
3240 return code; | 3256 return code; |
3241 } | 3257 } |
3242 | 3258 |
3243 } // namespace compiler | 3259 } // namespace compiler |
3244 } // namespace internal | 3260 } // namespace internal |
3245 } // namespace v8 | 3261 } // namespace v8 |
OLD | NEW |