Index: src/mips/full-codegen-mips.cc |
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc |
index 2176725665c4e16c16168ceaf5f3f8b3f180c620..048dad64f6580230bc0da563347e9d8d452acd3d 100644 |
--- a/src/mips/full-codegen-mips.cc |
+++ b/src/mips/full-codegen-mips.cc |
@@ -3121,6 +3121,53 @@ 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 |
@@ -3140,9 +3187,7 @@ void FullCodeGenerator::VisitCall(Call* expr) { |
int arg_count = args->length(); |
{ PreservePositionScope pos_scope(masm()->positions_recorder()); |
- VisitForStackValue(callee); |
- __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); |
- __ push(a2); // Reserved receiver slot. |
+ PushCalleeAndWithBaseObject(expr); |
// Push the arguments. |
for (int i = 0; i < arg_count; i++) { |
@@ -3158,7 +3203,7 @@ void FullCodeGenerator::VisitCall(Call* expr) { |
// Touch up the stack with the resolved function. |
__ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
- PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS); |
+ PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); |
} |
// Record source position for debugger. |
SetSourcePosition(expr->position()); |
@@ -3173,43 +3218,7 @@ void FullCodeGenerator::VisitCall(Call* expr) { |
EmitCallWithLoadIC(expr); |
} else if (call_type == Call::LOOKUP_SLOT_CALL) { |
// Call to a lookup slot (dynamically introduced variable). |
- 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. |
+ PushCalleeAndWithBaseObject(expr); |
EmitCall(expr); |
} else if (call_type == Call::PROPERTY_CALL) { |
Property* property = callee->AsProperty(); |