Chromium Code Reviews| 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 if (scope->has_this_declaration() && scope->receiver()->IsStackAllocated()) { |
| 472 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); | 472 // If the receiver is context-allocated, we patch it in |
| 473 env.Bind(scope->receiver(), patched_receiver); | 473 // BuildLocalFunctionContext. |
| 474 Node* original_receiver = env.Lookup(scope->receiver()); | |
| 475 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); | |
|
Michael Starzinger
2015/04/22 10:59:21
Instead of having two call-sites of BuildPatchRece
Michael Starzinger
2015/04/22 11:17:53
Or alternatively pass the patched_receiver as an a
wingo
2015/04/22 13:05:23
A bit squirrely, but done.
| |
| 476 env.Bind(scope->receiver(), patched_receiver); | |
| 477 } | |
| 474 | 478 |
| 475 // Build function context only if there are context allocated variables. | 479 // Build function context only if there are context allocated variables. |
| 476 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 480 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
| 477 if (heap_slots > 0) { | 481 if (heap_slots > 0) { |
| 478 // Push a new inner context scope for the function. | 482 // Push a new inner context scope for the function. |
| 479 Node* inner_context = BuildLocalFunctionContext(function_context_.get()); | 483 Node* inner_context = BuildLocalFunctionContext(function_context_.get()); |
| 480 ContextScope top_context(this, scope, inner_context); | 484 ContextScope top_context(this, scope, inner_context); |
| 481 CreateGraphBody(stack_check); | 485 CreateGraphBody(stack_check); |
| 482 } else { | 486 } else { |
| 483 // Simply use the outer function context in building the graph. | 487 // Simply use the outer function context in building the graph. |
| (...skipping 1657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2141 if (possibly_eval && args->length() > 0) { | 2145 if (possibly_eval && args->length() > 0) { |
| 2142 int arg_count = args->length(); | 2146 int arg_count = args->length(); |
| 2143 | 2147 |
| 2144 // Extract callee and source string from the environment. | 2148 // Extract callee and source string from the environment. |
| 2145 Node* callee = environment()->Peek(arg_count + 1); | 2149 Node* callee = environment()->Peek(arg_count + 1); |
| 2146 Node* source = environment()->Peek(arg_count - 1); | 2150 Node* source = environment()->Peek(arg_count - 1); |
| 2147 | 2151 |
| 2148 // Create node to ask for help resolving potential eval call. This will | 2152 // Create node to ask for help resolving potential eval call. This will |
| 2149 // provide a fully resolved callee and the corresponding receiver. | 2153 // provide a fully resolved callee and the corresponding receiver. |
| 2150 Node* function = GetFunctionClosure(); | 2154 Node* function = GetFunctionClosure(); |
| 2151 Node* receiver = environment()->Lookup(info()->scope()->receiver()); | 2155 // TODO(wingo): ResolvePossibleDirectEval doesn't really need a receiver, |
| 2156 // now that eval scopes don't have "this" declarations. Remove this hack | |
| 2157 // once ResolvePossibleDirectEval changes. | |
|
Michael Starzinger
2015/04/22 10:59:21
Does this mean that the "receiver" input to Resolv
wingo
2015/04/22 13:05:23
Yes I think so, and the second return value from R
Michael Starzinger
2015/04/22 13:26:19
Woot! That would be the awesomez! :)
| |
| 2158 Node* receiver; | |
| 2159 { | |
| 2160 Variable* variable = info()->scope()->LookupThis(); | |
| 2161 if (variable->IsStackAllocated()) { | |
| 2162 receiver = environment()->Lookup(variable); | |
| 2163 } else { | |
| 2164 DCHECK(variable->IsContextSlot()); | |
| 2165 int depth = current_scope()->ContextChainLength(variable->scope()); | |
| 2166 bool immutable = variable->maybe_assigned() == kNotAssigned; | |
| 2167 const Operator* op = | |
| 2168 javascript()->LoadContext(depth, variable->index(), immutable); | |
| 2169 receiver = NewNode(op, current_context()); | |
| 2170 } | |
| 2171 } | |
| 2152 Node* language = jsgraph()->Constant(language_mode()); | 2172 Node* language = jsgraph()->Constant(language_mode()); |
| 2153 Node* position = jsgraph()->Constant(info()->scope()->start_position()); | 2173 Node* position = jsgraph()->Constant(info()->scope()->start_position()); |
| 2154 const Operator* op = | 2174 const Operator* op = |
| 2155 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); | 2175 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); |
| 2156 Node* pair = | 2176 Node* pair = |
| 2157 NewNode(op, callee, source, function, receiver, language, position); | 2177 NewNode(op, callee, source, function, receiver, language, position); |
| 2158 PrepareFrameState(pair, expr->EvalOrLookupId(), | 2178 PrepareFrameState(pair, expr->EvalOrLookupId(), |
| 2159 OutputFrameStateCombine::PokeAt(arg_count + 1)); | 2179 OutputFrameStateCombine::PokeAt(arg_count + 1)); |
| 2160 Node* new_callee = NewNode(common()->Projection(0), pair); | 2180 Node* new_callee = NewNode(common()->Projection(0), pair); |
| 2161 Node* new_receiver = NewNode(common()->Projection(1), pair); | 2181 Node* new_receiver = NewNode(common()->Projection(1), pair); |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2642 | 2662 |
| 2643 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context) { | 2663 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context) { |
| 2644 Node* closure = GetFunctionClosure(); | 2664 Node* closure = GetFunctionClosure(); |
| 2645 | 2665 |
| 2646 // Allocate a new local context. | 2666 // Allocate a new local context. |
| 2647 Node* local_context = | 2667 Node* local_context = |
| 2648 info()->scope()->is_script_scope() | 2668 info()->scope()->is_script_scope() |
| 2649 ? BuildLocalScriptContext(info()->scope()) | 2669 ? BuildLocalScriptContext(info()->scope()) |
| 2650 : NewNode(javascript()->CreateFunctionContext(), closure); | 2670 : NewNode(javascript()->CreateFunctionContext(), closure); |
| 2651 | 2671 |
| 2672 if (info()->scope()->has_this_declaration() && | |
| 2673 info()->scope()->receiver()->IsContextSlot()) { | |
| 2674 Node* original_receiver = NewNode(common()->Parameter(0), graph()->start()); | |
| 2675 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); | |
| 2676 // Context variable (at bottom of the context chain). | |
| 2677 Variable* variable = info()->scope()->receiver(); | |
| 2678 DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope())); | |
| 2679 const Operator* op = javascript()->StoreContext(0, variable->index()); | |
| 2680 NewNode(op, local_context, patched_receiver); | |
| 2681 } | |
| 2682 | |
| 2652 // Copy parameters into context if necessary. | 2683 // Copy parameters into context if necessary. |
| 2653 int num_parameters = info()->scope()->num_parameters(); | 2684 int num_parameters = info()->scope()->num_parameters(); |
| 2654 for (int i = 0; i < num_parameters; i++) { | 2685 for (int i = 0; i < num_parameters; i++) { |
| 2655 Variable* variable = info()->scope()->parameter(i); | 2686 Variable* variable = info()->scope()->parameter(i); |
| 2656 if (!variable->IsContextSlot()) continue; | 2687 if (!variable->IsContextSlot()) continue; |
| 2657 // Temporary parameter node. The parameter indices are shifted by 1 | 2688 // Temporary parameter node. The parameter indices are shifted by 1 |
| 2658 // (receiver is parameter index -1 but environment index 0). | 2689 // (receiver is parameter index -1 but environment index 0). |
| 2659 Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start()); | 2690 Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start()); |
| 2660 // Context variable (at bottom of the context chain). | 2691 // Context variable (at bottom of the context chain). |
| 2661 DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope())); | 2692 DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope())); |
| (...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3550 // Phi does not exist yet, introduce one. | 3581 // Phi does not exist yet, introduce one. |
| 3551 value = NewPhi(inputs, value, control); | 3582 value = NewPhi(inputs, value, control); |
| 3552 value->ReplaceInput(inputs - 1, other); | 3583 value->ReplaceInput(inputs - 1, other); |
| 3553 } | 3584 } |
| 3554 return value; | 3585 return value; |
| 3555 } | 3586 } |
| 3556 | 3587 |
| 3557 } // namespace compiler | 3588 } // namespace compiler |
| 3558 } // namespace internal | 3589 } // namespace internal |
| 3559 } // namespace v8 | 3590 } // namespace v8 |
| OLD | NEW |