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