@@ -470,15 +470,21 @@ bool AstGraphBuilder::CreateGraph(bool constant_context, bool stack_check) {
470470
471471 // Build receiver check for sloppy mode if necessary.
472472 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
473- Node* original_receiver = env.Lookup (scope->receiver ());
474- Node* patched_receiver = BuildPatchReceiverToGlobalProxy (original_receiver);
475- env.Bind (scope->receiver (), patched_receiver);
473+ Node* patched_receiver = nullptr ;
474+ if (scope->has_this_declaration ()) {
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+ }
476481
477482 // Build function context only if there are context allocated variables.
478483 int heap_slots = info ()->num_heap_slots () - Context::MIN_CONTEXT_SLOTS ;
479484 if (heap_slots > 0 ) {
480485 // 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);
482488 ContextScope top_context (this , scope, inner_context);
483489 CreateGraphBody (stack_check);
484490 } else {
@@ -2167,7 +2173,23 @@ void AstGraphBuilder::VisitCall(Call* expr) {
21672173 // Create node to ask for help resolving potential eval call. This will
21682174 // provide a fully resolved callee and the corresponding receiver.
21692175 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+ }
21712193 Node* language = jsgraph ()->Constant (language_mode ());
21722194 Node* position = jsgraph ()->Constant (info ()->scope ()->start_position ());
21732195 const Operator* op =
@@ -2658,25 +2680,36 @@ Node* AstGraphBuilder::BuildPatchReceiverToGlobalProxy(Node* receiver) {
26582680}
26592681
26602682
2661- Node* AstGraphBuilder::BuildLocalFunctionContext (Node* context) {
2683+ Node* AstGraphBuilder::BuildLocalFunctionContext (Node* context,
2684+ Node* patched_receiver) {
2685+ Scope* scope = info ()->scope ();
26622686 Node* closure = GetFunctionClosure ();
26632687
26642688 // Allocate a new local context.
26652689 Node* local_context =
2666- info ()-> scope () ->is_script_scope ()
2667- ? BuildLocalScriptContext (info ()-> scope () )
2690+ scope->is_script_scope ()
2691+ ? BuildLocalScriptContext (scope)
26682692 : NewNode (javascript ()->CreateFunctionContext (), closure);
26692693
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+
26702703 // Copy parameters into context if necessary.
2671- int num_parameters = info ()-> scope () ->num_parameters ();
2704+ int num_parameters = scope->num_parameters ();
26722705 for (int i = 0 ; i < num_parameters; i++) {
2673- Variable* variable = info ()-> scope () ->parameter (i);
2706+ Variable* variable = scope->parameter (i);
26742707 if (!variable->IsContextSlot ()) continue ;
26752708 // Temporary parameter node. The parameter indices are shifted by 1
26762709 // (receiver is parameter index -1 but environment index 0).
26772710 Node* parameter = NewNode (common ()->Parameter (i + 1 ), graph ()->start ());
26782711 // 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 ()));
26802713 const Operator* op = javascript ()->StoreContext (0 , variable->index ());
26812714 NewNode (op, local_context, parameter);
26822715 }
0 commit comments