OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
10 #include "src/compiler/js-type-feedback.h" | 10 #include "src/compiler/js-type-feedback.h" |
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 | 461 |
462 // Initialize the incoming context. | 462 // Initialize the incoming context. |
463 CreateFunctionContext(constant_context); | 463 CreateFunctionContext(constant_context); |
464 ContextScope incoming(this, scope, function_context_.get()); | 464 ContextScope incoming(this, scope, function_context_.get()); |
465 | 465 |
466 // Initialize control scope. | 466 // Initialize control scope. |
467 ControlScope control(this); | 467 ControlScope control(this); |
468 | 468 |
469 // Build receiver check for sloppy mode if necessary. | 469 // Build receiver check for sloppy mode if necessary. |
470 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? | 470 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? |
471 Node* original_receiver = env.Lookup(scope->receiver()); | 471 Node* patched_receiver = nullptr; |
472 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); | 472 if (scope->has_this_declaration()) { |
473 env.Bind(scope->receiver(), patched_receiver); | 473 Node* original_receiver = NewNode(common()->Parameter(0), graph()->start()); |
| 474 patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); |
| 475 if (scope->receiver()->IsStackAllocated()) { |
| 476 env.Bind(scope->receiver(), patched_receiver); |
| 477 } |
| 478 } |
474 | 479 |
475 // Build function context only if there are context allocated variables. | 480 // Build function context only if there are context allocated variables. |
476 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 481 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
477 if (heap_slots > 0) { | 482 if (heap_slots > 0) { |
478 // Push a new inner context scope for the function. | 483 // Push a new inner context scope for the function. |
479 Node* inner_context = BuildLocalFunctionContext(function_context_.get()); | 484 Node* inner_context = |
| 485 BuildLocalFunctionContext(function_context_.get(), patched_receiver); |
480 ContextScope top_context(this, scope, inner_context); | 486 ContextScope top_context(this, scope, inner_context); |
481 CreateGraphBody(stack_check); | 487 CreateGraphBody(stack_check); |
482 } else { | 488 } else { |
483 // Simply use the outer function context in building the graph. | 489 // Simply use the outer function context in building the graph. |
484 CreateGraphBody(stack_check); | 490 CreateGraphBody(stack_check); |
485 } | 491 } |
486 | 492 |
487 // Finish the basic structure of the graph. | 493 // Finish the basic structure of the graph. |
488 graph()->SetEnd(graph()->NewNode(common()->End(), exit_control())); | 494 graph()->SetEnd(graph()->NewNode(common()->End(), exit_control())); |
489 | 495 |
(...skipping 1651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2141 if (possibly_eval && args->length() > 0) { | 2147 if (possibly_eval && args->length() > 0) { |
2142 int arg_count = args->length(); | 2148 int arg_count = args->length(); |
2143 | 2149 |
2144 // Extract callee and source string from the environment. | 2150 // Extract callee and source string from the environment. |
2145 Node* callee = environment()->Peek(arg_count + 1); | 2151 Node* callee = environment()->Peek(arg_count + 1); |
2146 Node* source = environment()->Peek(arg_count - 1); | 2152 Node* source = environment()->Peek(arg_count - 1); |
2147 | 2153 |
2148 // Create node to ask for help resolving potential eval call. This will | 2154 // Create node to ask for help resolving potential eval call. This will |
2149 // provide a fully resolved callee and the corresponding receiver. | 2155 // provide a fully resolved callee and the corresponding receiver. |
2150 Node* function = GetFunctionClosure(); | 2156 Node* function = GetFunctionClosure(); |
2151 Node* receiver = environment()->Lookup(info()->scope()->receiver()); | 2157 // TODO(wingo): ResolvePossibleDirectEval doesn't really need a receiver, |
| 2158 // now that eval scopes don't have "this" declarations. Remove this hack |
| 2159 // once ResolvePossibleDirectEval changes. |
| 2160 Node* receiver; |
| 2161 { |
| 2162 Variable* variable = info()->scope()->LookupThis(); |
| 2163 if (variable->IsStackAllocated()) { |
| 2164 receiver = environment()->Lookup(variable); |
| 2165 } else { |
| 2166 DCHECK(variable->IsContextSlot()); |
| 2167 int depth = current_scope()->ContextChainLength(variable->scope()); |
| 2168 bool immutable = variable->maybe_assigned() == kNotAssigned; |
| 2169 const Operator* op = |
| 2170 javascript()->LoadContext(depth, variable->index(), immutable); |
| 2171 receiver = NewNode(op, current_context()); |
| 2172 } |
| 2173 } |
2152 Node* language = jsgraph()->Constant(language_mode()); | 2174 Node* language = jsgraph()->Constant(language_mode()); |
2153 Node* position = jsgraph()->Constant(info()->scope()->start_position()); | 2175 Node* position = jsgraph()->Constant(info()->scope()->start_position()); |
2154 const Operator* op = | 2176 const Operator* op = |
2155 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); | 2177 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); |
2156 Node* pair = | 2178 Node* pair = |
2157 NewNode(op, callee, source, function, receiver, language, position); | 2179 NewNode(op, callee, source, function, receiver, language, position); |
2158 PrepareFrameState(pair, expr->EvalOrLookupId(), | 2180 PrepareFrameState(pair, expr->EvalOrLookupId(), |
2159 OutputFrameStateCombine::PokeAt(arg_count + 1)); | 2181 OutputFrameStateCombine::PokeAt(arg_count + 1)); |
2160 Node* new_callee = NewNode(common()->Projection(0), pair); | 2182 Node* new_callee = NewNode(common()->Projection(0), pair); |
2161 Node* new_receiver = NewNode(common()->Projection(1), pair); | 2183 Node* new_receiver = NewNode(common()->Projection(1), pair); |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2633 receiver_check.Then(); | 2655 receiver_check.Then(); |
2634 Node* proxy = BuildLoadGlobalProxy(); | 2656 Node* proxy = BuildLoadGlobalProxy(); |
2635 environment()->Push(proxy); | 2657 environment()->Push(proxy); |
2636 receiver_check.Else(); | 2658 receiver_check.Else(); |
2637 environment()->Push(receiver); | 2659 environment()->Push(receiver); |
2638 receiver_check.End(); | 2660 receiver_check.End(); |
2639 return environment()->Pop(); | 2661 return environment()->Pop(); |
2640 } | 2662 } |
2641 | 2663 |
2642 | 2664 |
2643 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context) { | 2665 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, |
| 2666 Node* patched_receiver) { |
| 2667 Scope* scope = info()->scope(); |
2644 Node* closure = GetFunctionClosure(); | 2668 Node* closure = GetFunctionClosure(); |
2645 | 2669 |
2646 // Allocate a new local context. | 2670 // Allocate a new local context. |
2647 Node* local_context = | 2671 Node* local_context = |
2648 info()->scope()->is_script_scope() | 2672 scope->is_script_scope() |
2649 ? BuildLocalScriptContext(info()->scope()) | 2673 ? BuildLocalScriptContext(scope) |
2650 : NewNode(javascript()->CreateFunctionContext(), closure); | 2674 : NewNode(javascript()->CreateFunctionContext(), closure); |
2651 | 2675 |
| 2676 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) { |
| 2677 DCHECK_NOT_NULL(patched_receiver); |
| 2678 // Context variable (at bottom of the context chain). |
| 2679 Variable* variable = scope->receiver(); |
| 2680 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); |
| 2681 const Operator* op = javascript()->StoreContext(0, variable->index()); |
| 2682 NewNode(op, local_context, patched_receiver); |
| 2683 } |
| 2684 |
2652 // Copy parameters into context if necessary. | 2685 // Copy parameters into context if necessary. |
2653 int num_parameters = info()->scope()->num_parameters(); | 2686 int num_parameters = scope->num_parameters(); |
2654 for (int i = 0; i < num_parameters; i++) { | 2687 for (int i = 0; i < num_parameters; i++) { |
2655 Variable* variable = info()->scope()->parameter(i); | 2688 Variable* variable = scope->parameter(i); |
2656 if (!variable->IsContextSlot()) continue; | 2689 if (!variable->IsContextSlot()) continue; |
2657 // Temporary parameter node. The parameter indices are shifted by 1 | 2690 // Temporary parameter node. The parameter indices are shifted by 1 |
2658 // (receiver is parameter index -1 but environment index 0). | 2691 // (receiver is parameter index -1 but environment index 0). |
2659 Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start()); | 2692 Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start()); |
2660 // Context variable (at bottom of the context chain). | 2693 // Context variable (at bottom of the context chain). |
2661 DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope())); | 2694 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); |
2662 const Operator* op = javascript()->StoreContext(0, variable->index()); | 2695 const Operator* op = javascript()->StoreContext(0, variable->index()); |
2663 NewNode(op, local_context, parameter); | 2696 NewNode(op, local_context, parameter); |
2664 } | 2697 } |
2665 | 2698 |
2666 return local_context; | 2699 return local_context; |
2667 } | 2700 } |
2668 | 2701 |
2669 | 2702 |
2670 Node* AstGraphBuilder::BuildLocalScriptContext(Scope* scope) { | 2703 Node* AstGraphBuilder::BuildLocalScriptContext(Scope* scope) { |
2671 Node* closure = GetFunctionClosure(); | 2704 Node* closure = GetFunctionClosure(); |
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3550 // Phi does not exist yet, introduce one. | 3583 // Phi does not exist yet, introduce one. |
3551 value = NewPhi(inputs, value, control); | 3584 value = NewPhi(inputs, value, control); |
3552 value->ReplaceInput(inputs - 1, other); | 3585 value->ReplaceInput(inputs - 1, other); |
3553 } | 3586 } |
3554 return value; | 3587 return value; |
3555 } | 3588 } |
3556 | 3589 |
3557 } // namespace compiler | 3590 } // namespace compiler |
3558 } // namespace internal | 3591 } // namespace internal |
3559 } // namespace v8 | 3592 } // namespace v8 |
OLD | NEW |