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_MIPS | 5 #if V8_TARGET_ARCH_MIPS |
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 5576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5587 __ mov(s0, v0); | 5587 __ mov(s0, v0); |
5588 __ mov(a0, v0); | 5588 __ mov(a0, v0); |
5589 __ PrepareCallCFunction(1, s1); | 5589 __ PrepareCallCFunction(1, s1); |
5590 __ li(a0, Operand(ExternalReference::isolate_address(isolate))); | 5590 __ li(a0, Operand(ExternalReference::isolate_address(isolate))); |
5591 __ CallCFunction(ExternalReference::delete_handle_scope_extensions(isolate), | 5591 __ CallCFunction(ExternalReference::delete_handle_scope_extensions(isolate), |
5592 1); | 5592 1); |
5593 __ mov(v0, s0); | 5593 __ mov(v0, s0); |
5594 __ jmp(&leave_exit_frame); | 5594 __ jmp(&leave_exit_frame); |
5595 } | 5595 } |
5596 | 5596 |
5597 static void CallApiFunctionStubHelper(MacroAssembler* masm, | 5597 void CallApiCallbackStub::Generate(MacroAssembler* masm) { |
5598 const ParameterCount& argc, | |
5599 bool return_first_arg, | |
5600 bool call_data_undefined, bool is_lazy) { | |
5601 // ----------- S t a t e ------------- | 5598 // ----------- S t a t e ------------- |
5602 // -- a0 : callee | 5599 // -- a0 : callee |
5603 // -- t0 : call_data | 5600 // -- t0 : call_data |
5604 // -- a2 : holder | 5601 // -- a2 : holder |
5605 // -- a1 : api_function_address | 5602 // -- a1 : api_function_address |
5606 // -- a3 : number of arguments if argc is a register | |
5607 // -- cp : context | 5603 // -- cp : context |
5608 // -- | 5604 // -- |
5609 // -- sp[0] : last argument | 5605 // -- sp[0] : last argument |
5610 // -- ... | 5606 // -- ... |
5611 // -- sp[(argc - 1)* 4] : first argument | 5607 // -- sp[(argc - 1)* 4] : first argument |
5612 // -- sp[argc * 4] : receiver | 5608 // -- sp[argc * 4] : receiver |
5613 // ----------------------------------- | 5609 // ----------------------------------- |
5614 | 5610 |
5615 Register callee = a0; | 5611 Register callee = a0; |
5616 Register call_data = t0; | 5612 Register call_data = t0; |
5617 Register holder = a2; | 5613 Register holder = a2; |
5618 Register api_function_address = a1; | 5614 Register api_function_address = a1; |
5619 Register context = cp; | 5615 Register context = cp; |
5620 | 5616 |
5621 typedef FunctionCallbackArguments FCA; | 5617 typedef FunctionCallbackArguments FCA; |
5622 | 5618 |
5623 STATIC_ASSERT(FCA::kContextSaveIndex == 6); | 5619 STATIC_ASSERT(FCA::kContextSaveIndex == 6); |
5624 STATIC_ASSERT(FCA::kCalleeIndex == 5); | 5620 STATIC_ASSERT(FCA::kCalleeIndex == 5); |
5625 STATIC_ASSERT(FCA::kDataIndex == 4); | 5621 STATIC_ASSERT(FCA::kDataIndex == 4); |
5626 STATIC_ASSERT(FCA::kReturnValueOffset == 3); | 5622 STATIC_ASSERT(FCA::kReturnValueOffset == 3); |
5627 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); | 5623 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); |
5628 STATIC_ASSERT(FCA::kIsolateIndex == 1); | 5624 STATIC_ASSERT(FCA::kIsolateIndex == 1); |
5629 STATIC_ASSERT(FCA::kHolderIndex == 0); | 5625 STATIC_ASSERT(FCA::kHolderIndex == 0); |
5630 STATIC_ASSERT(FCA::kArgsLength == 7); | 5626 STATIC_ASSERT(FCA::kArgsLength == 7); |
5631 | 5627 |
5632 DCHECK(argc.is_immediate() || a3.is(argc.reg())); | |
5633 | |
5634 // Save context, callee and call data. | 5628 // Save context, callee and call data. |
5635 __ Push(context, callee, call_data); | 5629 __ Push(context, callee, call_data); |
5636 if (!is_lazy) { | 5630 if (!is_lazy()) { |
5637 // Load context from callee. | 5631 // Load context from callee. |
5638 __ lw(context, FieldMemOperand(callee, JSFunction::kContextOffset)); | 5632 __ lw(context, FieldMemOperand(callee, JSFunction::kContextOffset)); |
5639 } | 5633 } |
5640 | 5634 |
5641 Register scratch = call_data; | 5635 Register scratch = call_data; |
5642 if (!call_data_undefined) { | 5636 if (!call_data_undefined()) { |
5643 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); | 5637 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); |
5644 } | 5638 } |
5645 // Push return value and default return value. | 5639 // Push return value and default return value. |
5646 __ Push(scratch, scratch); | 5640 __ Push(scratch, scratch); |
5647 __ li(scratch, Operand(ExternalReference::isolate_address(masm->isolate()))); | 5641 __ li(scratch, Operand(ExternalReference::isolate_address(masm->isolate()))); |
5648 // Push isolate and holder. | 5642 // Push isolate and holder. |
5649 __ Push(scratch, holder); | 5643 __ Push(scratch, holder); |
5650 | 5644 |
5651 // Prepare arguments. | 5645 // Prepare arguments. |
5652 __ mov(scratch, sp); | 5646 __ mov(scratch, sp); |
5653 | 5647 |
5654 // Allocate the v8::Arguments structure in the arguments' space since | 5648 // Allocate the v8::Arguments structure in the arguments' space since |
5655 // it's not controlled by GC. | 5649 // it's not controlled by GC. |
5656 const int kApiStackSpace = 4; | 5650 const int kApiStackSpace = 4; |
5657 | 5651 |
5658 FrameScope frame_scope(masm, StackFrame::MANUAL); | 5652 FrameScope frame_scope(masm, StackFrame::MANUAL); |
5659 __ EnterExitFrame(false, kApiStackSpace); | 5653 __ EnterExitFrame(false, kApiStackSpace); |
5660 | 5654 |
5661 DCHECK(!api_function_address.is(a0) && !scratch.is(a0)); | 5655 DCHECK(!api_function_address.is(a0) && !scratch.is(a0)); |
5662 // a0 = FunctionCallbackInfo& | 5656 // a0 = FunctionCallbackInfo& |
5663 // Arguments is after the return address. | 5657 // Arguments is after the return address. |
5664 __ Addu(a0, sp, Operand(1 * kPointerSize)); | 5658 __ Addu(a0, sp, Operand(1 * kPointerSize)); |
5665 // FunctionCallbackInfo::implicit_args_ | 5659 // FunctionCallbackInfo::implicit_args_ |
5666 __ sw(scratch, MemOperand(a0, 0 * kPointerSize)); | 5660 __ sw(scratch, MemOperand(a0, 0 * kPointerSize)); |
5667 if (argc.is_immediate()) { | 5661 // FunctionCallbackInfo::values_ |
5668 // FunctionCallbackInfo::values_ | 5662 __ Addu(at, scratch, Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize)); |
5669 __ Addu(at, scratch, | 5663 __ sw(at, MemOperand(a0, 1 * kPointerSize)); |
5670 Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize)); | 5664 // FunctionCallbackInfo::length_ = argc |
5671 __ sw(at, MemOperand(a0, 1 * kPointerSize)); | 5665 __ li(at, Operand(argc())); |
5672 // FunctionCallbackInfo::length_ = argc | 5666 __ sw(at, MemOperand(a0, 2 * kPointerSize)); |
5673 __ li(at, Operand(argc.immediate())); | 5667 // FunctionCallbackInfo::is_construct_call_ = 0 |
5674 __ sw(at, MemOperand(a0, 2 * kPointerSize)); | 5668 __ sw(zero_reg, MemOperand(a0, 3 * kPointerSize)); |
5675 // FunctionCallbackInfo::is_construct_call_ = 0 | |
5676 __ sw(zero_reg, MemOperand(a0, 3 * kPointerSize)); | |
5677 } else { | |
5678 // FunctionCallbackInfo::values_ | |
5679 __ sll(at, argc.reg(), kPointerSizeLog2); | |
5680 __ Addu(at, at, scratch); | |
5681 __ Addu(at, at, Operand((FCA::kArgsLength - 1) * kPointerSize)); | |
5682 __ sw(at, MemOperand(a0, 1 * kPointerSize)); | |
5683 // FunctionCallbackInfo::length_ = argc | |
5684 __ sw(argc.reg(), MemOperand(a0, 2 * kPointerSize)); | |
5685 // FunctionCallbackInfo::is_construct_call_ | |
5686 __ Addu(argc.reg(), argc.reg(), Operand(FCA::kArgsLength + 1)); | |
5687 __ sll(at, argc.reg(), kPointerSizeLog2); | |
5688 __ sw(at, MemOperand(a0, 3 * kPointerSize)); | |
5689 } | |
5690 | 5669 |
5691 ExternalReference thunk_ref = | 5670 ExternalReference thunk_ref = |
5692 ExternalReference::invoke_function_callback(masm->isolate()); | 5671 ExternalReference::invoke_function_callback(masm->isolate()); |
5693 | 5672 |
5694 AllowExternalCallThatCantCauseGC scope(masm); | 5673 AllowExternalCallThatCantCauseGC scope(masm); |
5695 MemOperand context_restore_operand( | 5674 MemOperand context_restore_operand( |
5696 fp, (2 + FCA::kContextSaveIndex) * kPointerSize); | 5675 fp, (2 + FCA::kContextSaveIndex) * kPointerSize); |
5697 // Stores return the first js argument. | 5676 // Stores return the first js argument. |
5698 int return_value_offset = 0; | 5677 int return_value_offset = 0; |
5699 if (return_first_arg) { | 5678 if (is_store()) { |
5700 return_value_offset = 2 + FCA::kArgsLength; | 5679 return_value_offset = 2 + FCA::kArgsLength; |
5701 } else { | 5680 } else { |
5702 return_value_offset = 2 + FCA::kReturnValueOffset; | 5681 return_value_offset = 2 + FCA::kReturnValueOffset; |
5703 } | 5682 } |
5704 MemOperand return_value_operand(fp, return_value_offset * kPointerSize); | 5683 MemOperand return_value_operand(fp, return_value_offset * kPointerSize); |
5705 int stack_space = 0; | 5684 int stack_space = 0; |
5706 int32_t stack_space_offset = 4 * kPointerSize; | 5685 int32_t stack_space_offset = 4 * kPointerSize; |
5707 if (argc.is_immediate()) { | 5686 stack_space = argc() + FCA::kArgsLength + 1; |
5708 stack_space = argc.immediate() + FCA::kArgsLength + 1; | 5687 stack_space_offset = kInvalidStackOffset; |
5709 stack_space_offset = kInvalidStackOffset; | |
5710 } | |
5711 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space, | 5688 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space, |
5712 stack_space_offset, return_value_operand, | 5689 stack_space_offset, return_value_operand, |
5713 &context_restore_operand); | 5690 &context_restore_operand); |
5714 } | 5691 } |
5715 | 5692 |
5716 | 5693 |
5717 void CallApiFunctionStub::Generate(MacroAssembler* masm) { | |
5718 bool call_data_undefined = this->call_data_undefined(); | |
5719 CallApiFunctionStubHelper(masm, ParameterCount(a3), false, | |
5720 call_data_undefined, false); | |
5721 } | |
5722 | |
5723 | |
5724 void CallApiAccessorStub::Generate(MacroAssembler* masm) { | |
5725 bool is_store = this->is_store(); | |
5726 int argc = this->argc(); | |
5727 bool call_data_undefined = this->call_data_undefined(); | |
5728 bool is_lazy = this->is_lazy(); | |
5729 CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store, | |
5730 call_data_undefined, is_lazy); | |
5731 } | |
5732 | |
5733 | |
5734 void CallApiGetterStub::Generate(MacroAssembler* masm) { | 5694 void CallApiGetterStub::Generate(MacroAssembler* masm) { |
5735 // ----------- S t a t e ------------- | 5695 // ----------- S t a t e ------------- |
5736 // -- sp[0] : name | 5696 // -- sp[0] : name |
5737 // -- sp[4 .. (4 + kArgsLength*4)] : v8::PropertyCallbackInfo::args_ | 5697 // -- sp[4 .. (4 + kArgsLength*4)] : v8::PropertyCallbackInfo::args_ |
5738 // -- ... | 5698 // -- ... |
5739 // -- a2 : api_function_address | 5699 // -- a2 : api_function_address |
5740 // ----------------------------------- | 5700 // ----------------------------------- |
5741 | 5701 |
5742 Register api_function_address = ApiGetterDescriptor::function_address(); | 5702 Register api_function_address = ApiGetterDescriptor::function_address(); |
5743 DCHECK(api_function_address.is(a2)); | 5703 DCHECK(api_function_address.is(a2)); |
(...skipping 25 matching lines...) Expand all Loading... |
5769 return_value_operand, NULL); | 5729 return_value_operand, NULL); |
5770 } | 5730 } |
5771 | 5731 |
5772 | 5732 |
5773 #undef __ | 5733 #undef __ |
5774 | 5734 |
5775 } // namespace internal | 5735 } // namespace internal |
5776 } // namespace v8 | 5736 } // namespace v8 |
5777 | 5737 |
5778 #endif // V8_TARGET_ARCH_MIPS | 5738 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |