OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 5660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5671 __ mov(Operand::StaticVariable(limit_address), edi); | 5671 __ mov(Operand::StaticVariable(limit_address), edi); |
5672 __ mov(edi, eax); | 5672 __ mov(edi, eax); |
5673 __ mov(Operand(esp, 0), | 5673 __ mov(Operand(esp, 0), |
5674 Immediate(ExternalReference::isolate_address(isolate))); | 5674 Immediate(ExternalReference::isolate_address(isolate))); |
5675 __ mov(eax, Immediate(delete_extensions)); | 5675 __ mov(eax, Immediate(delete_extensions)); |
5676 __ call(eax); | 5676 __ call(eax); |
5677 __ mov(eax, edi); | 5677 __ mov(eax, edi); |
5678 __ jmp(&leave_exit_frame); | 5678 __ jmp(&leave_exit_frame); |
5679 } | 5679 } |
5680 | 5680 |
5681 void CallApiCallbackStub::Generate(MacroAssembler* masm) { | 5681 static void CallApiFunctionStubHelper(MacroAssembler* masm, |
| 5682 const ParameterCount& argc, |
| 5683 bool return_first_arg, |
| 5684 bool call_data_undefined, bool is_lazy) { |
5682 // ----------- S t a t e ------------- | 5685 // ----------- S t a t e ------------- |
5683 // -- edi : callee | 5686 // -- edi : callee |
5684 // -- ebx : call_data | 5687 // -- ebx : call_data |
5685 // -- ecx : holder | 5688 // -- ecx : holder |
5686 // -- edx : api_function_address | 5689 // -- edx : api_function_address |
5687 // -- esi : context | 5690 // -- esi : context |
| 5691 // -- eax : number of arguments if argc is a register |
5688 // -- | 5692 // -- |
5689 // -- esp[0] : return address | 5693 // -- esp[0] : return address |
5690 // -- esp[4] : last argument | 5694 // -- esp[4] : last argument |
5691 // -- ... | 5695 // -- ... |
5692 // -- esp[argc * 4] : first argument | 5696 // -- esp[argc * 4] : first argument |
5693 // -- esp[(argc + 1) * 4] : receiver | 5697 // -- esp[(argc + 1) * 4] : receiver |
5694 // ----------------------------------- | 5698 // ----------------------------------- |
5695 | 5699 |
5696 Register callee = edi; | 5700 Register callee = edi; |
5697 Register call_data = ebx; | 5701 Register call_data = ebx; |
5698 Register holder = ecx; | 5702 Register holder = ecx; |
5699 Register api_function_address = edx; | 5703 Register api_function_address = edx; |
5700 Register context = esi; | 5704 Register context = esi; |
5701 Register return_address = eax; | 5705 Register return_address = eax; |
5702 | 5706 |
5703 typedef FunctionCallbackArguments FCA; | 5707 typedef FunctionCallbackArguments FCA; |
5704 | 5708 |
5705 STATIC_ASSERT(FCA::kContextSaveIndex == 6); | 5709 STATIC_ASSERT(FCA::kContextSaveIndex == 6); |
5706 STATIC_ASSERT(FCA::kCalleeIndex == 5); | 5710 STATIC_ASSERT(FCA::kCalleeIndex == 5); |
5707 STATIC_ASSERT(FCA::kDataIndex == 4); | 5711 STATIC_ASSERT(FCA::kDataIndex == 4); |
5708 STATIC_ASSERT(FCA::kReturnValueOffset == 3); | 5712 STATIC_ASSERT(FCA::kReturnValueOffset == 3); |
5709 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); | 5713 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); |
5710 STATIC_ASSERT(FCA::kIsolateIndex == 1); | 5714 STATIC_ASSERT(FCA::kIsolateIndex == 1); |
5711 STATIC_ASSERT(FCA::kHolderIndex == 0); | 5715 STATIC_ASSERT(FCA::kHolderIndex == 0); |
5712 STATIC_ASSERT(FCA::kArgsLength == 7); | 5716 STATIC_ASSERT(FCA::kArgsLength == 7); |
5713 | 5717 |
5714 __ pop(return_address); | 5718 DCHECK(argc.is_immediate() || eax.is(argc.reg())); |
5715 // context save. | 5719 |
5716 __ push(context); | 5720 if (argc.is_immediate()) { |
| 5721 __ pop(return_address); |
| 5722 // context save. |
| 5723 __ push(context); |
| 5724 } else { |
| 5725 // pop return address and save context |
| 5726 __ xchg(context, Operand(esp, 0)); |
| 5727 return_address = context; |
| 5728 } |
5717 | 5729 |
5718 // callee | 5730 // callee |
5719 __ push(callee); | 5731 __ push(callee); |
5720 | 5732 |
5721 // call data | 5733 // call data |
5722 __ push(call_data); | 5734 __ push(call_data); |
5723 | 5735 |
5724 Register scratch = call_data; | 5736 Register scratch = call_data; |
5725 if (!call_data_undefined()) { | 5737 if (!call_data_undefined) { |
5726 // return value | 5738 // return value |
5727 __ push(Immediate(masm->isolate()->factory()->undefined_value())); | 5739 __ push(Immediate(masm->isolate()->factory()->undefined_value())); |
5728 // return value default | 5740 // return value default |
5729 __ push(Immediate(masm->isolate()->factory()->undefined_value())); | 5741 __ push(Immediate(masm->isolate()->factory()->undefined_value())); |
5730 } else { | 5742 } else { |
5731 // return value | 5743 // return value |
5732 __ push(scratch); | 5744 __ push(scratch); |
5733 // return value default | 5745 // return value default |
5734 __ push(scratch); | 5746 __ push(scratch); |
5735 } | 5747 } |
5736 // isolate | 5748 // isolate |
5737 __ push(Immediate(reinterpret_cast<int>(masm->isolate()))); | 5749 __ push(Immediate(reinterpret_cast<int>(masm->isolate()))); |
5738 // holder | 5750 // holder |
5739 __ push(holder); | 5751 __ push(holder); |
5740 | 5752 |
5741 __ mov(scratch, esp); | 5753 __ mov(scratch, esp); |
5742 | 5754 |
5743 // push return address | 5755 // push return address |
5744 __ push(return_address); | 5756 __ push(return_address); |
5745 | 5757 |
5746 if (!is_lazy()) { | 5758 if (!is_lazy) { |
5747 // load context from callee | 5759 // load context from callee |
5748 __ mov(context, FieldOperand(callee, JSFunction::kContextOffset)); | 5760 __ mov(context, FieldOperand(callee, JSFunction::kContextOffset)); |
5749 } | 5761 } |
5750 | 5762 |
5751 // API function gets reference to the v8::Arguments. If CPU profiler | 5763 // API function gets reference to the v8::Arguments. If CPU profiler |
5752 // is enabled wrapper function will be called and we need to pass | 5764 // is enabled wrapper function will be called and we need to pass |
5753 // address of the callback as additional parameter, always allocate | 5765 // address of the callback as additional parameter, always allocate |
5754 // space for it. | 5766 // space for it. |
5755 const int kApiArgc = 1 + 1; | 5767 const int kApiArgc = 1 + 1; |
5756 | 5768 |
5757 // Allocate the v8::Arguments structure in the arguments' space since | 5769 // Allocate the v8::Arguments structure in the arguments' space since |
5758 // it's not controlled by GC. | 5770 // it's not controlled by GC. |
5759 const int kApiStackSpace = 4; | 5771 const int kApiStackSpace = 4; |
5760 | 5772 |
5761 PrepareCallApiFunction(masm, kApiArgc + kApiStackSpace); | 5773 PrepareCallApiFunction(masm, kApiArgc + kApiStackSpace); |
5762 | 5774 |
5763 // FunctionCallbackInfo::implicit_args_. | 5775 // FunctionCallbackInfo::implicit_args_. |
5764 __ mov(ApiParameterOperand(2), scratch); | 5776 __ mov(ApiParameterOperand(2), scratch); |
5765 __ add(scratch, Immediate((argc() + FCA::kArgsLength - 1) * kPointerSize)); | 5777 if (argc.is_immediate()) { |
5766 // FunctionCallbackInfo::values_. | 5778 __ add(scratch, |
5767 __ mov(ApiParameterOperand(3), scratch); | 5779 Immediate((argc.immediate() + FCA::kArgsLength - 1) * kPointerSize)); |
5768 // FunctionCallbackInfo::length_. | 5780 // FunctionCallbackInfo::values_. |
5769 __ Move(ApiParameterOperand(4), Immediate(argc())); | 5781 __ mov(ApiParameterOperand(3), scratch); |
5770 // FunctionCallbackInfo::is_construct_call_. | 5782 // FunctionCallbackInfo::length_. |
5771 __ Move(ApiParameterOperand(5), Immediate(0)); | 5783 __ Move(ApiParameterOperand(4), Immediate(argc.immediate())); |
| 5784 // FunctionCallbackInfo::is_construct_call_. |
| 5785 __ Move(ApiParameterOperand(5), Immediate(0)); |
| 5786 } else { |
| 5787 __ lea(scratch, Operand(scratch, argc.reg(), times_pointer_size, |
| 5788 (FCA::kArgsLength - 1) * kPointerSize)); |
| 5789 // FunctionCallbackInfo::values_. |
| 5790 __ mov(ApiParameterOperand(3), scratch); |
| 5791 // FunctionCallbackInfo::length_. |
| 5792 __ mov(ApiParameterOperand(4), argc.reg()); |
| 5793 // FunctionCallbackInfo::is_construct_call_. |
| 5794 __ lea(argc.reg(), Operand(argc.reg(), times_pointer_size, |
| 5795 (FCA::kArgsLength + 1) * kPointerSize)); |
| 5796 __ mov(ApiParameterOperand(5), argc.reg()); |
| 5797 } |
5772 | 5798 |
5773 // v8::InvocationCallback's argument. | 5799 // v8::InvocationCallback's argument. |
5774 __ lea(scratch, ApiParameterOperand(2)); | 5800 __ lea(scratch, ApiParameterOperand(2)); |
5775 __ mov(ApiParameterOperand(0), scratch); | 5801 __ mov(ApiParameterOperand(0), scratch); |
5776 | 5802 |
5777 ExternalReference thunk_ref = | 5803 ExternalReference thunk_ref = |
5778 ExternalReference::invoke_function_callback(masm->isolate()); | 5804 ExternalReference::invoke_function_callback(masm->isolate()); |
5779 | 5805 |
5780 Operand context_restore_operand(ebp, | 5806 Operand context_restore_operand(ebp, |
5781 (2 + FCA::kContextSaveIndex) * kPointerSize); | 5807 (2 + FCA::kContextSaveIndex) * kPointerSize); |
5782 // Stores return the first js argument | 5808 // Stores return the first js argument |
5783 int return_value_offset = 0; | 5809 int return_value_offset = 0; |
5784 if (is_store()) { | 5810 if (return_first_arg) { |
5785 return_value_offset = 2 + FCA::kArgsLength; | 5811 return_value_offset = 2 + FCA::kArgsLength; |
5786 } else { | 5812 } else { |
5787 return_value_offset = 2 + FCA::kReturnValueOffset; | 5813 return_value_offset = 2 + FCA::kReturnValueOffset; |
5788 } | 5814 } |
5789 Operand return_value_operand(ebp, return_value_offset * kPointerSize); | 5815 Operand return_value_operand(ebp, return_value_offset * kPointerSize); |
5790 int stack_space = 0; | 5816 int stack_space = 0; |
5791 Operand is_construct_call_operand = ApiParameterOperand(5); | 5817 Operand is_construct_call_operand = ApiParameterOperand(5); |
5792 Operand* stack_space_operand = &is_construct_call_operand; | 5818 Operand* stack_space_operand = &is_construct_call_operand; |
5793 stack_space = argc() + FCA::kArgsLength + 1; | 5819 if (argc.is_immediate()) { |
5794 stack_space_operand = nullptr; | 5820 stack_space = argc.immediate() + FCA::kArgsLength + 1; |
| 5821 stack_space_operand = nullptr; |
| 5822 } |
5795 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, | 5823 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, |
5796 ApiParameterOperand(1), stack_space, | 5824 ApiParameterOperand(1), stack_space, |
5797 stack_space_operand, return_value_operand, | 5825 stack_space_operand, return_value_operand, |
5798 &context_restore_operand); | 5826 &context_restore_operand); |
5799 } | 5827 } |
5800 | 5828 |
5801 | 5829 |
| 5830 void CallApiFunctionStub::Generate(MacroAssembler* masm) { |
| 5831 bool call_data_undefined = this->call_data_undefined(); |
| 5832 CallApiFunctionStubHelper(masm, ParameterCount(eax), false, |
| 5833 call_data_undefined, false); |
| 5834 } |
| 5835 |
| 5836 |
| 5837 void CallApiAccessorStub::Generate(MacroAssembler* masm) { |
| 5838 bool is_store = this->is_store(); |
| 5839 int argc = this->argc(); |
| 5840 bool call_data_undefined = this->call_data_undefined(); |
| 5841 bool is_lazy = this->is_lazy(); |
| 5842 CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store, |
| 5843 call_data_undefined, is_lazy); |
| 5844 } |
| 5845 |
| 5846 |
5802 void CallApiGetterStub::Generate(MacroAssembler* masm) { | 5847 void CallApiGetterStub::Generate(MacroAssembler* masm) { |
5803 // ----------- S t a t e ------------- | 5848 // ----------- S t a t e ------------- |
5804 // -- esp[0] : return address | 5849 // -- esp[0] : return address |
5805 // -- esp[4] : name | 5850 // -- esp[4] : name |
5806 // -- esp[8 .. (8 + kArgsLength*4)] : v8::PropertyCallbackInfo::args_ | 5851 // -- esp[8 .. (8 + kArgsLength*4)] : v8::PropertyCallbackInfo::args_ |
5807 // -- ... | 5852 // -- ... |
5808 // -- edx : api_function_address | 5853 // -- edx : api_function_address |
5809 // ----------------------------------- | 5854 // ----------------------------------- |
5810 DCHECK(edx.is(ApiGetterDescriptor::function_address())); | 5855 DCHECK(edx.is(ApiGetterDescriptor::function_address())); |
5811 | 5856 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5847 return_value_operand, NULL); | 5892 return_value_operand, NULL); |
5848 } | 5893 } |
5849 | 5894 |
5850 | 5895 |
5851 #undef __ | 5896 #undef __ |
5852 | 5897 |
5853 } // namespace internal | 5898 } // namespace internal |
5854 } // namespace v8 | 5899 } // namespace v8 |
5855 | 5900 |
5856 #endif // V8_TARGET_ARCH_IA32 | 5901 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |