| 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 // Note on Mips implementation: | 7 // Note on Mips implementation: |
| 8 // | 8 // |
| 9 // The result_register() for mips is the 'v0' register, which is defined | 9 // The result_register() for mips is the 'v0' register, which is defined |
| 10 // by the ABI to contain function return values. However, the first | 10 // by the ABI to contain function return values. However, the first |
| (...skipping 972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 983 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 983 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
| 984 } | 984 } |
| 985 | 985 |
| 986 | 986 |
| 987 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 987 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
| 988 Comment cmnt(masm_, "[ ForInStatement"); | 988 Comment cmnt(masm_, "[ ForInStatement"); |
| 989 SetStatementPosition(stmt, SKIP_BREAK); | 989 SetStatementPosition(stmt, SKIP_BREAK); |
| 990 | 990 |
| 991 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); | 991 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); |
| 992 | 992 |
| 993 Label loop, exit; | |
| 994 ForIn loop_statement(this, stmt); | |
| 995 increment_loop_depth(); | |
| 996 | |
| 997 // Get the object to enumerate over. | 993 // Get the object to enumerate over. |
| 998 SetExpressionAsStatementPosition(stmt->enumerable()); | 994 SetExpressionAsStatementPosition(stmt->enumerable()); |
| 999 VisitForAccumulatorValue(stmt->enumerable()); | 995 VisitForAccumulatorValue(stmt->enumerable()); |
| 1000 __ mov(a0, result_register()); | 996 __ mov(a0, result_register()); |
| 1001 OperandStackDepthIncrement(ForIn::kElementCount); | 997 OperandStackDepthIncrement(5); |
| 998 |
| 999 Label loop, exit; |
| 1000 Iteration loop_statement(this, stmt); |
| 1001 increment_loop_depth(); |
| 1002 | 1002 |
| 1003 // If the object is null or undefined, skip over the loop, otherwise convert | 1003 // If the object is null or undefined, skip over the loop, otherwise convert |
| 1004 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. | 1004 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. |
| 1005 Label convert, done_convert; | 1005 Label convert, done_convert; |
| 1006 __ JumpIfSmi(a0, &convert); | 1006 __ JumpIfSmi(a0, &convert); |
| 1007 __ GetObjectType(a0, a1, a1); | 1007 __ GetObjectType(a0, a1, a1); |
| 1008 __ Branch(USE_DELAY_SLOT, &done_convert, ge, a1, | 1008 __ Branch(USE_DELAY_SLOT, &done_convert, ge, a1, |
| 1009 Operand(FIRST_JS_RECEIVER_TYPE)); | 1009 Operand(FIRST_JS_RECEIVER_TYPE)); |
| 1010 __ LoadRoot(at, Heap::kNullValueRootIndex); // In delay slot. | 1010 __ LoadRoot(at, Heap::kNullValueRootIndex); // In delay slot. |
| 1011 __ Branch(USE_DELAY_SLOT, &exit, eq, a0, Operand(at)); | 1011 __ Branch(USE_DELAY_SLOT, &exit, eq, a0, Operand(at)); |
| (...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1879 SetExpressionPosition(expr); | 1879 SetExpressionPosition(expr); |
| 1880 | 1880 |
| 1881 // Evaluate yielded value first; the initial iterator definition depends on | 1881 // Evaluate yielded value first; the initial iterator definition depends on |
| 1882 // this. It stays on the stack while we update the iterator. | 1882 // this. It stays on the stack while we update the iterator. |
| 1883 VisitForStackValue(expr->expression()); | 1883 VisitForStackValue(expr->expression()); |
| 1884 | 1884 |
| 1885 switch (expr->yield_kind()) { | 1885 switch (expr->yield_kind()) { |
| 1886 case Yield::kSuspend: | 1886 case Yield::kSuspend: |
| 1887 // Pop value from top-of-stack slot; box result into result register. | 1887 // Pop value from top-of-stack slot; box result into result register. |
| 1888 EmitCreateIteratorResult(false); | 1888 EmitCreateIteratorResult(false); |
| 1889 __ push(result_register()); | 1889 PushOperand(result_register()); |
| 1890 // Fall through. | 1890 // Fall through. |
| 1891 case Yield::kInitial: { | 1891 case Yield::kInitial: { |
| 1892 Label suspend, continuation, post_runtime, resume; | 1892 Label suspend, continuation, post_runtime, resume; |
| 1893 | 1893 |
| 1894 __ jmp(&suspend); | 1894 __ jmp(&suspend); |
| 1895 __ bind(&continuation); | 1895 __ bind(&continuation); |
| 1896 // When we arrive here, the stack top is the resume mode and | 1896 // When we arrive here, the stack top is the resume mode and |
| 1897 // result_register() holds the input value (the argument given to the | 1897 // result_register() holds the input value (the argument given to the |
| 1898 // respective resume operation). | 1898 // respective resume operation). |
| 1899 __ RecordGeneratorContinuation(); | 1899 __ RecordGeneratorContinuation(); |
| 1900 __ pop(a1); | 1900 __ pop(a1); |
| 1901 __ Branch(&resume, ne, a1, | 1901 __ Branch(&resume, ne, a1, |
| 1902 Operand(Smi::FromInt(JSGeneratorObject::RETURN))); | 1902 Operand(Smi::FromInt(JSGeneratorObject::RETURN))); |
| 1903 __ push(result_register()); | 1903 __ push(result_register()); |
| 1904 EmitCreateIteratorResult(true); | 1904 EmitCreateIteratorResult(true); |
| 1905 EmitUnwindAndReturn(); | 1905 EmitUnwindAndReturn(); |
| 1906 | 1906 |
| 1907 __ bind(&suspend); | 1907 __ bind(&suspend); |
| 1908 OperandStackDepthIncrement(1); // Not popped on this path. |
| 1908 VisitForAccumulatorValue(expr->generator_object()); | 1909 VisitForAccumulatorValue(expr->generator_object()); |
| 1909 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); | 1910 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); |
| 1910 __ li(a1, Operand(Smi::FromInt(continuation.pos()))); | 1911 __ li(a1, Operand(Smi::FromInt(continuation.pos()))); |
| 1911 __ sw(a1, FieldMemOperand(v0, JSGeneratorObject::kContinuationOffset)); | 1912 __ sw(a1, FieldMemOperand(v0, JSGeneratorObject::kContinuationOffset)); |
| 1912 __ sw(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset)); | 1913 __ sw(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset)); |
| 1913 __ mov(a1, cp); | 1914 __ mov(a1, cp); |
| 1914 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2, | 1915 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2, |
| 1915 kRAHasBeenSaved, kDontSaveFPRegs); | 1916 kRAHasBeenSaved, kDontSaveFPRegs); |
| 1916 __ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); | 1917 __ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); |
| 1917 __ Branch(&post_runtime, eq, sp, Operand(a1)); | 1918 __ Branch(&post_runtime, eq, sp, Operand(a1)); |
| 1918 __ push(v0); // generator object | 1919 __ push(v0); // generator object |
| 1919 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 1920 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
| 1920 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1921 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 1921 __ bind(&post_runtime); | 1922 __ bind(&post_runtime); |
| 1922 PopOperand(result_register()); | 1923 PopOperand(result_register()); |
| 1923 EmitReturnSequence(); | 1924 EmitReturnSequence(); |
| 1924 | 1925 |
| 1925 __ bind(&resume); | 1926 __ bind(&resume); |
| 1926 context()->Plug(result_register()); | 1927 context()->Plug(result_register()); |
| 1927 break; | 1928 break; |
| 1928 } | 1929 } |
| 1929 | 1930 |
| 1930 case Yield::kFinal: { | 1931 case Yield::kFinal: { |
| 1931 // Pop value from top-of-stack slot, box result into result register. | 1932 // Pop value from top-of-stack slot, box result into result register. |
| 1932 OperandStackDepthDecrement(1); | |
| 1933 EmitCreateIteratorResult(true); | 1933 EmitCreateIteratorResult(true); |
| 1934 EmitUnwindAndReturn(); | 1934 EmitUnwindAndReturn(); |
| 1935 break; | 1935 break; |
| 1936 } | 1936 } |
| 1937 | 1937 |
| 1938 case Yield::kDelegating: | 1938 case Yield::kDelegating: |
| 1939 UNREACHABLE(); | 1939 UNREACHABLE(); |
| 1940 } | 1940 } |
| 1941 } | 1941 } |
| 1942 | 1942 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2072 | 2072 |
| 2073 __ Allocate(JSIteratorResult::kSize, v0, a2, a3, &allocate, TAG_OBJECT); | 2073 __ Allocate(JSIteratorResult::kSize, v0, a2, a3, &allocate, TAG_OBJECT); |
| 2074 __ jmp(&done_allocate); | 2074 __ jmp(&done_allocate); |
| 2075 | 2075 |
| 2076 __ bind(&allocate); | 2076 __ bind(&allocate); |
| 2077 __ Push(Smi::FromInt(JSIteratorResult::kSize)); | 2077 __ Push(Smi::FromInt(JSIteratorResult::kSize)); |
| 2078 __ CallRuntime(Runtime::kAllocateInNewSpace); | 2078 __ CallRuntime(Runtime::kAllocateInNewSpace); |
| 2079 | 2079 |
| 2080 __ bind(&done_allocate); | 2080 __ bind(&done_allocate); |
| 2081 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, a1); | 2081 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, a1); |
| 2082 __ pop(a2); | 2082 PopOperand(a2); |
| 2083 __ LoadRoot(a3, | 2083 __ LoadRoot(a3, |
| 2084 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); | 2084 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); |
| 2085 __ LoadRoot(t0, Heap::kEmptyFixedArrayRootIndex); | 2085 __ LoadRoot(t0, Heap::kEmptyFixedArrayRootIndex); |
| 2086 __ sw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); | 2086 __ sw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); |
| 2087 __ sw(t0, FieldMemOperand(v0, JSObject::kPropertiesOffset)); | 2087 __ sw(t0, FieldMemOperand(v0, JSObject::kPropertiesOffset)); |
| 2088 __ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset)); | 2088 __ sw(t0, FieldMemOperand(v0, JSObject::kElementsOffset)); |
| 2089 __ sw(a2, FieldMemOperand(v0, JSIteratorResult::kValueOffset)); | 2089 __ sw(a2, FieldMemOperand(v0, JSIteratorResult::kValueOffset)); |
| 2090 __ sw(a3, FieldMemOperand(v0, JSIteratorResult::kDoneOffset)); | 2090 __ sw(a3, FieldMemOperand(v0, JSIteratorResult::kDoneOffset)); |
| 2091 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); | 2091 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); |
| 2092 } | 2092 } |
| (...skipping 2163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4256 reinterpret_cast<uint32_t>( | 4256 reinterpret_cast<uint32_t>( |
| 4257 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4257 isolate->builtins()->OsrAfterStackCheck()->entry())); |
| 4258 return OSR_AFTER_STACK_CHECK; | 4258 return OSR_AFTER_STACK_CHECK; |
| 4259 } | 4259 } |
| 4260 | 4260 |
| 4261 | 4261 |
| 4262 } // namespace internal | 4262 } // namespace internal |
| 4263 } // namespace v8 | 4263 } // namespace v8 |
| 4264 | 4264 |
| 4265 #endif // V8_TARGET_ARCH_MIPS | 4265 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |