Index: src/arm/full-codegen-arm.cc |
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc |
index fc01336d7c46ca0bdf04e34af89f782c2d3bd76f..6f1f16a9c35c692cfd376055fc5864f0f289ecf2 100644 |
--- a/src/arm/full-codegen-arm.cc |
+++ b/src/arm/full-codegen-arm.cc |
@@ -3137,28 +3137,78 @@ |
} |
-// 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()) { |
+void FullCodeGenerator::VisitCall(Call* expr) { |
+#ifdef DEBUG |
+ // We want to verify that RecordJSReturnSite gets called on all paths |
+ // through this function. Avoid early returns. |
+ expr->return_is_recorded_ = false; |
+#endif |
+ |
+ Comment cmnt(masm_, "[ Call"); |
+ Expression* callee = expr->expression(); |
+ Call::CallType call_type = expr->GetCallType(isolate()); |
+ |
+ if (call_type == Call::POSSIBLY_EVAL_CALL) { |
+ // In a call to eval, we first call |
+ // RuntimeHidden_asResolvePossiblyDirectEval to resolve the function we need |
+ // to call. Then we call the resolved function using the given arguments. |
+ ZoneList<Expression*>* args = expr->arguments(); |
+ int arg_count = args->length(); |
+ |
+ { PreservePositionScope pos_scope(masm()->positions_recorder()); |
+ VisitForStackValue(callee); |
+ __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
+ __ push(r2); // Reserved receiver slot. |
+ |
+ // Push the arguments. |
+ for (int i = 0; i < arg_count; i++) { |
+ VisitForStackValue(args->at(i)); |
+ } |
+ |
+ // Push a copy of the function (found below the arguments) and |
+ // resolve eval. |
+ __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
+ __ push(r1); |
+ EmitResolvePossiblyDirectEval(arg_count); |
+ |
+ // Touch up the stack with the resolved function. |
+ __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
+ |
+ PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS); |
+ } |
+ |
+ // Record source position for debugger. |
+ SetSourcePosition(expr->position()); |
+ CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
+ __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
+ __ CallStub(&stub); |
+ RecordJSReturnSite(expr); |
+ // Restore context register. |
+ __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ context()->DropAndPlug(1, r0); |
+ } else if (call_type == Call::GLOBAL_CALL) { |
+ 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()); |
+ { PreservePositionScope scope(masm()->positions_recorder()); |
// Generate code for loading from variables potentially shadowed |
// by eval-introduced variables. |
- EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |
+ 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(callee->name())); |
+ __ mov(r2, Operand(proxy->name())); |
__ Push(context_register(), r2); |
__ CallRuntime(Runtime::kLoadLookupSlot, 2); |
__ Push(r0, r1); // Function, receiver. |
- PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); |
+ 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 |
@@ -3175,68 +3225,9 @@ |
__ 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 |
- // through this function. Avoid early returns. |
- expr->return_is_recorded_ = false; |
-#endif |
- |
- Comment cmnt(masm_, "[ Call"); |
- Expression* callee = expr->expression(); |
- Call::CallType call_type = expr->GetCallType(isolate()); |
- |
- if (call_type == Call::POSSIBLY_EVAL_CALL) { |
- // In a call to eval, we first call |
- // RuntimeHidden_asResolvePossiblyDirectEval to resolve the function we need |
- // to call. Then we call the resolved function using the given arguments. |
- ZoneList<Expression*>* args = expr->arguments(); |
- int arg_count = args->length(); |
- |
- { PreservePositionScope pos_scope(masm()->positions_recorder()); |
- PushCalleeAndWithBaseObject(expr); |
- |
- // Push the arguments. |
- for (int i = 0; i < arg_count; i++) { |
- VisitForStackValue(args->at(i)); |
- } |
- |
- // Push a copy of the function (found below the arguments) and |
- // resolve eval. |
- __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
- __ push(r1); |
- EmitResolvePossiblyDirectEval(arg_count); |
- |
- // Touch up the stack with the resolved function. |
- __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
- |
- PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); |
- } |
- |
- // Record source position for debugger. |
- SetSourcePosition(expr->position()); |
- CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
- __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
- __ CallStub(&stub); |
- RecordJSReturnSite(expr); |
- // Restore context register. |
- __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
- context()->DropAndPlug(1, r0); |
- } else if (call_type == Call::GLOBAL_CALL) { |
- EmitCallWithLoadIC(expr); |
- |
- } else if (call_type == Call::LOOKUP_SLOT_CALL) { |
- // Call to a lookup slot (dynamically introduced variable). |
- PushCalleeAndWithBaseObject(expr); |
+ |
+ // 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(); |