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

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

Issue 1097283003: Resolve references to "this" the same way as normal variables (Closed) Base URL: https://chromium.googlesource.com/v8/v8@master
Patch Set: Created 5 years, 8 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 | « no previous file | 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 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
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()) {
472 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); 472 Node* original_receiver = env.Lookup(scope->receiver());
473 env.Bind(scope->receiver(), patched_receiver); 473 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver);
474 env.Bind(scope->receiver(), patched_receiver);
475 }
474 476
475 // Build function context only if there are context allocated variables. 477 // Build function context only if there are context allocated variables.
476 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 478 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
477 if (heap_slots > 0) { 479 if (heap_slots > 0) {
478 // Push a new inner context scope for the function. 480 // Push a new inner context scope for the function.
479 Node* inner_context = BuildLocalFunctionContext(function_context_.get()); 481 Node* inner_context = BuildLocalFunctionContext(function_context_.get());
480 ContextScope top_context(this, scope, inner_context); 482 ContextScope top_context(this, scope, inner_context);
481 CreateGraphBody(stack_check); 483 CreateGraphBody(stack_check);
482 } else { 484 } else {
483 // Simply use the outer function context in building the graph. 485 // Simply use the outer function context in building the graph.
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 // Split the liveness blocks. 634 // Split the liveness blocks.
633 copy->liveness_block_ = 635 copy->liveness_block_ =
634 builder_->liveness_analyzer()->NewBlock(copy->liveness_block()); 636 builder_->liveness_analyzer()->NewBlock(copy->liveness_block());
635 liveness_block_ = 637 liveness_block_ =
636 builder_->liveness_analyzer()->NewBlock(copy->liveness_block()); 638 builder_->liveness_analyzer()->NewBlock(copy->liveness_block());
637 } 639 }
638 } 640 }
639 641
640 642
641 void AstGraphBuilder::Environment::Bind(Variable* variable, Node* node) { 643 void AstGraphBuilder::Environment::Bind(Variable* variable, Node* node) {
644 // "this" may be context-allocated, but it's possible for us to look it up and
645 // patch it on the stack before it has been hoisted to the context.
646 if (variable->is_this()) {
Michael Starzinger 2015/04/21 18:13:44 AFAICT, this is only needed for patching the recei
wingo 2015/04/22 08:04:00 I had tried to do that, but I couldn't get at envi
Michael Starzinger 2015/04/22 10:59:21 Yes, I think for patching purposes Parameter(0) is
647 values()->at(0) = node;
648 return;
649 }
650
642 DCHECK(variable->IsStackAllocated()); 651 DCHECK(variable->IsStackAllocated());
643 if (variable->IsParameter()) { 652 if (variable->IsParameter()) {
644 // The parameter indices are shifted by 1 (receiver is parameter 653 // The parameter indices are shifted by 1 (receiver is parameter
645 // index -1 but environment index 0). 654 // index -1 but environment index 0).
646 values()->at(variable->index() + 1) = node; 655 values()->at(variable->index() + 1) = node;
647 } else { 656 } else {
648 DCHECK(variable->IsStackLocal()); 657 DCHECK(variable->IsStackLocal());
649 values()->at(variable->index() + parameters_count_) = node; 658 values()->at(variable->index() + parameters_count_) = node;
650 if (FLAG_analyze_environment_liveness) { 659 if (FLAG_analyze_environment_liveness) {
651 liveness_block()->Bind(variable->index()); 660 liveness_block()->Bind(variable->index());
652 } 661 }
653 } 662 }
654 } 663 }
655 664
656 665
657 Node* AstGraphBuilder::Environment::Lookup(Variable* variable) { 666 Node* AstGraphBuilder::Environment::Lookup(Variable* variable) {
667 // "this" may be context-allocated, but it's possible for us to look it up and
668 // patch it on the stack before it has been hoisted to the context.
669 if (variable->is_this()) {
Michael Starzinger 2015/04/21 18:13:44 Likewise.
wingo 2015/04/22 08:04:00 Acknowledged.
670 return values()->at(0);
671 }
672
658 DCHECK(variable->IsStackAllocated()); 673 DCHECK(variable->IsStackAllocated());
659 if (variable->IsParameter()) { 674 if (variable->IsParameter()) {
660 // The parameter indices are shifted by 1 (receiver is parameter 675 // The parameter indices are shifted by 1 (receiver is parameter
661 // index -1 but environment index 0). 676 // index -1 but environment index 0).
662 return values()->at(variable->index() + 1); 677 return values()->at(variable->index() + 1);
663 } else { 678 } else {
664 DCHECK(variable->IsStackLocal()); 679 DCHECK(variable->IsStackLocal());
665 if (FLAG_analyze_environment_liveness) { 680 if (FLAG_analyze_environment_liveness) {
666 liveness_block()->Lookup(variable->index()); 681 liveness_block()->Lookup(variable->index());
667 } 682 }
(...skipping 1473 matching lines...) Expand 10 before | Expand all | Expand 10 after
2141 if (possibly_eval && args->length() > 0) { 2156 if (possibly_eval && args->length() > 0) {
2142 int arg_count = args->length(); 2157 int arg_count = args->length();
2143 2158
2144 // Extract callee and source string from the environment. 2159 // Extract callee and source string from the environment.
2145 Node* callee = environment()->Peek(arg_count + 1); 2160 Node* callee = environment()->Peek(arg_count + 1);
2146 Node* source = environment()->Peek(arg_count - 1); 2161 Node* source = environment()->Peek(arg_count - 1);
2147 2162
2148 // Create node to ask for help resolving potential eval call. This will 2163 // Create node to ask for help resolving potential eval call. This will
2149 // provide a fully resolved callee and the corresponding receiver. 2164 // provide a fully resolved callee and the corresponding receiver.
2150 Node* function = GetFunctionClosure(); 2165 Node* function = GetFunctionClosure();
2151 Node* receiver = environment()->Lookup(info()->scope()->receiver()); 2166 Node* receiver = environment()->Lookup(info()->scope()->LookupThis());
2152 Node* language = jsgraph()->Constant(language_mode()); 2167 Node* language = jsgraph()->Constant(language_mode());
2153 Node* position = jsgraph()->Constant(info()->scope()->start_position()); 2168 Node* position = jsgraph()->Constant(info()->scope()->start_position());
2154 const Operator* op = 2169 const Operator* op =
2155 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); 2170 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6);
2156 Node* pair = 2171 Node* pair =
2157 NewNode(op, callee, source, function, receiver, language, position); 2172 NewNode(op, callee, source, function, receiver, language, position);
2158 PrepareFrameState(pair, expr->EvalOrLookupId(), 2173 PrepareFrameState(pair, expr->EvalOrLookupId(),
2159 OutputFrameStateCombine::PokeAt(arg_count + 1)); 2174 OutputFrameStateCombine::PokeAt(arg_count + 1));
2160 Node* new_callee = NewNode(common()->Projection(0), pair); 2175 Node* new_callee = NewNode(common()->Projection(0), pair);
2161 Node* new_receiver = NewNode(common()->Projection(1), pair); 2176 Node* new_receiver = NewNode(common()->Projection(1), pair);
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
2644 Node* closure = GetFunctionClosure(); 2659 Node* closure = GetFunctionClosure();
2645 2660
2646 // Allocate a new local context. 2661 // Allocate a new local context.
2647 Node* local_context = 2662 Node* local_context =
2648 info()->scope()->is_script_scope() 2663 info()->scope()->is_script_scope()
2649 ? BuildLocalScriptContext(info()->scope()) 2664 ? BuildLocalScriptContext(info()->scope())
2650 : NewNode(javascript()->CreateFunctionContext(), closure); 2665 : NewNode(javascript()->CreateFunctionContext(), closure);
2651 2666
2652 // Copy parameters into context if necessary. 2667 // Copy parameters into context if necessary.
2653 int num_parameters = info()->scope()->num_parameters(); 2668 int num_parameters = info()->scope()->num_parameters();
2654 for (int i = 0; i < num_parameters; i++) { 2669 int first_parameter = info()->scope()->has_this_declaration() ? -1 : 0;
2655 Variable* variable = info()->scope()->parameter(i); 2670 for (int i = first_parameter; i < num_parameters; i++) {
2671 Variable* variable =
2672 (i == -1) ? info()->scope()->receiver() : info()->scope()->parameter(i);
Michael Starzinger 2015/04/21 18:13:44 This is getting out of hand, please hoist handling
2656 if (!variable->IsContextSlot()) continue; 2673 if (!variable->IsContextSlot()) continue;
2657 // Temporary parameter node. The parameter indices are shifted by 1 2674 // Temporary parameter node. The parameter indices are shifted by 1
2658 // (receiver is parameter index -1 but environment index 0). 2675 // (receiver is parameter index -1 but environment index 0).
2659 Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start()); 2676 Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start());
Michael Starzinger 2015/04/21 18:13:44 If the receiver parameter has been patched, then u
wingo 2015/04/22 08:04:00 I see. Thanks, I didn't realize that. Will updat
2660 // Context variable (at bottom of the context chain). 2677 // Context variable (at bottom of the context chain).
2661 DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope())); 2678 DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope()));
2662 const Operator* op = javascript()->StoreContext(0, variable->index()); 2679 const Operator* op = javascript()->StoreContext(0, variable->index());
2663 NewNode(op, local_context, parameter); 2680 NewNode(op, local_context, parameter);
2664 } 2681 }
2665 2682
2666 return local_context; 2683 return local_context;
2667 } 2684 }
2668 2685
2669 2686
(...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after
3550 // Phi does not exist yet, introduce one. 3567 // Phi does not exist yet, introduce one.
3551 value = NewPhi(inputs, value, control); 3568 value = NewPhi(inputs, value, control);
3552 value->ReplaceInput(inputs - 1, other); 3569 value->ReplaceInput(inputs - 1, other);
3553 } 3570 }
3554 return value; 3571 return value;
3555 } 3572 }
3556 3573
3557 } // namespace compiler 3574 } // namespace compiler
3558 } // namespace internal 3575 } // namespace internal
3559 } // namespace v8 3576 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/contexts.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698