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 |