OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 4700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4711 __ bind(&done); | 4711 __ bind(&done); |
4712 __ add(sp, sp, Operand(3 * kPointerSize)); | 4712 __ add(sp, sp, Operand(3 * kPointerSize)); |
4713 __ Ret(); | 4713 __ Ret(); |
4714 | 4714 |
4715 __ bind(&slowcase); | 4715 __ bind(&slowcase); |
4716 __ TailCallRuntime(Runtime::kRegExpConstructResult, 3, 1); | 4716 __ TailCallRuntime(Runtime::kRegExpConstructResult, 3, 1); |
4717 } | 4717 } |
4718 | 4718 |
4719 | 4719 |
4720 void CallFunctionStub::Generate(MacroAssembler* masm) { | 4720 void CallFunctionStub::Generate(MacroAssembler* masm) { |
4721 Label slow; | 4721 Label slow, non_function; |
4722 | 4722 |
4723 // The receiver might implicitly be the global object. This is | 4723 // The receiver might implicitly be the global object. This is |
4724 // indicated by passing the hole as the receiver to the call | 4724 // indicated by passing the hole as the receiver to the call |
4725 // function stub. | 4725 // function stub. |
4726 if (ReceiverMightBeImplicit()) { | 4726 if (ReceiverMightBeImplicit()) { |
4727 Label call; | 4727 Label call; |
4728 // Get the receiver from the stack. | 4728 // Get the receiver from the stack. |
4729 // function, receiver [, arguments] | 4729 // function, receiver [, arguments] |
4730 __ ldr(r4, MemOperand(sp, argc_ * kPointerSize)); | 4730 __ ldr(r4, MemOperand(sp, argc_ * kPointerSize)); |
4731 // Call as function is indicated with the hole. | 4731 // Call as function is indicated with the hole. |
4732 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); | 4732 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); |
4733 __ b(ne, &call); | 4733 __ b(ne, &call); |
4734 // Patch the receiver on the stack with the global receiver object. | 4734 // Patch the receiver on the stack with the global receiver object. |
4735 __ ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); | 4735 __ ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); |
4736 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 4736 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
4737 __ str(r1, MemOperand(sp, argc_ * kPointerSize)); | 4737 __ str(r1, MemOperand(sp, argc_ * kPointerSize)); |
4738 __ bind(&call); | 4738 __ bind(&call); |
4739 } | 4739 } |
4740 | 4740 |
4741 // Get the function to call from the stack. | 4741 // Get the function to call from the stack. |
4742 // function, receiver [, arguments] | 4742 // function, receiver [, arguments] |
4743 __ ldr(r1, MemOperand(sp, (argc_ + 1) * kPointerSize)); | 4743 __ ldr(r1, MemOperand(sp, (argc_ + 1) * kPointerSize)); |
4744 | 4744 |
4745 // Check that the function is really a JavaScript function. | 4745 // Check that the function is really a JavaScript function. |
4746 // r1: pushed function (to be verified) | 4746 // r1: pushed function (to be verified) |
4747 __ JumpIfSmi(r1, &slow); | 4747 __ JumpIfSmi(r1, &non_function); |
4748 // Get the map of the function object. | 4748 // Get the map of the function object. |
4749 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); | 4749 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); |
4750 __ b(ne, &slow); | 4750 __ b(ne, &slow); |
4751 | 4751 |
4752 // Fast-case: Invoke the function now. | 4752 // Fast-case: Invoke the function now. |
4753 // r1: pushed function | 4753 // r1: pushed function |
4754 ParameterCount actual(argc_); | 4754 ParameterCount actual(argc_); |
4755 | 4755 |
4756 if (ReceiverMightBeImplicit()) { | 4756 if (ReceiverMightBeImplicit()) { |
4757 Label call_as_function; | 4757 Label call_as_function; |
4758 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); | 4758 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); |
4759 __ b(eq, &call_as_function); | 4759 __ b(eq, &call_as_function); |
4760 __ InvokeFunction(r1, | 4760 __ InvokeFunction(r1, |
4761 actual, | 4761 actual, |
4762 JUMP_FUNCTION, | 4762 JUMP_FUNCTION, |
4763 NullCallWrapper(), | 4763 NullCallWrapper(), |
4764 CALL_AS_METHOD); | 4764 CALL_AS_METHOD); |
4765 __ bind(&call_as_function); | 4765 __ bind(&call_as_function); |
4766 } | 4766 } |
4767 __ InvokeFunction(r1, | 4767 __ InvokeFunction(r1, |
4768 actual, | 4768 actual, |
4769 JUMP_FUNCTION, | 4769 JUMP_FUNCTION, |
4770 NullCallWrapper(), | 4770 NullCallWrapper(), |
4771 CALL_AS_FUNCTION); | 4771 CALL_AS_FUNCTION); |
4772 | 4772 |
4773 // Slow-case: Non-function called. | 4773 // Slow-case: Non-function called. |
4774 __ bind(&slow); | 4774 __ bind(&slow); |
| 4775 // Check for function proxy. |
| 4776 __ cmp(r2, Operand(JS_FUNCTION_PROXY_TYPE)); |
| 4777 __ b(ne, &non_function); |
| 4778 __ push(r1); // put proxy as additional argument |
| 4779 __ mov(r0, Operand(argc_ + 1, RelocInfo::NONE)); |
| 4780 __ mov(r2, Operand(0, RelocInfo::NONE)); |
| 4781 __ GetBuiltinEntry(r3, Builtins::CALL_FUNCTION_PROXY); |
| 4782 __ SetCallKind(r5, CALL_AS_FUNCTION); |
| 4783 { |
| 4784 Handle<Code> adaptor = |
| 4785 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); |
| 4786 __ Jump(adaptor, RelocInfo::CODE_TARGET); |
| 4787 } |
| 4788 |
4775 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead | 4789 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead |
4776 // of the original receiver from the call site). | 4790 // of the original receiver from the call site). |
| 4791 __ bind(&non_function); |
4777 __ str(r1, MemOperand(sp, argc_ * kPointerSize)); | 4792 __ str(r1, MemOperand(sp, argc_ * kPointerSize)); |
4778 __ mov(r0, Operand(argc_)); // Setup the number of arguments. | 4793 __ mov(r0, Operand(argc_)); // Setup the number of arguments. |
4779 __ mov(r2, Operand(0, RelocInfo::NONE)); | 4794 __ mov(r2, Operand(0, RelocInfo::NONE)); |
4780 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 4795 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); |
4781 __ SetCallKind(r5, CALL_AS_METHOD); | 4796 __ SetCallKind(r5, CALL_AS_METHOD); |
4782 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 4797 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
4783 RelocInfo::CODE_TARGET); | 4798 RelocInfo::CODE_TARGET); |
4784 } | 4799 } |
4785 | 4800 |
4786 | 4801 |
(...skipping 1804 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6591 __ mov(result, Operand(0)); | 6606 __ mov(result, Operand(0)); |
6592 __ Ret(); | 6607 __ Ret(); |
6593 } | 6608 } |
6594 | 6609 |
6595 | 6610 |
6596 #undef __ | 6611 #undef __ |
6597 | 6612 |
6598 } } // namespace v8::internal | 6613 } } // namespace v8::internal |
6599 | 6614 |
6600 #endif // V8_TARGET_ARCH_ARM | 6615 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |