Revert of Fix receiver when calling eval() bound by with scope (patchset #3 id:40001...
authormachenbach <machenbach@chromium.org>
Wed, 24 Jun 2015 19:08:28 +0000 (12:08 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 24 Jun 2015 19:08:35 +0000 (19:08 +0000)
Reason for revert:
[Sheriff] Breaks layout tests. Please fix upstream blink first.
http://build.chromium.org/p/client.v8.fyi/builders/V8-Blink%20Mac/builds/574

Please consider extra blink trybots on a reland.

Original issue's description:
> Fix receiver when calling eval() bound by with scope
>
> Thanks to AndrĂ© Bargull for the report.
>
> BUG=v8:4214
> LOG=N
> R=arv@chromium.org, mstarzinger@chromium.org
>
> Committed: https://crrev.com/3c5f0db3a1768ade68108bf003676ce378d1cbdc
> Cr-Commit-Position: refs/heads/master@{#29259}

TBR=arv@chromium.org,mstarzinger@chromium.org,verwaest@chromium.org,wingo@igalia.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:4214

Review URL: https://codereview.chromium.org/1201273004

Cr-Commit-Position: refs/heads/master@{#29267}

12 files changed:
src/arm/full-codegen-arm.cc
src/arm64/full-codegen-arm64.cc
src/ast.h
src/compiler/ast-graph-builder.cc
src/full-codegen.h
src/ia32/full-codegen-ia32.cc
src/mips/full-codegen-mips.cc
src/mips64/full-codegen-mips64.cc
src/ppc/full-codegen-ppc.cc
src/x64/full-codegen-x64.cc
src/x87/full-codegen-x87.cc
test/mjsunit/regress/regress-4214.js [deleted file]

index fc01336d7c46ca0bdf04e34af89f782c2d3bd76f..6f1f16a9c35c692cfd376055fc5864f0f289ecf2 100644 (file)
@@ -3137,53 +3137,6 @@ void FullCodeGenerator::EmitInitializeThisAfterSuper(
 }
 
 
-// See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
-void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
-  VariableProxy* callee = expr->expression()->AsVariableProxy();
-  if (callee->var()->IsLookupSlot()) {
-    Label slow, done;
-
-    {
-      PreservePositionScope scope(masm()->positions_recorder());
-      // Generate code for loading from variables potentially shadowed
-      // by eval-introduced variables.
-      EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
-    }
-
-    __ bind(&slow);
-    // Call the runtime to find the function to call (returned in r0)
-    // and the object holding it (returned in edx).
-    DCHECK(!context_register().is(r2));
-    __ mov(r2, Operand(callee->name()));
-    __ Push(context_register(), r2);
-    __ CallRuntime(Runtime::kLoadLookupSlot, 2);
-    __ Push(r0, r1);  // Function, receiver.
-    PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
-
-    // If fast case code has been generated, emit code to push the
-    // function and receiver and have the slow path jump around this
-    // code.
-    if (done.is_linked()) {
-      Label call;
-      __ b(&call);
-      __ bind(&done);
-      // Push function.
-      __ push(r0);
-      // The receiver is implicitly the global receiver. Indicate this
-      // by passing the hole to the call function stub.
-      __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
-      __ push(r1);
-      __ bind(&call);
-    }
-  } else {
-    VisitForStackValue(callee);
-    // refEnv.WithBaseObject()
-    __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
-    __ push(r2);  // Reserved receiver slot.
-  }
-}
-
-
 void FullCodeGenerator::VisitCall(Call* expr) {
 #ifdef DEBUG
   // We want to verify that RecordJSReturnSite gets called on all paths
@@ -3203,7 +3156,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
     int arg_count = args->length();
 
     { PreservePositionScope pos_scope(masm()->positions_recorder());
-      PushCalleeAndWithBaseObject(expr);
+      VisitForStackValue(callee);
+      __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
+      __ push(r2);  // Reserved receiver slot.
 
       // Push the arguments.
       for (int i = 0; i < arg_count; i++) {
@@ -3219,7 +3174,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
       // Touch up the stack with the resolved function.
       __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
 
-      PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
+      PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
     }
 
     // Record source position for debugger.
@@ -3236,7 +3191,43 @@ void FullCodeGenerator::VisitCall(Call* expr) {
 
   } else if (call_type == Call::LOOKUP_SLOT_CALL) {
     // Call to a lookup slot (dynamically introduced variable).
-    PushCalleeAndWithBaseObject(expr);
+    VariableProxy* proxy = callee->AsVariableProxy();
+    Label slow, done;
+
+    { PreservePositionScope scope(masm()->positions_recorder());
+      // Generate code for loading from variables potentially shadowed
+      // by eval-introduced variables.
+      EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done);
+    }
+
+    __ bind(&slow);
+    // Call the runtime to find the function to call (returned in r0)
+    // and the object holding it (returned in edx).
+    DCHECK(!context_register().is(r2));
+    __ mov(r2, Operand(proxy->name()));
+    __ Push(context_register(), r2);
+    __ CallRuntime(Runtime::kLoadLookupSlot, 2);
+    __ Push(r0, r1);  // Function, receiver.
+    PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
+
+    // If fast case code has been generated, emit code to push the
+    // function and receiver and have the slow path jump around this
+    // code.
+    if (done.is_linked()) {
+      Label call;
+      __ b(&call);
+      __ bind(&done);
+      // Push function.
+      __ push(r0);
+      // The receiver is implicitly the global receiver. Indicate this
+      // by passing the hole to the call function stub.
+      __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
+      __ push(r1);
+      __ bind(&call);
+    }
+
+    // The receiver is either the global receiver or an object found
+    // by LoadContextSlot.
     EmitCall(expr);
   } else if (call_type == Call::PROPERTY_CALL) {
     Property* property = callee->AsProperty();
index db03ef72a47af38c1b472a43dc603c8f8bc7acb4..93e4d4f51aed3777396b785641212537417c2d5a 100644 (file)
@@ -2829,51 +2829,6 @@ void FullCodeGenerator::EmitInitializeThisAfterSuper(
 }
 
 
-// See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
-void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
-  VariableProxy* callee = expr->expression()->AsVariableProxy();
-  if (callee->var()->IsLookupSlot()) {
-    Label slow, done;
-
-    {
-      PreservePositionScope scope(masm()->positions_recorder());
-      // Generate code for loading from variables potentially shadowed
-      // by eval-introduced variables.
-      EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
-    }
-
-    __ Bind(&slow);
-    // Call the runtime to find the function to call (returned in x0)
-    // and the object holding it (returned in x1).
-    __ Mov(x10, Operand(callee->name()));
-    __ Push(context_register(), x10);
-    __ CallRuntime(Runtime::kLoadLookupSlot, 2);
-    __ Push(x0, x1);  // Receiver, function.
-    PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
-
-    // If fast case code has been generated, emit code to push the
-    // function and receiver and have the slow path jump around this
-    // code.
-    if (done.is_linked()) {
-      Label call;
-      __ B(&call);
-      __ Bind(&done);
-      // Push function.
-      // The receiver is implicitly the global receiver. Indicate this
-      // by passing the undefined to the call function stub.
-      __ LoadRoot(x1, Heap::kUndefinedValueRootIndex);
-      __ Push(x0, x1);
-      __ Bind(&call);
-    }
-  } else {
-    VisitForStackValue(callee);
-    // refEnv.WithBaseObject()
-    __ LoadRoot(x10, Heap::kUndefinedValueRootIndex);
-    __ Push(x10);  // Reserved receiver slot.
-  }
-}
-
-
 void FullCodeGenerator::VisitCall(Call* expr) {
 #ifdef DEBUG
   // We want to verify that RecordJSReturnSite gets called on all paths
@@ -2894,7 +2849,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
 
     {
       PreservePositionScope pos_scope(masm()->positions_recorder());
-      PushCalleeAndWithBaseObject(expr);
+      VisitForStackValue(callee);
+      __ LoadRoot(x10, Heap::kUndefinedValueRootIndex);
+      __ Push(x10);  // Reserved receiver slot.
 
       // Push the arguments.
       for (int i = 0; i < arg_count; i++) {
@@ -2910,7 +2867,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
       // Touch up the stack with the resolved function.
       __ Poke(x0, (arg_count + 1) * kPointerSize);
 
-      PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
+      PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
     }
 
     // Record source position for debugger.
@@ -2930,7 +2887,41 @@ void FullCodeGenerator::VisitCall(Call* expr) {
 
   } else if (call_type == Call::LOOKUP_SLOT_CALL) {
     // Call to a lookup slot (dynamically introduced variable).
-    PushCalleeAndWithBaseObject(expr);
+    VariableProxy* proxy = callee->AsVariableProxy();
+    Label slow, done;
+
+    { PreservePositionScope scope(masm()->positions_recorder());
+      // Generate code for loading from variables potentially shadowed
+      // by eval-introduced variables.
+      EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done);
+    }
+
+    __ Bind(&slow);
+    // Call the runtime to find the function to call (returned in x0)
+    // and the object holding it (returned in x1).
+    __ Mov(x10, Operand(proxy->name()));
+    __ Push(context_register(), x10);
+    __ CallRuntime(Runtime::kLoadLookupSlot, 2);
+    __ Push(x0, x1);  // Receiver, function.
+    PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
+
+    // If fast case code has been generated, emit code to push the
+    // function and receiver and have the slow path jump around this
+    // code.
+    if (done.is_linked()) {
+      Label call;
+      __ B(&call);
+      __ Bind(&done);
+      // Push function.
+      // The receiver is implicitly the global receiver. Indicate this
+      // by passing the undefined to the call function stub.
+      __ LoadRoot(x1, Heap::kUndefinedValueRootIndex);
+      __ Push(x0, x1);
+      __ Bind(&call);
+    }
+
+    // The receiver is either the global receiver or an object found
+    // by LoadContextSlot.
     EmitCall(expr);
   } else if (call_type == Call::PROPERTY_CALL) {
     Property* property = callee->AsProperty();
index 314885be13577d32f32221fc966dad54ac2db541..61a6ea936963bab05811fc36f53a4ca58bc6f308 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -1869,10 +1869,9 @@ class Call final : public Expression {
     allocation_site_ = site;
   }
 
-  static int num_ids() { return parent_num_ids() + 3; }
+  static int num_ids() { return parent_num_ids() + 2; }
   BailoutId ReturnId() const { return BailoutId(local_id(0)); }
-  BailoutId EvalId() const { return BailoutId(local_id(1)); }
-  BailoutId LookupId() const { return BailoutId(local_id(2)); }
+  BailoutId EvalOrLookupId() const { return BailoutId(local_id(1)); }
 
   bool is_uninitialized() const {
     return IsUninitializedField::decode(bit_field_);
index 1848c76cbc76b3d75315b6c6ef41b9072410341f..1147f85a6377c5978b39a5701438d789779b1aab 100644 (file)
@@ -2360,7 +2360,7 @@ void AstGraphBuilder::VisitCall(Call* expr) {
       callee_value = NewNode(common()->Projection(0), pair);
       receiver_value = NewNode(common()->Projection(1), pair);
 
-      PrepareFrameState(pair, expr->LookupId(),
+      PrepareFrameState(pair, expr->EvalOrLookupId(),
                         OutputFrameStateCombine::Push(2));
       break;
     }
@@ -2428,18 +2428,6 @@ void AstGraphBuilder::VisitCall(Call* expr) {
       break;
     case Call::POSSIBLY_EVAL_CALL:
       possibly_eval = true;
-      if (callee->AsVariableProxy()->var()->IsLookupSlot()) {
-        Variable* variable = callee->AsVariableProxy()->var();
-        Node* name = jsgraph()->Constant(variable->name());
-        const Operator* op =
-            javascript()->CallRuntime(Runtime::kLoadLookupSlot, 2);
-        Node* pair = NewNode(op, current_context(), name);
-        callee_value = NewNode(common()->Projection(0), pair);
-        receiver_value = NewNode(common()->Projection(1), pair);
-        PrepareFrameState(pair, expr->LookupId(),
-                          OutputFrameStateCombine::Push(2));
-        break;
-      }
     // Fall through.
     case Call::OTHER_CALL:
       VisitForValue(callee);
@@ -2475,7 +2463,7 @@ void AstGraphBuilder::VisitCall(Call* expr) {
         javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
     Node* new_callee =
         NewNode(op, callee, source, function, language, position);
-    PrepareFrameState(new_callee, expr->EvalId(),
+    PrepareFrameState(new_callee, expr->EvalOrLookupId(),
                       OutputFrameStateCombine::PokeAt(arg_count + 1));
 
     // Patch callee on the environment.
index b9a3d2b078a1c12fbf7b5da79d3476a46870b1a2..f9c3ece937c63ed3c0e006c51454306ec160c974 100644 (file)
@@ -736,8 +736,6 @@ class FullCodeGenerator: public AstVisitor {
   // and PushCatchContext.
   void PushFunctionArgumentForContextAllocation();
 
-  void PushCalleeAndWithBaseObject(Call* expr);
-
   // AST node visit functions.
 #define DECLARE_VISIT(type) virtual void Visit##type(type* node) override;
   AST_NODE_LIST(DECLARE_VISIT)
index a74b785f44a308a1c1b6e268c235639ecc5e184a..56ce46b84294bae032b9db28bb58a6be2305f284 100644 (file)
@@ -3036,48 +3036,6 @@ void FullCodeGenerator::EmitInitializeThisAfterSuper(
 }
 
 
-// See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
-void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
-  VariableProxy* callee = expr->expression()->AsVariableProxy();
-  if (callee->var()->IsLookupSlot()) {
-    Label slow, done;
-    {
-      PreservePositionScope scope(masm()->positions_recorder());
-      // Generate code for loading from variables potentially shadowed by
-      // eval-introduced variables.
-      EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
-    }
-    __ bind(&slow);
-    // Call the runtime to find the function to call (returned in eax) and
-    // the object holding it (returned in edx).
-    __ push(context_register());
-    __ push(Immediate(callee->name()));
-    __ CallRuntime(Runtime::kLoadLookupSlot, 2);
-    __ push(eax);  // Function.
-    __ push(edx);  // Receiver.
-    PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
-
-    // If fast case code has been generated, emit code to push the function
-    // and receiver and have the slow path jump around this code.
-    if (done.is_linked()) {
-      Label call;
-      __ jmp(&call, Label::kNear);
-      __ bind(&done);
-      // Push function.
-      __ push(eax);
-      // The receiver is implicitly the global receiver. Indicate this by
-      // passing the hole to the call function stub.
-      __ push(Immediate(isolate()->factory()->undefined_value()));
-      __ bind(&call);
-    }
-  } else {
-    VisitForStackValue(callee);
-    // refEnv.WithBaseObject()
-    __ push(Immediate(isolate()->factory()->undefined_value()));
-  }
-}
-
-
 void FullCodeGenerator::VisitCall(Call* expr) {
 #ifdef DEBUG
   // We want to verify that RecordJSReturnSite gets called on all paths
@@ -3096,8 +3054,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
     ZoneList<Expression*>* args = expr->arguments();
     int arg_count = args->length();
     { PreservePositionScope pos_scope(masm()->positions_recorder());
-      PushCalleeAndWithBaseObject(expr);
-
+      VisitForStackValue(callee);
+      // Reserved receiver slot.
+      __ push(Immediate(isolate()->factory()->undefined_value()));
       // Push the arguments.
       for (int i = 0; i < arg_count; i++) {
         VisitForStackValue(args->at(i));
@@ -3111,7 +3070,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
       // Touch up the stack with the resolved function.
       __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
 
-      PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
+      PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
     }
     // Record source position for debugger.
     SetSourcePosition(expr->position());
@@ -3127,8 +3086,41 @@ void FullCodeGenerator::VisitCall(Call* expr) {
     EmitCallWithLoadIC(expr);
   } else if (call_type == Call::LOOKUP_SLOT_CALL) {
     // Call to a lookup slot (dynamically introduced variable).
-    PushCalleeAndWithBaseObject(expr);
+    VariableProxy* proxy = callee->AsVariableProxy();
+    Label slow, done;
+    { PreservePositionScope scope(masm()->positions_recorder());
+      // Generate code for loading from variables potentially shadowed by
+      // eval-introduced variables.
+      EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done);
+    }
+    __ bind(&slow);
+    // Call the runtime to find the function to call (returned in eax) and
+    // the object holding it (returned in edx).
+    __ push(context_register());
+    __ push(Immediate(proxy->name()));
+    __ CallRuntime(Runtime::kLoadLookupSlot, 2);
+    __ push(eax);  // Function.
+    __ push(edx);  // Receiver.
+    PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
+
+    // If fast case code has been generated, emit code to push the function
+    // and receiver and have the slow path jump around this code.
+    if (done.is_linked()) {
+      Label call;
+      __ jmp(&call, Label::kNear);
+      __ bind(&done);
+      // Push function.
+      __ push(eax);
+      // The receiver is implicitly the global receiver. Indicate this by
+      // passing the hole to the call function stub.
+      __ push(Immediate(isolate()->factory()->undefined_value()));
+      __ bind(&call);
+    }
+
+    // The receiver is either the global receiver or an object found by
+    // LoadContextSlot.
     EmitCall(expr);
+
   } else if (call_type == Call::PROPERTY_CALL) {
     Property* property = callee->AsProperty();
     bool is_named_call = property->key()->IsPropertyName();
index 048dad64f6580230bc0da563347e9d8d452acd3d..2176725665c4e16c16168ceaf5f3f8b3f180c620 100644 (file)
@@ -3121,53 +3121,6 @@ void FullCodeGenerator::EmitInitializeThisAfterSuper(
 }
 
 
-// See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
-void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
-  VariableProxy* callee = expr->expression()->AsVariableProxy();
-  if (callee->var()->IsLookupSlot()) {
-    Label slow, done;
-
-    {
-      PreservePositionScope scope(masm()->positions_recorder());
-      // Generate code for loading from variables potentially shadowed
-      // by eval-introduced variables.
-      EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
-    }
-
-    __ bind(&slow);
-    // Call the runtime to find the function to call (returned in v0)
-    // and the object holding it (returned in v1).
-    DCHECK(!context_register().is(a2));
-    __ li(a2, Operand(callee->name()));
-    __ Push(context_register(), a2);
-    __ CallRuntime(Runtime::kLoadLookupSlot, 2);
-    __ Push(v0, v1);  // Function, receiver.
-    PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
-
-    // If fast case code has been generated, emit code to push the
-    // function and receiver and have the slow path jump around this
-    // code.
-    if (done.is_linked()) {
-      Label call;
-      __ Branch(&call);
-      __ bind(&done);
-      // Push function.
-      __ push(v0);
-      // The receiver is implicitly the global receiver. Indicate this
-      // by passing the hole to the call function stub.
-      __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
-      __ push(a1);
-      __ bind(&call);
-    }
-  } else {
-    VisitForStackValue(callee);
-    // refEnv.WithBaseObject()
-    __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
-    __ push(a2);  // Reserved receiver slot.
-  }
-}
-
-
 void FullCodeGenerator::VisitCall(Call* expr) {
 #ifdef DEBUG
   // We want to verify that RecordJSReturnSite gets called on all paths
@@ -3187,7 +3140,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
     int arg_count = args->length();
 
     { PreservePositionScope pos_scope(masm()->positions_recorder());
-      PushCalleeAndWithBaseObject(expr);
+      VisitForStackValue(callee);
+      __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
+      __ push(a2);  // Reserved receiver slot.
 
       // Push the arguments.
       for (int i = 0; i < arg_count; i++) {
@@ -3203,7 +3158,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
       // Touch up the stack with the resolved function.
       __ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
 
-      PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
+      PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
     }
     // Record source position for debugger.
     SetSourcePosition(expr->position());
@@ -3218,7 +3173,43 @@ void FullCodeGenerator::VisitCall(Call* expr) {
     EmitCallWithLoadIC(expr);
   } else if (call_type == Call::LOOKUP_SLOT_CALL) {
     // Call to a lookup slot (dynamically introduced variable).
-    PushCalleeAndWithBaseObject(expr);
+    VariableProxy* proxy = callee->AsVariableProxy();
+    Label slow, done;
+
+    { PreservePositionScope scope(masm()->positions_recorder());
+      // Generate code for loading from variables potentially shadowed
+      // by eval-introduced variables.
+      EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done);
+    }
+
+    __ bind(&slow);
+    // Call the runtime to find the function to call (returned in v0)
+    // and the object holding it (returned in v1).
+    DCHECK(!context_register().is(a2));
+    __ li(a2, Operand(proxy->name()));
+    __ Push(context_register(), a2);
+    __ CallRuntime(Runtime::kLoadLookupSlot, 2);
+    __ Push(v0, v1);  // Function, receiver.
+    PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
+
+    // If fast case code has been generated, emit code to push the
+    // function and receiver and have the slow path jump around this
+    // code.
+    if (done.is_linked()) {
+      Label call;
+      __ Branch(&call);
+      __ bind(&done);
+      // Push function.
+      __ push(v0);
+      // The receiver is implicitly the global receiver. Indicate this
+      // by passing the hole to the call function stub.
+      __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
+      __ push(a1);
+      __ bind(&call);
+    }
+
+    // The receiver is either the global receiver or an object found
+    // by LoadContextSlot.
     EmitCall(expr);
   } else if (call_type == Call::PROPERTY_CALL) {
     Property* property = callee->AsProperty();
index 8979bac9f63d091a5c6e87c08628713a54d953d7..0453850fa7a283effd3c2655e398e46fe7df8ae5 100644 (file)
@@ -3122,53 +3122,6 @@ void FullCodeGenerator::EmitInitializeThisAfterSuper(
 }
 
 
-// See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
-void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
-  VariableProxy* callee = expr->expression()->AsVariableProxy();
-  if (callee->var()->IsLookupSlot()) {
-    Label slow, done;
-
-    {
-      PreservePositionScope scope(masm()->positions_recorder());
-      // Generate code for loading from variables potentially shadowed
-      // by eval-introduced variables.
-      EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
-    }
-
-    __ bind(&slow);
-    // Call the runtime to find the function to call (returned in v0)
-    // and the object holding it (returned in v1).
-    DCHECK(!context_register().is(a2));
-    __ li(a2, Operand(callee->name()));
-    __ Push(context_register(), a2);
-    __ CallRuntime(Runtime::kLoadLookupSlot, 2);
-    __ Push(v0, v1);  // Function, receiver.
-    PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
-
-    // If fast case code has been generated, emit code to push the
-    // function and receiver and have the slow path jump around this
-    // code.
-    if (done.is_linked()) {
-      Label call;
-      __ Branch(&call);
-      __ bind(&done);
-      // Push function.
-      __ push(v0);
-      // The receiver is implicitly the global receiver. Indicate this
-      // by passing the hole to the call function stub.
-      __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
-      __ push(a1);
-      __ bind(&call);
-    }
-  } else {
-    VisitForStackValue(callee);
-    // refEnv.WithBaseObject()
-    __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
-    __ push(a2);  // Reserved receiver slot.
-  }
-}
-
-
 void FullCodeGenerator::VisitCall(Call* expr) {
 #ifdef DEBUG
   // We want to verify that RecordJSReturnSite gets called on all paths
@@ -3188,7 +3141,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
     int arg_count = args->length();
 
     { PreservePositionScope pos_scope(masm()->positions_recorder());
-      PushCalleeAndWithBaseObject(expr);
+      VisitForStackValue(callee);
+      __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
+      __ push(a2);  // Reserved receiver slot.
 
       // Push the arguments.
       for (int i = 0; i < arg_count; i++) {
@@ -3204,7 +3159,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
       // Touch up the stack with the resolved function.
       __ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
 
-      PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
+      PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
     }
     // Record source position for debugger.
     SetSourcePosition(expr->position());
@@ -3219,7 +3174,43 @@ void FullCodeGenerator::VisitCall(Call* expr) {
     EmitCallWithLoadIC(expr);
   } else if (call_type == Call::LOOKUP_SLOT_CALL) {
     // Call to a lookup slot (dynamically introduced variable).
-    PushCalleeAndWithBaseObject(expr);
+    VariableProxy* proxy = callee->AsVariableProxy();
+    Label slow, done;
+
+    { PreservePositionScope scope(masm()->positions_recorder());
+      // Generate code for loading from variables potentially shadowed
+      // by eval-introduced variables.
+      EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done);
+    }
+
+    __ bind(&slow);
+    // Call the runtime to find the function to call (returned in v0)
+    // and the object holding it (returned in v1).
+    DCHECK(!context_register().is(a2));
+    __ li(a2, Operand(proxy->name()));
+    __ Push(context_register(), a2);
+    __ CallRuntime(Runtime::kLoadLookupSlot, 2);
+    __ Push(v0, v1);  // Function, receiver.
+    PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
+
+    // If fast case code has been generated, emit code to push the
+    // function and receiver and have the slow path jump around this
+    // code.
+    if (done.is_linked()) {
+      Label call;
+      __ Branch(&call);
+      __ bind(&done);
+      // Push function.
+      __ push(v0);
+      // The receiver is implicitly the global receiver. Indicate this
+      // by passing the hole to the call function stub.
+      __ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
+      __ push(a1);
+      __ bind(&call);
+    }
+
+    // The receiver is either the global receiver or an object found
+    // by LoadContextSlot.
     EmitCall(expr);
   } else if (call_type == Call::PROPERTY_CALL) {
     Property* property = callee->AsProperty();
index e89be857cfd4c70a83fba91986b99ccb50f2d3e6..acf64309f7c56bee1564bd528febd64915fdc27f 100644 (file)
@@ -3135,51 +3135,6 @@ void FullCodeGenerator::EmitInitializeThisAfterSuper(
 }
 
 
-// See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
-void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
-  VariableProxy* callee = expr->expression()->AsVariableProxy();
-  if (callee->var()->IsLookupSlot()) {
-    Label slow, done;
-
-    {
-      PreservePositionScope scope(masm()->positions_recorder());
-      // Generate code for loading from variables potentially shadowed by
-      // eval-introduced variables.
-      EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
-    }
-    __ bind(&slow);
-    // Call the runtime to find the function to call (returned in rax) and
-    // the object holding it (returned in rdx).
-    __ Push(context_register());
-    __ Push(callee->name());
-    __ CallRuntime(Runtime::kLoadLookupSlot, 2);
-    __ Push(rax);  // Function.
-    __ Push(rdx);  // Receiver.
-    PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
-
-    // If fast case code has been generated, emit code to push the function
-    // and receiver and have the slow path jump around this code.
-    if (done.is_linked()) {
-      Label call;
-      __ jmp(&call, Label::kNear);
-      __ bind(&done);
-      // Push function.
-      __ Push(rax);
-      // Pass undefined as the receiver, which is the WithBaseObject of a
-      // non-object environment record.  If the callee is sloppy, it will patch
-      // it up to be the global receiver.
-      __ PushRoot(Heap::kUndefinedValueRootIndex);
-      __ bind(&call);
-    }
-  } else {
-    VisitForStackValue(callee);
-    // refEnv.WithBaseObject()
-    __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
-    __ push(r5);
-  }
-}
-
-
 void FullCodeGenerator::VisitCall(Call* expr) {
 #ifdef DEBUG
   // We want to verify that RecordJSReturnSite gets called on all paths
@@ -3200,7 +3155,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
 
     {
       PreservePositionScope pos_scope(masm()->positions_recorder());
-      PushCalleeAndWithBaseObject(expr);
+      VisitForStackValue(callee);
+      __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
+      __ push(r5);  // Reserved receiver slot.
 
       // Push the arguments.
       for (int i = 0; i < arg_count; i++) {
@@ -3216,7 +3173,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
       // Touch up the stack with the resolved function.
       __ StoreP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
 
-      PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
+      PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
     }
 
     // Record source position for debugger.
@@ -3233,7 +3190,44 @@ void FullCodeGenerator::VisitCall(Call* expr) {
 
   } else if (call_type == Call::LOOKUP_SLOT_CALL) {
     // Call to a lookup slot (dynamically introduced variable).
-    PushCalleeAndWithBaseObject(expr);
+    VariableProxy* proxy = callee->AsVariableProxy();
+    Label slow, done;
+
+    {
+      PreservePositionScope scope(masm()->positions_recorder());
+      // Generate code for loading from variables potentially shadowed
+      // by eval-introduced variables.
+      EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done);
+    }
+
+    __ bind(&slow);
+    // Call the runtime to find the function to call (returned in r3)
+    // and the object holding it (returned in edx).
+    DCHECK(!context_register().is(r5));
+    __ mov(r5, Operand(proxy->name()));
+    __ Push(context_register(), r5);
+    __ CallRuntime(Runtime::kLoadLookupSlot, 2);
+    __ Push(r3, r4);  // Function, receiver.
+    PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
+
+    // If fast case code has been generated, emit code to push the
+    // function and receiver and have the slow path jump around this
+    // code.
+    if (done.is_linked()) {
+      Label call;
+      __ b(&call);
+      __ bind(&done);
+      // Push function.
+      __ push(r3);
+      // The receiver is implicitly the global receiver. Indicate this
+      // by passing the hole to the call function stub.
+      __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
+      __ push(r4);
+      __ bind(&call);
+    }
+
+    // The receiver is either the global receiver or an object found
+    // by LoadContextSlot.
     EmitCall(expr);
   } else if (call_type == Call::PROPERTY_CALL) {
     Property* property = callee->AsProperty();
index b519d46ea654865c83dea72169f1cdd3e692a31c..b8cb3ee31a334b6ddac4888be4b359d6f69343e9 100644 (file)
@@ -3032,50 +3032,6 @@ void FullCodeGenerator::EmitInitializeThisAfterSuper(
 }
 
 
-// See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
-void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
-  VariableProxy* callee = expr->expression()->AsVariableProxy();
-  if (callee->var()->IsLookupSlot()) {
-    Label slow, done;
-
-    {
-      PreservePositionScope scope(masm()->positions_recorder());
-      // Generate code for loading from variables potentially shadowed by
-      // eval-introduced variables.
-      EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
-    }
-    __ bind(&slow);
-    // Call the runtime to find the function to call (returned in rax) and
-    // the object holding it (returned in rdx).
-    __ Push(context_register());
-    __ Push(callee->name());
-    __ CallRuntime(Runtime::kLoadLookupSlot, 2);
-    __ Push(rax);  // Function.
-    __ Push(rdx);  // Receiver.
-    PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
-
-    // If fast case code has been generated, emit code to push the function
-    // and receiver and have the slow path jump around this code.
-    if (done.is_linked()) {
-      Label call;
-      __ jmp(&call, Label::kNear);
-      __ bind(&done);
-      // Push function.
-      __ Push(rax);
-      // Pass undefined as the receiver, which is the WithBaseObject of a
-      // non-object environment record.  If the callee is sloppy, it will patch
-      // it up to be the global receiver.
-      __ PushRoot(Heap::kUndefinedValueRootIndex);
-      __ bind(&call);
-    }
-  } else {
-    VisitForStackValue(callee);
-    // refEnv.WithBaseObject()
-    __ PushRoot(Heap::kUndefinedValueRootIndex);
-  }
-}
-
-
 void FullCodeGenerator::VisitCall(Call* expr) {
 #ifdef DEBUG
   // We want to verify that RecordJSReturnSite gets called on all paths
@@ -3094,7 +3050,8 @@ void FullCodeGenerator::VisitCall(Call* expr) {
     ZoneList<Expression*>* args = expr->arguments();
     int arg_count = args->length();
     { PreservePositionScope pos_scope(masm()->positions_recorder());
-      PushCalleeAndWithBaseObject(expr);
+      VisitForStackValue(callee);
+      __ PushRoot(Heap::kUndefinedValueRootIndex);  // Reserved receiver slot.
 
       // Push the arguments.
       for (int i = 0; i < arg_count; i++) {
@@ -3109,7 +3066,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
       // Touch up the callee.
       __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax);
 
-      PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
+      PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
     }
     // Record source position for debugger.
     SetSourcePosition(expr->position());
@@ -3125,7 +3082,40 @@ void FullCodeGenerator::VisitCall(Call* expr) {
 
   } else if (call_type == Call::LOOKUP_SLOT_CALL) {
     // Call to a lookup slot (dynamically introduced variable).
-    PushCalleeAndWithBaseObject(expr);
+    VariableProxy* proxy = callee->AsVariableProxy();
+    Label slow, done;
+
+    { PreservePositionScope scope(masm()->positions_recorder());
+      // Generate code for loading from variables potentially shadowed by
+      // eval-introduced variables.
+      EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done);
+    }
+    __ bind(&slow);
+    // Call the runtime to find the function to call (returned in rax) and
+    // the object holding it (returned in rdx).
+    __ Push(context_register());
+    __ Push(proxy->name());
+    __ CallRuntime(Runtime::kLoadLookupSlot, 2);
+    __ Push(rax);  // Function.
+    __ Push(rdx);  // Receiver.
+    PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
+
+    // If fast case code has been generated, emit code to push the function
+    // and receiver and have the slow path jump around this code.
+    if (done.is_linked()) {
+      Label call;
+      __ jmp(&call, Label::kNear);
+      __ bind(&done);
+      // Push function.
+      __ Push(rax);
+      // The receiver is implicitly the global receiver. Indicate this by
+      // passing the hole to the call function stub.
+      __ PushRoot(Heap::kUndefinedValueRootIndex);
+      __ bind(&call);
+    }
+
+    // The receiver is either the global receiver or an object found by
+    // LoadContextSlot.
     EmitCall(expr);
   } else if (call_type == Call::PROPERTY_CALL) {
     Property* property = callee->AsProperty();
index cbe7f027443b4a2a4104fab0d8d503d33c6baa5a..683eae91cc7107794bdbca70ea4b1c9ea3fcf3f9 100644 (file)
@@ -3017,48 +3017,6 @@ void FullCodeGenerator::EmitInitializeThisAfterSuper(
 }
 
 
-// See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
-void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
-  VariableProxy* callee = expr->expression()->AsVariableProxy();
-  if (callee->var()->IsLookupSlot()) {
-    Label slow, done;
-    {
-      PreservePositionScope scope(masm()->positions_recorder());
-      // Generate code for loading from variables potentially shadowed by
-      // eval-introduced variables.
-      EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
-    }
-    __ bind(&slow);
-    // Call the runtime to find the function to call (returned in eax) and
-    // the object holding it (returned in edx).
-    __ push(context_register());
-    __ push(Immediate(callee->name()));
-    __ CallRuntime(Runtime::kLoadLookupSlot, 2);
-    __ push(eax);  // Function.
-    __ push(edx);  // Receiver.
-    PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
-
-    // If fast case code has been generated, emit code to push the function
-    // and receiver and have the slow path jump around this code.
-    if (done.is_linked()) {
-      Label call;
-      __ jmp(&call, Label::kNear);
-      __ bind(&done);
-      // Push function.
-      __ push(eax);
-      // The receiver is implicitly the global receiver. Indicate this by
-      // passing the hole to the call function stub.
-      __ push(Immediate(isolate()->factory()->undefined_value()));
-      __ bind(&call);
-    }
-  } else {
-    VisitForStackValue(callee);
-    // refEnv.WithBaseObject()
-    __ push(Immediate(isolate()->factory()->undefined_value()));
-  }
-}
-
-
 void FullCodeGenerator::VisitCall(Call* expr) {
 #ifdef DEBUG
   // We want to verify that RecordJSReturnSite gets called on all paths
@@ -3077,8 +3035,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
     ZoneList<Expression*>* args = expr->arguments();
     int arg_count = args->length();
     { PreservePositionScope pos_scope(masm()->positions_recorder());
-      PushCalleeAndWithBaseObject(expr);
-
+      VisitForStackValue(callee);
+      // Reserved receiver slot.
+      __ push(Immediate(isolate()->factory()->undefined_value()));
       // Push the arguments.
       for (int i = 0; i < arg_count; i++) {
         VisitForStackValue(args->at(i));
@@ -3092,7 +3051,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
       // Touch up the stack with the resolved function.
       __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
 
-      PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
+      PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
     }
     // Record source position for debugger.
     SetSourcePosition(expr->position());
@@ -3108,8 +3067,41 @@ void FullCodeGenerator::VisitCall(Call* expr) {
     EmitCallWithLoadIC(expr);
   } else if (call_type == Call::LOOKUP_SLOT_CALL) {
     // Call to a lookup slot (dynamically introduced variable).
-    PushCalleeAndWithBaseObject(expr);
+    VariableProxy* proxy = callee->AsVariableProxy();
+    Label slow, done;
+    { PreservePositionScope scope(masm()->positions_recorder());
+      // Generate code for loading from variables potentially shadowed by
+      // eval-introduced variables.
+      EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done);
+    }
+    __ bind(&slow);
+    // Call the runtime to find the function to call (returned in eax) and
+    // the object holding it (returned in edx).
+    __ push(context_register());
+    __ push(Immediate(proxy->name()));
+    __ CallRuntime(Runtime::kLoadLookupSlot, 2);
+    __ push(eax);  // Function.
+    __ push(edx);  // Receiver.
+    PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
+
+    // If fast case code has been generated, emit code to push the function
+    // and receiver and have the slow path jump around this code.
+    if (done.is_linked()) {
+      Label call;
+      __ jmp(&call, Label::kNear);
+      __ bind(&done);
+      // Push function.
+      __ push(eax);
+      // The receiver is implicitly the global receiver. Indicate this by
+      // passing the hole to the call function stub.
+      __ push(Immediate(isolate()->factory()->undefined_value()));
+      __ bind(&call);
+    }
+
+    // The receiver is either the global receiver or an object found by
+    // LoadContextSlot.
     EmitCall(expr);
+
   } else if (call_type == Call::PROPERTY_CALL) {
     Property* property = callee->AsProperty();
     bool is_named_call = property->key()->IsPropertyName();
diff --git a/test/mjsunit/regress/regress-4214.js b/test/mjsunit/regress/regress-4214.js
deleted file mode 100644 (file)
index 7c28104..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var o = { eval: function() { return this; } }
-with (o) assertSame(o, eval());