Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: src/compiler/ast-graph-builder.cc

Issue 1136883006: Reapply "Resolve references to "this" the same way as normal variables"" (Closed) Base URL: https://chromium.googlesource.com/v8/v8@master
Patch Set: Fix this reference in super call, fix "this" in debug evaluator Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/contexts.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 494 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 505
506 // Initialize the incoming context. 506 // Initialize the incoming context.
507 CreateFunctionContext(constant_context); 507 CreateFunctionContext(constant_context);
508 ContextScope incoming(this, scope, function_context_.get()); 508 ContextScope incoming(this, scope, function_context_.get());
509 509
510 // Initialize control scope. 510 // Initialize control scope.
511 ControlScope control(this); 511 ControlScope control(this);
512 512
513 // Build receiver check for sloppy mode if necessary. 513 // Build receiver check for sloppy mode if necessary.
514 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? 514 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
515 Node* original_receiver = env.Lookup(scope->receiver()); 515 Node* patched_receiver = nullptr;
516 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); 516 if (scope->has_this_declaration()) {
517 env.Bind(scope->receiver(), patched_receiver); 517 Node* original_receiver = NewNode(common()->Parameter(0), graph()->start());
518 patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver);
519 if (scope->receiver()->IsStackAllocated()) {
520 env.Bind(scope->receiver(), patched_receiver);
521 }
522 }
518 523
519 // Build function context only if there are context allocated variables. 524 // Build function context only if there are context allocated variables.
520 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 525 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
521 if (heap_slots > 0) { 526 if (heap_slots > 0) {
522 // Push a new inner context scope for the function. 527 // Push a new inner context scope for the function.
523 Node* inner_context = BuildLocalFunctionContext(function_context_.get()); 528 Node* inner_context =
529 BuildLocalFunctionContext(function_context_.get(), patched_receiver);
524 ContextScope top_context(this, scope, inner_context); 530 ContextScope top_context(this, scope, inner_context);
525 CreateGraphBody(stack_check); 531 CreateGraphBody(stack_check);
526 } else { 532 } else {
527 // Simply use the outer function context in building the graph. 533 // Simply use the outer function context in building the graph.
528 CreateGraphBody(stack_check); 534 CreateGraphBody(stack_check);
529 } 535 }
530 536
531 // Finish the basic structure of the graph. 537 // Finish the basic structure of the graph.
532 graph()->SetEnd(graph()->NewNode(common()->End(), exit_control())); 538 graph()->SetEnd(graph()->NewNode(common()->End(), exit_control()));
533 539
(...skipping 1710 matching lines...) Expand 10 before | Expand all | Expand 10 after
2244 if (possibly_eval && args->length() > 0) { 2250 if (possibly_eval && args->length() > 0) {
2245 int arg_count = args->length(); 2251 int arg_count = args->length();
2246 2252
2247 // Extract callee and source string from the environment. 2253 // Extract callee and source string from the environment.
2248 Node* callee = environment()->Peek(arg_count + 1); 2254 Node* callee = environment()->Peek(arg_count + 1);
2249 Node* source = environment()->Peek(arg_count - 1); 2255 Node* source = environment()->Peek(arg_count - 1);
2250 2256
2251 // Create node to ask for help resolving potential eval call. This will 2257 // Create node to ask for help resolving potential eval call. This will
2252 // provide a fully resolved callee and the corresponding receiver. 2258 // provide a fully resolved callee and the corresponding receiver.
2253 Node* function = GetFunctionClosure(); 2259 Node* function = GetFunctionClosure();
2254 Node* receiver = environment()->Lookup(info()->scope()->receiver()); 2260 // TODO(wingo): ResolvePossibleDirectEval doesn't really need a receiver,
2261 // now that eval scopes don't have "this" declarations. Remove this hack
2262 // once ResolvePossibleDirectEval changes.
2263 Node* receiver;
2264 {
2265 Variable* variable = info()->scope()->LookupThis();
2266 if (variable->IsStackAllocated()) {
2267 receiver = environment()->Lookup(variable);
2268 } else {
2269 DCHECK(variable->IsContextSlot());
2270 int depth = current_scope()->ContextChainLength(variable->scope());
2271 bool immutable = variable->maybe_assigned() == kNotAssigned;
2272 const Operator* op =
2273 javascript()->LoadContext(depth, variable->index(), immutable);
2274 receiver = NewNode(op, current_context());
2275 }
2276 }
2255 Node* language = jsgraph()->Constant(language_mode()); 2277 Node* language = jsgraph()->Constant(language_mode());
2256 Node* position = jsgraph()->Constant(info()->scope()->start_position()); 2278 Node* position = jsgraph()->Constant(info()->scope()->start_position());
2257 const Operator* op = 2279 const Operator* op =
2258 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); 2280 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6);
2259 Node* pair = 2281 Node* pair =
2260 NewNode(op, callee, source, function, receiver, language, position); 2282 NewNode(op, callee, source, function, receiver, language, position);
2261 PrepareFrameState(pair, expr->EvalOrLookupId(), 2283 PrepareFrameState(pair, expr->EvalOrLookupId(),
2262 OutputFrameStateCombine::PokeAt(arg_count + 1)); 2284 OutputFrameStateCombine::PokeAt(arg_count + 1));
2263 Node* new_callee = NewNode(common()->Projection(0), pair); 2285 Node* new_callee = NewNode(common()->Projection(0), pair);
2264 Node* new_receiver = NewNode(common()->Projection(1), pair); 2286 Node* new_receiver = NewNode(common()->Projection(1), pair);
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
2724 return value; 2746 return value;
2725 } 2747 }
2726 2748
2727 2749
2728 Node* AstGraphBuilder::BuildPatchReceiverToGlobalProxy(Node* receiver) { 2750 Node* AstGraphBuilder::BuildPatchReceiverToGlobalProxy(Node* receiver) {
2729 // Sloppy mode functions and builtins need to replace the receiver with the 2751 // Sloppy mode functions and builtins need to replace the receiver with the
2730 // global proxy when called as functions (without an explicit receiver 2752 // global proxy when called as functions (without an explicit receiver
2731 // object). Otherwise there is nothing left to do here. 2753 // object). Otherwise there is nothing left to do here.
2732 if (is_strict(language_mode()) || info()->is_native()) return receiver; 2754 if (is_strict(language_mode()) || info()->is_native()) return receiver;
2733 2755
2734 // There is no need to perform patching if the receiver is never used. Note 2756 // There is no need to perform patching if the receiver will never be used.
2735 // that scope predicates are purely syntactical, a call to eval might still
2736 // inspect the receiver value.
2737 if (!info()->MayUseThis()) return receiver; 2757 if (!info()->MayUseThis()) return receiver;
2738 2758
2739 IfBuilder receiver_check(this); 2759 IfBuilder receiver_check(this);
2740 Node* undefined = jsgraph()->UndefinedConstant(); 2760 Node* undefined = jsgraph()->UndefinedConstant();
2741 Node* check = NewNode(javascript()->StrictEqual(), receiver, undefined); 2761 Node* check = NewNode(javascript()->StrictEqual(), receiver, undefined);
2742 receiver_check.If(check); 2762 receiver_check.If(check);
2743 receiver_check.Then(); 2763 receiver_check.Then();
2744 Node* proxy = BuildLoadGlobalProxy(); 2764 Node* proxy = BuildLoadGlobalProxy();
2745 environment()->Push(proxy); 2765 environment()->Push(proxy);
2746 receiver_check.Else(); 2766 receiver_check.Else();
2747 environment()->Push(receiver); 2767 environment()->Push(receiver);
2748 receiver_check.End(); 2768 receiver_check.End();
2749 return environment()->Pop(); 2769 return environment()->Pop();
2750 } 2770 }
2751 2771
2752 2772
2753 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context) { 2773 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context,
2774 Node* patched_receiver) {
2775 Scope* scope = info()->scope();
2754 Node* closure = GetFunctionClosure(); 2776 Node* closure = GetFunctionClosure();
2755 2777
2756 // Allocate a new local context. 2778 // Allocate a new local context.
2757 Node* local_context = 2779 Node* local_context =
2758 info()->scope()->is_script_scope() 2780 scope->is_script_scope()
2759 ? BuildLocalScriptContext(info()->scope()) 2781 ? BuildLocalScriptContext(scope)
2760 : NewNode(javascript()->CreateFunctionContext(), closure); 2782 : NewNode(javascript()->CreateFunctionContext(), closure);
2761 2783
2784 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) {
2785 DCHECK_NOT_NULL(patched_receiver);
2786 // Context variable (at bottom of the context chain).
2787 Variable* variable = scope->receiver();
2788 DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
2789 const Operator* op = javascript()->StoreContext(0, variable->index());
2790 NewNode(op, local_context, patched_receiver);
2791 }
2792
2762 // Copy parameters into context if necessary. 2793 // Copy parameters into context if necessary.
2763 int num_parameters = info()->scope()->num_parameters(); 2794 int num_parameters = scope->num_parameters();
2764 for (int i = 0; i < num_parameters; i++) { 2795 for (int i = 0; i < num_parameters; i++) {
2765 Variable* variable = info()->scope()->parameter(i); 2796 Variable* variable = scope->parameter(i);
2766 if (!variable->IsContextSlot()) continue; 2797 if (!variable->IsContextSlot()) continue;
2767 // Temporary parameter node. The parameter indices are shifted by 1 2798 // Temporary parameter node. The parameter indices are shifted by 1
2768 // (receiver is parameter index -1 but environment index 0). 2799 // (receiver is parameter index -1 but environment index 0).
2769 Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start()); 2800 Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start());
2770 // Context variable (at bottom of the context chain). 2801 // Context variable (at bottom of the context chain).
2771 DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope())); 2802 DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
2772 const Operator* op = javascript()->StoreContext(0, variable->index()); 2803 const Operator* op = javascript()->StoreContext(0, variable->index());
2773 NewNode(op, local_context, parameter); 2804 NewNode(op, local_context, parameter);
2774 } 2805 }
2775 2806
2776 return local_context; 2807 return local_context;
2777 } 2808 }
2778 2809
2779 2810
2780 Node* AstGraphBuilder::BuildLocalScriptContext(Scope* scope) { 2811 Node* AstGraphBuilder::BuildLocalScriptContext(Scope* scope) {
2781 Node* closure = GetFunctionClosure(); 2812 Node* closure = GetFunctionClosure();
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after
3649 // Phi does not exist yet, introduce one. 3680 // Phi does not exist yet, introduce one.
3650 value = NewPhi(inputs, value, control); 3681 value = NewPhi(inputs, value, control);
3651 value->ReplaceInput(inputs - 1, other); 3682 value->ReplaceInput(inputs - 1, other);
3652 } 3683 }
3653 return value; 3684 return value;
3654 } 3685 }
3655 3686
3656 } // namespace compiler 3687 } // namespace compiler
3657 } // namespace internal 3688 } // namespace internal
3658 } // namespace v8 3689 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/contexts.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698