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/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
886 { | 886 { |
887 Label done_loop, loop; | 887 Label done_loop, loop; |
888 __ bind(&loop); | 888 __ bind(&loop); |
889 __ Subu(a3, a3, Operand(Smi::FromInt(1))); | 889 __ Subu(a3, a3, Operand(Smi::FromInt(1))); |
890 __ Branch(&done_loop, lt, a3, Operand(zero_reg)); | 890 __ Branch(&done_loop, lt, a3, Operand(zero_reg)); |
891 __ PushRoot(Heap::kTheHoleValueRootIndex); | 891 __ PushRoot(Heap::kTheHoleValueRootIndex); |
892 __ Branch(&loop); | 892 __ Branch(&loop); |
893 __ bind(&done_loop); | 893 __ bind(&done_loop); |
894 } | 894 } |
895 | 895 |
896 // Enter a new JavaScript frame, and initialize its slots as they were when | 896 // Dispatch on the kind of generator object. |
897 // the generator was suspended. | 897 Label old_generator; |
898 FrameScope scope(masm, StackFrame::MANUAL); | 898 __ lw(a3, FieldMemOperand(t0, JSFunction::kSharedFunctionInfoOffset)); |
899 __ Push(ra, fp); | 899 __ lw(a3, FieldMemOperand(a3, SharedFunctionInfo::kFunctionDataOffset)); |
900 __ Move(fp, sp); | 900 __ GetObjectType(a3, a3, a3); |
901 __ Push(cp, t0); | 901 __ Branch(&old_generator, ne, a3, Operand(BYTECODE_ARRAY_TYPE)); |
902 | 902 |
903 // Restore the operand stack. | 903 // New-style (ignition/turbofan) generator object. |
904 __ lw(a0, FieldMemOperand(a1, JSGeneratorObject::kOperandStackOffset)); | |
905 __ lw(a3, FieldMemOperand(a0, FixedArray::kLengthOffset)); | |
906 __ Addu(a0, a0, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | |
907 __ Lsa(a3, a0, a3, kPointerSizeLog2 - 1); | |
908 { | 904 { |
909 Label done_loop, loop; | 905 __ lw(a0, FieldMemOperand(t0, JSFunction::kSharedFunctionInfoOffset)); |
910 __ bind(&loop); | 906 __ lw(a0, |
911 __ Branch(&done_loop, eq, a0, Operand(a3)); | 907 FieldMemOperand(a0, SharedFunctionInfo::kFormalParameterCountOffset)); |
912 __ lw(t1, MemOperand(a0)); | 908 __ SmiUntag(a0); |
913 __ Push(t1); | 909 // We abuse new.target both to indicate that this is a resume call and to |
914 __ Branch(USE_DELAY_SLOT, &loop); | 910 // pass in the generator object. In ordinary calls, new.target is always |
915 __ addiu(a0, a0, kPointerSize); // In delay slot. | 911 // undefined because generator functions are non-constructable. |
916 __ bind(&done_loop); | 912 __ Move(a3, a1); |
| 913 __ Move(a1, t0); |
| 914 __ lw(a2, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
| 915 __ Jump(a2); |
917 } | 916 } |
918 | 917 |
919 // Reset operand stack so we don't leak. | 918 // Old-style (full-codegen) generator object |
920 __ LoadRoot(t1, Heap::kEmptyFixedArrayRootIndex); | 919 __ bind(&old_generator); |
921 __ sw(t1, FieldMemOperand(a1, JSGeneratorObject::kOperandStackOffset)); | 920 { |
| 921 // Enter a new JavaScript frame, and initialize its slots as they were when |
| 922 // the generator was suspended. |
| 923 FrameScope scope(masm, StackFrame::MANUAL); |
| 924 __ Push(ra, fp); |
| 925 __ Move(fp, sp); |
| 926 __ Push(cp, t0); |
922 | 927 |
923 // Resume the generator function at the continuation. | 928 // Restore the operand stack. |
924 __ lw(a3, FieldMemOperand(t0, JSFunction::kSharedFunctionInfoOffset)); | 929 __ lw(a0, FieldMemOperand(a1, JSGeneratorObject::kOperandStackOffset)); |
925 __ lw(a3, FieldMemOperand(a3, SharedFunctionInfo::kCodeOffset)); | 930 __ lw(a3, FieldMemOperand(a0, FixedArray::kLengthOffset)); |
926 __ Addu(a3, a3, Operand(Code::kHeaderSize - kHeapObjectTag)); | 931 __ Addu(a0, a0, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
927 __ lw(a2, FieldMemOperand(a1, JSGeneratorObject::kContinuationOffset)); | 932 __ Lsa(a3, a0, a3, kPointerSizeLog2 - 1); |
928 __ SmiUntag(a2); | 933 { |
929 __ Addu(a3, a3, Operand(a2)); | 934 Label done_loop, loop; |
930 __ li(a2, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))); | 935 __ bind(&loop); |
931 __ sw(a2, FieldMemOperand(a1, JSGeneratorObject::kContinuationOffset)); | 936 __ Branch(&done_loop, eq, a0, Operand(a3)); |
932 __ Move(v0, a1); // Continuation expects generator object in v0. | 937 __ lw(t1, MemOperand(a0)); |
933 __ Jump(a3); | 938 __ Push(t1); |
| 939 __ Branch(USE_DELAY_SLOT, &loop); |
| 940 __ addiu(a0, a0, kPointerSize); // In delay slot. |
| 941 __ bind(&done_loop); |
| 942 } |
| 943 |
| 944 // Reset operand stack so we don't leak. |
| 945 __ LoadRoot(t1, Heap::kEmptyFixedArrayRootIndex); |
| 946 __ sw(t1, FieldMemOperand(a1, JSGeneratorObject::kOperandStackOffset)); |
| 947 |
| 948 // Resume the generator function at the continuation. |
| 949 __ lw(a3, FieldMemOperand(t0, JSFunction::kSharedFunctionInfoOffset)); |
| 950 __ lw(a3, FieldMemOperand(a3, SharedFunctionInfo::kCodeOffset)); |
| 951 __ Addu(a3, a3, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 952 __ lw(a2, FieldMemOperand(a1, JSGeneratorObject::kContinuationOffset)); |
| 953 __ SmiUntag(a2); |
| 954 __ Addu(a3, a3, Operand(a2)); |
| 955 __ li(a2, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))); |
| 956 __ sw(a2, FieldMemOperand(a1, JSGeneratorObject::kContinuationOffset)); |
| 957 __ Move(v0, a1); // Continuation expects generator object in v0. |
| 958 __ Jump(a3); |
| 959 } |
934 } | 960 } |
935 | 961 |
936 // Generate code for entering a JS function with the interpreter. | 962 // Generate code for entering a JS function with the interpreter. |
937 // On entry to the function the receiver and arguments have been pushed on the | 963 // On entry to the function the receiver and arguments have been pushed on the |
938 // stack left to right. The actual argument count matches the formal parameter | 964 // stack left to right. The actual argument count matches the formal parameter |
939 // count expected by the function. | 965 // count expected by the function. |
940 // | 966 // |
941 // The live registers are: | 967 // The live registers are: |
942 // o a1: the JS function object being called. | 968 // o a1: the JS function object being called. |
943 // o a3: the new target | 969 // o a3: the new target |
(...skipping 1900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2844 } | 2870 } |
2845 } | 2871 } |
2846 | 2872 |
2847 | 2873 |
2848 #undef __ | 2874 #undef __ |
2849 | 2875 |
2850 } // namespace internal | 2876 } // namespace internal |
2851 } // namespace v8 | 2877 } // namespace v8 |
2852 | 2878 |
2853 #endif // V8_TARGET_ARCH_MIPS | 2879 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |