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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 4815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4826 | 4826 |
4827 Label fast_elements_case; | 4827 Label fast_elements_case; |
4828 __ Branch(&fast_elements_case, eq, a3, Operand(FAST_ELEMENTS)); | 4828 __ Branch(&fast_elements_case, eq, a3, Operand(FAST_ELEMENTS)); |
4829 GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 4829 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
4830 | 4830 |
4831 __ bind(&fast_elements_case); | 4831 __ bind(&fast_elements_case); |
4832 GenerateCase(masm, FAST_ELEMENTS); | 4832 GenerateCase(masm, FAST_ELEMENTS); |
4833 } | 4833 } |
4834 | 4834 |
4835 | 4835 |
4836 void CallApiFunctionStub::Generate(MacroAssembler* masm) { | 4836 static void CallApiFunctionStubHelper(MacroAssembler* masm, |
| 4837 const ParameterCount& argc, |
| 4838 bool return_first_arg, |
| 4839 bool call_data_undefined) { |
4837 // ----------- S t a t e ------------- | 4840 // ----------- S t a t e ------------- |
4838 // -- a0 : callee | 4841 // -- a0 : callee |
4839 // -- t0 : call_data | 4842 // -- t0 : call_data |
4840 // -- a2 : holder | 4843 // -- a2 : holder |
4841 // -- a1 : api_function_address | 4844 // -- a1 : api_function_address |
| 4845 // -- a3 : number of arguments if argc is a register |
4842 // -- cp : context | 4846 // -- cp : context |
4843 // -- | 4847 // -- |
4844 // -- sp[0] : last argument | 4848 // -- sp[0] : last argument |
4845 // -- ... | 4849 // -- ... |
4846 // -- sp[(argc - 1)* 4] : first argument | 4850 // -- sp[(argc - 1)* 4] : first argument |
4847 // -- sp[argc * 4] : receiver | 4851 // -- sp[argc * 4] : receiver |
4848 // ----------------------------------- | 4852 // ----------------------------------- |
4849 | 4853 |
4850 Register callee = a0; | 4854 Register callee = a0; |
4851 Register call_data = t0; | 4855 Register call_data = t0; |
4852 Register holder = a2; | 4856 Register holder = a2; |
4853 Register api_function_address = a1; | 4857 Register api_function_address = a1; |
4854 Register context = cp; | 4858 Register context = cp; |
4855 | 4859 |
4856 int argc = this->argc(); | |
4857 bool is_store = this->is_store(); | |
4858 bool call_data_undefined = this->call_data_undefined(); | |
4859 | |
4860 typedef FunctionCallbackArguments FCA; | 4860 typedef FunctionCallbackArguments FCA; |
4861 | 4861 |
4862 STATIC_ASSERT(FCA::kContextSaveIndex == 6); | 4862 STATIC_ASSERT(FCA::kContextSaveIndex == 6); |
4863 STATIC_ASSERT(FCA::kCalleeIndex == 5); | 4863 STATIC_ASSERT(FCA::kCalleeIndex == 5); |
4864 STATIC_ASSERT(FCA::kDataIndex == 4); | 4864 STATIC_ASSERT(FCA::kDataIndex == 4); |
4865 STATIC_ASSERT(FCA::kReturnValueOffset == 3); | 4865 STATIC_ASSERT(FCA::kReturnValueOffset == 3); |
4866 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); | 4866 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); |
4867 STATIC_ASSERT(FCA::kIsolateIndex == 1); | 4867 STATIC_ASSERT(FCA::kIsolateIndex == 1); |
4868 STATIC_ASSERT(FCA::kHolderIndex == 0); | 4868 STATIC_ASSERT(FCA::kHolderIndex == 0); |
4869 STATIC_ASSERT(FCA::kArgsLength == 7); | 4869 STATIC_ASSERT(FCA::kArgsLength == 7); |
4870 | 4870 |
| 4871 DCHECK(argc.is_immediate() || a3.is(argc.reg())); |
| 4872 |
4871 // Save context, callee and call data. | 4873 // Save context, callee and call data. |
4872 __ Push(context, callee, call_data); | 4874 __ Push(context, callee, call_data); |
4873 // Load context from callee. | 4875 // Load context from callee. |
4874 __ lw(context, FieldMemOperand(callee, JSFunction::kContextOffset)); | 4876 __ lw(context, FieldMemOperand(callee, JSFunction::kContextOffset)); |
4875 | 4877 |
4876 Register scratch = call_data; | 4878 Register scratch = call_data; |
4877 if (!call_data_undefined) { | 4879 if (!call_data_undefined) { |
4878 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); | 4880 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); |
4879 } | 4881 } |
4880 // Push return value and default return value. | 4882 // Push return value and default return value. |
4881 __ Push(scratch, scratch); | 4883 __ Push(scratch, scratch); |
4882 __ li(scratch, | 4884 __ li(scratch, Operand(ExternalReference::isolate_address(masm->isolate()))); |
4883 Operand(ExternalReference::isolate_address(isolate()))); | |
4884 // Push isolate and holder. | 4885 // Push isolate and holder. |
4885 __ Push(scratch, holder); | 4886 __ Push(scratch, holder); |
4886 | 4887 |
4887 // Prepare arguments. | 4888 // Prepare arguments. |
4888 __ mov(scratch, sp); | 4889 __ mov(scratch, sp); |
4889 | 4890 |
4890 // Allocate the v8::Arguments structure in the arguments' space since | 4891 // Allocate the v8::Arguments structure in the arguments' space since |
4891 // it's not controlled by GC. | 4892 // it's not controlled by GC. |
4892 const int kApiStackSpace = 4; | 4893 const int kApiStackSpace = 4; |
4893 | 4894 |
4894 FrameScope frame_scope(masm, StackFrame::MANUAL); | 4895 FrameScope frame_scope(masm, StackFrame::MANUAL); |
4895 __ EnterExitFrame(false, kApiStackSpace); | 4896 __ EnterExitFrame(false, kApiStackSpace); |
4896 | 4897 |
4897 DCHECK(!api_function_address.is(a0) && !scratch.is(a0)); | 4898 DCHECK(!api_function_address.is(a0) && !scratch.is(a0)); |
4898 // a0 = FunctionCallbackInfo& | 4899 // a0 = FunctionCallbackInfo& |
4899 // Arguments is after the return address. | 4900 // Arguments is after the return address. |
4900 __ Addu(a0, sp, Operand(1 * kPointerSize)); | 4901 __ Addu(a0, sp, Operand(1 * kPointerSize)); |
4901 // FunctionCallbackInfo::implicit_args_ | 4902 // FunctionCallbackInfo::implicit_args_ |
4902 __ sw(scratch, MemOperand(a0, 0 * kPointerSize)); | 4903 __ sw(scratch, MemOperand(a0, 0 * kPointerSize)); |
4903 // FunctionCallbackInfo::values_ | 4904 if (argc.is_immediate()) { |
4904 __ Addu(at, scratch, Operand((FCA::kArgsLength - 1 + argc) * kPointerSize)); | 4905 // FunctionCallbackInfo::values_ |
4905 __ sw(at, MemOperand(a0, 1 * kPointerSize)); | 4906 __ Addu(at, scratch, |
4906 // FunctionCallbackInfo::length_ = argc | 4907 Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize)); |
4907 __ li(at, Operand(argc)); | 4908 __ sw(at, MemOperand(a0, 1 * kPointerSize)); |
4908 __ sw(at, MemOperand(a0, 2 * kPointerSize)); | 4909 // FunctionCallbackInfo::length_ = argc |
4909 // FunctionCallbackInfo::is_construct_call = 0 | 4910 __ li(at, Operand(argc.immediate())); |
4910 __ sw(zero_reg, MemOperand(a0, 3 * kPointerSize)); | 4911 __ sw(at, MemOperand(a0, 2 * kPointerSize)); |
| 4912 // FunctionCallbackInfo::is_construct_call_ = 0 |
| 4913 __ sw(zero_reg, MemOperand(a0, 3 * kPointerSize)); |
| 4914 } else { |
| 4915 // FunctionCallbackInfo::values_ |
| 4916 __ sll(at, argc.reg(), kPointerSizeLog2); |
| 4917 __ Addu(at, at, scratch); |
| 4918 __ Addu(at, at, Operand((FCA::kArgsLength - 1) * kPointerSize)); |
| 4919 __ sw(at, MemOperand(a0, 1 * kPointerSize)); |
| 4920 // FunctionCallbackInfo::length_ = argc |
| 4921 __ sw(argc.reg(), MemOperand(a0, 2 * kPointerSize)); |
| 4922 // FunctionCallbackInfo::is_construct_call_ |
| 4923 __ Addu(argc.reg(), argc.reg(), Operand(FCA::kArgsLength + 1)); |
| 4924 __ sll(at, argc.reg(), kPointerSizeLog2); |
| 4925 __ sw(at, MemOperand(a0, 3 * kPointerSize)); |
| 4926 } |
4911 | 4927 |
4912 const int kStackUnwindSpace = argc + FCA::kArgsLength + 1; | |
4913 ExternalReference thunk_ref = | 4928 ExternalReference thunk_ref = |
4914 ExternalReference::invoke_function_callback(isolate()); | 4929 ExternalReference::invoke_function_callback(masm->isolate()); |
4915 | 4930 |
4916 AllowExternalCallThatCantCauseGC scope(masm); | 4931 AllowExternalCallThatCantCauseGC scope(masm); |
4917 MemOperand context_restore_operand( | 4932 MemOperand context_restore_operand( |
4918 fp, (2 + FCA::kContextSaveIndex) * kPointerSize); | 4933 fp, (2 + FCA::kContextSaveIndex) * kPointerSize); |
4919 // Stores return the first js argument. | 4934 // Stores return the first js argument. |
4920 int return_value_offset = 0; | 4935 int return_value_offset = 0; |
4921 if (is_store) { | 4936 if (return_first_arg) { |
4922 return_value_offset = 2 + FCA::kArgsLength; | 4937 return_value_offset = 2 + FCA::kArgsLength; |
4923 } else { | 4938 } else { |
4924 return_value_offset = 2 + FCA::kReturnValueOffset; | 4939 return_value_offset = 2 + FCA::kReturnValueOffset; |
4925 } | 4940 } |
4926 MemOperand return_value_operand(fp, return_value_offset * kPointerSize); | 4941 MemOperand return_value_operand(fp, return_value_offset * kPointerSize); |
| 4942 int stack_space = 0; |
| 4943 MemOperand is_construct_call_operand = MemOperand(sp, 4 * kPointerSize); |
| 4944 MemOperand* stack_space_operand = &is_construct_call_operand; |
| 4945 if (argc.is_immediate()) { |
| 4946 stack_space = argc.immediate() + FCA::kArgsLength + 1; |
| 4947 stack_space_operand = NULL; |
| 4948 } |
| 4949 __ CallApiFunctionAndReturn(api_function_address, thunk_ref, stack_space, |
| 4950 stack_space_operand, return_value_operand, |
| 4951 &context_restore_operand); |
| 4952 } |
4927 | 4953 |
4928 __ CallApiFunctionAndReturn(api_function_address, | 4954 |
4929 thunk_ref, | 4955 void CallApiFunctionStub::Generate(MacroAssembler* masm) { |
4930 kStackUnwindSpace, | 4956 bool call_data_undefined = this->call_data_undefined(); |
4931 return_value_operand, | 4957 CallApiFunctionStubHelper(masm, ParameterCount(a3), false, |
4932 &context_restore_operand); | 4958 call_data_undefined); |
| 4959 } |
| 4960 |
| 4961 |
| 4962 void CallApiAccessorStub::Generate(MacroAssembler* masm) { |
| 4963 bool is_store = this->is_store(); |
| 4964 int argc = is_store ? 1 : 0; |
| 4965 bool call_data_undefined = this->call_data_undefined(); |
| 4966 CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store, |
| 4967 call_data_undefined); |
4933 } | 4968 } |
4934 | 4969 |
4935 | 4970 |
4936 void CallApiGetterStub::Generate(MacroAssembler* masm) { | 4971 void CallApiGetterStub::Generate(MacroAssembler* masm) { |
4937 // ----------- S t a t e ------------- | 4972 // ----------- S t a t e ------------- |
4938 // -- sp[0] : name | 4973 // -- sp[0] : name |
4939 // -- sp[4 - kArgsLength*4] : PropertyCallbackArguments object | 4974 // -- sp[4 - kArgsLength*4] : PropertyCallbackArguments object |
4940 // -- ... | 4975 // -- ... |
4941 // -- a2 : api_function_address | 4976 // -- a2 : api_function_address |
4942 // ----------------------------------- | 4977 // ----------------------------------- |
(...skipping 10 matching lines...) Expand all Loading... |
4953 | 4988 |
4954 // Create PropertyAccessorInfo instance on the stack above the exit frame with | 4989 // Create PropertyAccessorInfo instance on the stack above the exit frame with |
4955 // a1 (internal::Object** args_) as the data. | 4990 // a1 (internal::Object** args_) as the data. |
4956 __ sw(a1, MemOperand(sp, 1 * kPointerSize)); | 4991 __ sw(a1, MemOperand(sp, 1 * kPointerSize)); |
4957 __ Addu(a1, sp, Operand(1 * kPointerSize)); // a1 = AccessorInfo& | 4992 __ Addu(a1, sp, Operand(1 * kPointerSize)); // a1 = AccessorInfo& |
4958 | 4993 |
4959 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; | 4994 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; |
4960 | 4995 |
4961 ExternalReference thunk_ref = | 4996 ExternalReference thunk_ref = |
4962 ExternalReference::invoke_accessor_getter_callback(isolate()); | 4997 ExternalReference::invoke_accessor_getter_callback(isolate()); |
4963 __ CallApiFunctionAndReturn(api_function_address, | 4998 __ CallApiFunctionAndReturn(api_function_address, thunk_ref, |
4964 thunk_ref, | 4999 kStackUnwindSpace, NULL, |
4965 kStackUnwindSpace, | 5000 MemOperand(fp, 6 * kPointerSize), NULL); |
4966 MemOperand(fp, 6 * kPointerSize), | |
4967 NULL); | |
4968 } | 5001 } |
4969 | 5002 |
4970 | 5003 |
4971 #undef __ | 5004 #undef __ |
4972 | 5005 |
4973 } } // namespace v8::internal | 5006 } } // namespace v8::internal |
4974 | 5007 |
4975 #endif // V8_TARGET_ARCH_MIPS | 5008 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |