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

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

Issue 1136073002: Resolve references to "this" the same way as normal variables (Closed) Base URL: https://chromium.googlesource.com/v8/v8@master
Patch Set: "this" should never be looked up dynamically 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 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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