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 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 | 463 |
464 // Initialize the incoming context. | 464 // Initialize the incoming context. |
465 CreateFunctionContext(constant_context); | 465 CreateFunctionContext(constant_context); |
466 ContextScope incoming(this, scope, function_context_.get()); | 466 ContextScope incoming(this, scope, function_context_.get()); |
467 | 467 |
468 // Initialize control scope. | 468 // Initialize control scope. |
469 ControlScope control(this); | 469 ControlScope control(this); |
470 | 470 |
471 // Build receiver check for sloppy mode if necessary. | 471 // Build receiver check for sloppy mode if necessary. |
472 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? | 472 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? |
473 Node* original_receiver = env.Lookup(scope->receiver()); | 473 Node* patched_receiver = nullptr; |
474 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); | 474 if (scope->has_this_declaration()) { |
475 env.Bind(scope->receiver(), patched_receiver); | 475 Node* original_receiver = NewNode(common()->Parameter(0), graph()->start()); |
| 476 patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); |
| 477 if (scope->receiver()->IsStackAllocated()) { |
| 478 env.Bind(scope->receiver(), patched_receiver); |
| 479 } |
| 480 } |
476 | 481 |
477 // Build function context only if there are context allocated variables. | 482 // Build function context only if there are context allocated variables. |
478 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 483 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
479 if (heap_slots > 0) { | 484 if (heap_slots > 0) { |
480 // Push a new inner context scope for the function. | 485 // Push a new inner context scope for the function. |
481 Node* inner_context = BuildLocalFunctionContext(function_context_.get()); | 486 Node* inner_context = |
| 487 BuildLocalFunctionContext(function_context_.get(), patched_receiver); |
482 ContextScope top_context(this, scope, inner_context); | 488 ContextScope top_context(this, scope, inner_context); |
483 CreateGraphBody(stack_check); | 489 CreateGraphBody(stack_check); |
484 } else { | 490 } else { |
485 // Simply use the outer function context in building the graph. | 491 // Simply use the outer function context in building the graph. |
486 CreateGraphBody(stack_check); | 492 CreateGraphBody(stack_check); |
487 } | 493 } |
488 | 494 |
489 // Finish the basic structure of the graph. | 495 // Finish the basic structure of the graph. |
490 graph()->SetEnd(graph()->NewNode(common()->End(), exit_control())); | 496 graph()->SetEnd(graph()->NewNode(common()->End(), exit_control())); |
491 | 497 |
(...skipping 1668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2160 if (possibly_eval && args->length() > 0) { | 2166 if (possibly_eval && args->length() > 0) { |
2161 int arg_count = args->length(); | 2167 int arg_count = args->length(); |
2162 | 2168 |
2163 // Extract callee and source string from the environment. | 2169 // Extract callee and source string from the environment. |
2164 Node* callee = environment()->Peek(arg_count + 1); | 2170 Node* callee = environment()->Peek(arg_count + 1); |
2165 Node* source = environment()->Peek(arg_count - 1); | 2171 Node* source = environment()->Peek(arg_count - 1); |
2166 | 2172 |
2167 // Create node to ask for help resolving potential eval call. This will | 2173 // Create node to ask for help resolving potential eval call. This will |
2168 // provide a fully resolved callee and the corresponding receiver. | 2174 // provide a fully resolved callee and the corresponding receiver. |
2169 Node* function = GetFunctionClosure(); | 2175 Node* function = GetFunctionClosure(); |
2170 Node* receiver = environment()->Lookup(info()->scope()->receiver()); | 2176 // TODO(wingo): ResolvePossibleDirectEval doesn't really need a receiver, |
| 2177 // now that eval scopes don't have "this" declarations. Remove this hack |
| 2178 // once ResolvePossibleDirectEval changes. |
| 2179 Node* receiver; |
| 2180 { |
| 2181 Variable* variable = info()->scope()->LookupThis(); |
| 2182 if (variable->IsStackAllocated()) { |
| 2183 receiver = environment()->Lookup(variable); |
| 2184 } else { |
| 2185 DCHECK(variable->IsContextSlot()); |
| 2186 int depth = current_scope()->ContextChainLength(variable->scope()); |
| 2187 bool immutable = variable->maybe_assigned() == kNotAssigned; |
| 2188 const Operator* op = |
| 2189 javascript()->LoadContext(depth, variable->index(), immutable); |
| 2190 receiver = NewNode(op, current_context()); |
| 2191 } |
| 2192 } |
2171 Node* language = jsgraph()->Constant(language_mode()); | 2193 Node* language = jsgraph()->Constant(language_mode()); |
2172 Node* position = jsgraph()->Constant(info()->scope()->start_position()); | 2194 Node* position = jsgraph()->Constant(info()->scope()->start_position()); |
2173 const Operator* op = | 2195 const Operator* op = |
2174 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); | 2196 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); |
2175 Node* pair = | 2197 Node* pair = |
2176 NewNode(op, callee, source, function, receiver, language, position); | 2198 NewNode(op, callee, source, function, receiver, language, position); |
2177 PrepareFrameState(pair, expr->EvalOrLookupId(), | 2199 PrepareFrameState(pair, expr->EvalOrLookupId(), |
2178 OutputFrameStateCombine::PokeAt(arg_count + 1)); | 2200 OutputFrameStateCombine::PokeAt(arg_count + 1)); |
2179 Node* new_callee = NewNode(common()->Projection(0), pair); | 2201 Node* new_callee = NewNode(common()->Projection(0), pair); |
2180 Node* new_receiver = NewNode(common()->Projection(1), pair); | 2202 Node* new_receiver = NewNode(common()->Projection(1), pair); |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2651 receiver_check.Then(); | 2673 receiver_check.Then(); |
2652 Node* proxy = BuildLoadGlobalProxy(); | 2674 Node* proxy = BuildLoadGlobalProxy(); |
2653 environment()->Push(proxy); | 2675 environment()->Push(proxy); |
2654 receiver_check.Else(); | 2676 receiver_check.Else(); |
2655 environment()->Push(receiver); | 2677 environment()->Push(receiver); |
2656 receiver_check.End(); | 2678 receiver_check.End(); |
2657 return environment()->Pop(); | 2679 return environment()->Pop(); |
2658 } | 2680 } |
2659 | 2681 |
2660 | 2682 |
2661 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context) { | 2683 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, |
| 2684 Node* patched_receiver) { |
| 2685 Scope* scope = info()->scope(); |
2662 Node* closure = GetFunctionClosure(); | 2686 Node* closure = GetFunctionClosure(); |
2663 | 2687 |
2664 // Allocate a new local context. | 2688 // Allocate a new local context. |
2665 Node* local_context = | 2689 Node* local_context = |
2666 info()->scope()->is_script_scope() | 2690 scope->is_script_scope() |
2667 ? BuildLocalScriptContext(info()->scope()) | 2691 ? BuildLocalScriptContext(scope) |
2668 : NewNode(javascript()->CreateFunctionContext(), closure); | 2692 : NewNode(javascript()->CreateFunctionContext(), closure); |
2669 | 2693 |
| 2694 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) { |
| 2695 DCHECK_NOT_NULL(patched_receiver); |
| 2696 // Context variable (at bottom of the context chain). |
| 2697 Variable* variable = scope->receiver(); |
| 2698 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); |
| 2699 const Operator* op = javascript()->StoreContext(0, variable->index()); |
| 2700 NewNode(op, local_context, patched_receiver); |
| 2701 } |
| 2702 |
2670 // Copy parameters into context if necessary. | 2703 // Copy parameters into context if necessary. |
2671 int num_parameters = info()->scope()->num_parameters(); | 2704 int num_parameters = scope->num_parameters(); |
2672 for (int i = 0; i < num_parameters; i++) { | 2705 for (int i = 0; i < num_parameters; i++) { |
2673 Variable* variable = info()->scope()->parameter(i); | 2706 Variable* variable = scope->parameter(i); |
2674 if (!variable->IsContextSlot()) continue; | 2707 if (!variable->IsContextSlot()) continue; |
2675 // Temporary parameter node. The parameter indices are shifted by 1 | 2708 // Temporary parameter node. The parameter indices are shifted by 1 |
2676 // (receiver is parameter index -1 but environment index 0). | 2709 // (receiver is parameter index -1 but environment index 0). |
2677 Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start()); | 2710 Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start()); |
2678 // Context variable (at bottom of the context chain). | 2711 // Context variable (at bottom of the context chain). |
2679 DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope())); | 2712 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); |
2680 const Operator* op = javascript()->StoreContext(0, variable->index()); | 2713 const Operator* op = javascript()->StoreContext(0, variable->index()); |
2681 NewNode(op, local_context, parameter); | 2714 NewNode(op, local_context, parameter); |
2682 } | 2715 } |
2683 | 2716 |
2684 return local_context; | 2717 return local_context; |
2685 } | 2718 } |
2686 | 2719 |
2687 | 2720 |
2688 Node* AstGraphBuilder::BuildLocalScriptContext(Scope* scope) { | 2721 Node* AstGraphBuilder::BuildLocalScriptContext(Scope* scope) { |
2689 Node* closure = GetFunctionClosure(); | 2722 Node* closure = GetFunctionClosure(); |
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3568 // Phi does not exist yet, introduce one. | 3601 // Phi does not exist yet, introduce one. |
3569 value = NewPhi(inputs, value, control); | 3602 value = NewPhi(inputs, value, control); |
3570 value->ReplaceInput(inputs - 1, other); | 3603 value->ReplaceInput(inputs - 1, other); |
3571 } | 3604 } |
3572 return value; | 3605 return value; |
3573 } | 3606 } |
3574 | 3607 |
3575 } // namespace compiler | 3608 } // namespace compiler |
3576 } // namespace internal | 3609 } // namespace internal |
3577 } // namespace v8 | 3610 } // namespace v8 |
OLD | NEW |