| Index: src/arm/code-stubs-arm.cc
|
| diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
|
| index 5c149de5c9b169b695020d3aaa6635a1f2d1ae54..a754c14f19008737901b34fb94b17283443dc2f7 100644
|
| --- a/src/arm/code-stubs-arm.cc
|
| +++ b/src/arm/code-stubs-arm.cc
|
| @@ -3165,32 +3165,43 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
|
| // r2 : cache cell for call target
|
| Label slow, non_function;
|
|
|
| + // Check that the function is really a JavaScript function.
|
| + // r1: pushed function (to be verified)
|
| + __ JumpIfSmi(r1, &non_function);
|
| +
|
| // The receiver might implicitly be the global object. This is
|
| // indicated by passing the hole as the receiver to the call
|
| // function stub.
|
| - if (ReceiverMightBeImplicit()) {
|
| - Label call;
|
| - // Get the receiver from the stack.
|
| - // function, receiver [, arguments]
|
| - __ ldr(r4, MemOperand(sp, argc_ * kPointerSize));
|
| - // Call as function is indicated with the hole.
|
| - __ CompareRoot(r4, Heap::kTheHoleValueRootIndex);
|
| - __ b(ne, &call);
|
| + if (ReceiverMightBeImplicit() || ReceiverIsImplicit()) {
|
| + Label call, patch_current_context;
|
| + if (ReceiverMightBeImplicit()) {
|
| + // Get the receiver from the stack.
|
| + // function, receiver [, arguments]
|
| + __ ldr(r4, MemOperand(sp, argc_ * kPointerSize));
|
| + // Call as function is indicated with the hole.
|
| + __ CompareRoot(r4, Heap::kTheHoleValueRootIndex);
|
| + __ b(ne, &call);
|
| + }
|
| // Patch the receiver on the stack with the global receiver object.
|
| + // Goto slow case if we do not have a function.
|
| + __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
|
| + __ b(ne, &patch_current_context);
|
| + CallStubCompiler::FetchGlobalProxy(masm, r3, r1);
|
| + __ str(r3, MemOperand(sp, argc_ * kPointerSize));
|
| + __ jmp(&call);
|
| + __ bind(&patch_current_context);
|
| __ ldr(r3,
|
| MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
|
| __ ldr(r3, FieldMemOperand(r3, GlobalObject::kGlobalReceiverOffset));
|
| __ str(r3, MemOperand(sp, argc_ * kPointerSize));
|
| + __ jmp(&slow);
|
| __ bind(&call);
|
| + } else {
|
| + // Get the map of the function object.
|
| + __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
|
| + __ b(ne, &slow);
|
| }
|
|
|
| - // Check that the function is really a JavaScript function.
|
| - // r1: pushed function (to be verified)
|
| - __ JumpIfSmi(r1, &non_function);
|
| - // Get the map of the function object.
|
| - __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
|
| - __ b(ne, &slow);
|
| -
|
| if (RecordCallTarget()) {
|
| GenerateRecordCallTarget(masm);
|
| }
|
|
|