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