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_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
927 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 927 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
928 } | 928 } |
929 | 929 |
930 | 930 |
931 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 931 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
932 Comment cmnt(masm_, "[ ForInStatement"); | 932 Comment cmnt(masm_, "[ ForInStatement"); |
933 SetStatementPosition(stmt, SKIP_BREAK); | 933 SetStatementPosition(stmt, SKIP_BREAK); |
934 | 934 |
935 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); | 935 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); |
936 | 936 |
937 Label loop, exit; | |
938 ForIn loop_statement(this, stmt); | |
939 increment_loop_depth(); | |
940 | |
941 // Get the object to enumerate over. | 937 // Get the object to enumerate over. |
942 SetExpressionAsStatementPosition(stmt->enumerable()); | 938 SetExpressionAsStatementPosition(stmt->enumerable()); |
943 VisitForAccumulatorValue(stmt->enumerable()); | 939 VisitForAccumulatorValue(stmt->enumerable()); |
944 OperandStackDepthIncrement(ForIn::kElementCount); | 940 OperandStackDepthIncrement(5); |
| 941 |
| 942 Label loop, exit; |
| 943 Iteration loop_statement(this, stmt); |
| 944 increment_loop_depth(); |
945 | 945 |
946 // If the object is null or undefined, skip over the loop, otherwise convert | 946 // If the object is null or undefined, skip over the loop, otherwise convert |
947 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. | 947 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. |
948 Label convert, done_convert; | 948 Label convert, done_convert; |
949 __ JumpIfSmi(eax, &convert, Label::kNear); | 949 __ JumpIfSmi(eax, &convert, Label::kNear); |
950 __ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ecx); | 950 __ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ecx); |
951 __ j(above_equal, &done_convert, Label::kNear); | 951 __ j(above_equal, &done_convert, Label::kNear); |
952 __ cmp(eax, isolate()->factory()->undefined_value()); | 952 __ cmp(eax, isolate()->factory()->undefined_value()); |
953 __ j(equal, &exit); | 953 __ j(equal, &exit); |
954 __ cmp(eax, isolate()->factory()->null_value()); | 954 __ cmp(eax, isolate()->factory()->null_value()); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1082 // Generate code for going to the next element by incrementing the | 1082 // Generate code for going to the next element by incrementing the |
1083 // index (smi) stored on top of the stack. | 1083 // index (smi) stored on top of the stack. |
1084 __ bind(loop_statement.continue_label()); | 1084 __ bind(loop_statement.continue_label()); |
1085 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1))); | 1085 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1))); |
1086 | 1086 |
1087 EmitBackEdgeBookkeeping(stmt, &loop); | 1087 EmitBackEdgeBookkeeping(stmt, &loop); |
1088 __ jmp(&loop); | 1088 __ jmp(&loop); |
1089 | 1089 |
1090 // Remove the pointers stored on the stack. | 1090 // Remove the pointers stored on the stack. |
1091 __ bind(loop_statement.break_label()); | 1091 __ bind(loop_statement.break_label()); |
1092 __ add(esp, Immediate(5 * kPointerSize)); | 1092 DropOperands(5); |
1093 OperandStackDepthDecrement(ForIn::kElementCount); | |
1094 | 1093 |
1095 // Exit and decrement the loop depth. | 1094 // Exit and decrement the loop depth. |
1096 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1095 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
1097 __ bind(&exit); | 1096 __ bind(&exit); |
1098 decrement_loop_depth(); | 1097 decrement_loop_depth(); |
1099 } | 1098 } |
1100 | 1099 |
1101 | 1100 |
1102 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, | 1101 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, |
1103 bool pretenure) { | 1102 bool pretenure) { |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1798 SetExpressionPosition(expr); | 1797 SetExpressionPosition(expr); |
1799 | 1798 |
1800 // Evaluate yielded value first; the initial iterator definition depends on | 1799 // Evaluate yielded value first; the initial iterator definition depends on |
1801 // this. It stays on the stack while we update the iterator. | 1800 // this. It stays on the stack while we update the iterator. |
1802 VisitForStackValue(expr->expression()); | 1801 VisitForStackValue(expr->expression()); |
1803 | 1802 |
1804 switch (expr->yield_kind()) { | 1803 switch (expr->yield_kind()) { |
1805 case Yield::kSuspend: | 1804 case Yield::kSuspend: |
1806 // Pop value from top-of-stack slot; box result into result register. | 1805 // Pop value from top-of-stack slot; box result into result register. |
1807 EmitCreateIteratorResult(false); | 1806 EmitCreateIteratorResult(false); |
1808 __ push(result_register()); | 1807 PushOperand(result_register()); |
1809 // Fall through. | 1808 // Fall through. |
1810 case Yield::kInitial: { | 1809 case Yield::kInitial: { |
1811 Label suspend, continuation, post_runtime, resume; | 1810 Label suspend, continuation, post_runtime, resume; |
1812 | 1811 |
1813 __ jmp(&suspend); | 1812 __ jmp(&suspend); |
1814 __ bind(&continuation); | 1813 __ bind(&continuation); |
1815 // When we arrive here, the stack top is the resume mode and | 1814 // When we arrive here, the stack top is the resume mode and |
1816 // result_register() holds the input value (the argument given to the | 1815 // result_register() holds the input value (the argument given to the |
1817 // respective resume operation). | 1816 // respective resume operation). |
1818 __ RecordGeneratorContinuation(); | 1817 __ RecordGeneratorContinuation(); |
1819 __ pop(ebx); | 1818 __ pop(ebx); |
1820 __ cmp(ebx, Immediate(Smi::FromInt(JSGeneratorObject::RETURN))); | 1819 __ cmp(ebx, Immediate(Smi::FromInt(JSGeneratorObject::RETURN))); |
1821 __ j(not_equal, &resume); | 1820 __ j(not_equal, &resume); |
1822 __ push(result_register()); | 1821 __ push(result_register()); |
1823 EmitCreateIteratorResult(true); | 1822 EmitCreateIteratorResult(true); |
1824 EmitUnwindAndReturn(); | 1823 EmitUnwindAndReturn(); |
1825 | 1824 |
1826 __ bind(&suspend); | 1825 __ bind(&suspend); |
| 1826 OperandStackDepthIncrement(1); // Not popped on this path. |
1827 VisitForAccumulatorValue(expr->generator_object()); | 1827 VisitForAccumulatorValue(expr->generator_object()); |
1828 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); | 1828 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); |
1829 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), | 1829 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), |
1830 Immediate(Smi::FromInt(continuation.pos()))); | 1830 Immediate(Smi::FromInt(continuation.pos()))); |
1831 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); | 1831 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); |
1832 __ mov(ecx, esi); | 1832 __ mov(ecx, esi); |
1833 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, | 1833 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, |
1834 kDontSaveFPRegs); | 1834 kDontSaveFPRegs); |
1835 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset)); | 1835 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset)); |
1836 __ cmp(esp, ebx); | 1836 __ cmp(esp, ebx); |
1837 __ j(equal, &post_runtime); | 1837 __ j(equal, &post_runtime); |
1838 __ push(eax); // generator object | 1838 __ push(eax); // generator object |
1839 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 1839 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
1840 __ mov(context_register(), | 1840 __ mov(context_register(), |
1841 Operand(ebp, StandardFrameConstants::kContextOffset)); | 1841 Operand(ebp, StandardFrameConstants::kContextOffset)); |
1842 __ bind(&post_runtime); | 1842 __ bind(&post_runtime); |
1843 PopOperand(result_register()); | 1843 PopOperand(result_register()); |
1844 EmitReturnSequence(); | 1844 EmitReturnSequence(); |
1845 | 1845 |
1846 __ bind(&resume); | 1846 __ bind(&resume); |
1847 context()->Plug(result_register()); | 1847 context()->Plug(result_register()); |
1848 break; | 1848 break; |
1849 } | 1849 } |
1850 | 1850 |
1851 case Yield::kFinal: { | 1851 case Yield::kFinal: { |
1852 // Pop value from top-of-stack slot, box result into result register. | 1852 // Pop value from top-of-stack slot, box result into result register. |
1853 OperandStackDepthDecrement(1); | |
1854 EmitCreateIteratorResult(true); | 1853 EmitCreateIteratorResult(true); |
1855 EmitUnwindAndReturn(); | 1854 EmitUnwindAndReturn(); |
1856 break; | 1855 break; |
1857 } | 1856 } |
1858 | 1857 |
1859 case Yield::kDelegating: | 1858 case Yield::kDelegating: |
1860 UNREACHABLE(); | 1859 UNREACHABLE(); |
1861 } | 1860 } |
1862 } | 1861 } |
1863 | 1862 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1984 __ mov(ebx, ContextOperand(ebx, Context::ITERATOR_RESULT_MAP_INDEX)); | 1983 __ mov(ebx, ContextOperand(ebx, Context::ITERATOR_RESULT_MAP_INDEX)); |
1985 __ mov(FieldOperand(eax, HeapObject::kMapOffset), ebx); | 1984 __ mov(FieldOperand(eax, HeapObject::kMapOffset), ebx); |
1986 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), | 1985 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), |
1987 isolate()->factory()->empty_fixed_array()); | 1986 isolate()->factory()->empty_fixed_array()); |
1988 __ mov(FieldOperand(eax, JSObject::kElementsOffset), | 1987 __ mov(FieldOperand(eax, JSObject::kElementsOffset), |
1989 isolate()->factory()->empty_fixed_array()); | 1988 isolate()->factory()->empty_fixed_array()); |
1990 __ pop(FieldOperand(eax, JSIteratorResult::kValueOffset)); | 1989 __ pop(FieldOperand(eax, JSIteratorResult::kValueOffset)); |
1991 __ mov(FieldOperand(eax, JSIteratorResult::kDoneOffset), | 1990 __ mov(FieldOperand(eax, JSIteratorResult::kDoneOffset), |
1992 isolate()->factory()->ToBoolean(done)); | 1991 isolate()->factory()->ToBoolean(done)); |
1993 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); | 1992 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); |
| 1993 OperandStackDepthDecrement(1); |
1994 } | 1994 } |
1995 | 1995 |
1996 | 1996 |
1997 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1997 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
1998 SetExpressionPosition(prop); | 1998 SetExpressionPosition(prop); |
1999 Literal* key = prop->key()->AsLiteral(); | 1999 Literal* key = prop->key()->AsLiteral(); |
2000 DCHECK(!key->value()->IsSmi()); | 2000 DCHECK(!key->value()->IsSmi()); |
2001 DCHECK(!prop->IsSuperAccess()); | 2001 DCHECK(!prop->IsSuperAccess()); |
2002 | 2002 |
2003 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value())); | 2003 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value())); |
(...skipping 2130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4134 Assembler::target_address_at(call_target_address, | 4134 Assembler::target_address_at(call_target_address, |
4135 unoptimized_code)); | 4135 unoptimized_code)); |
4136 return OSR_AFTER_STACK_CHECK; | 4136 return OSR_AFTER_STACK_CHECK; |
4137 } | 4137 } |
4138 | 4138 |
4139 | 4139 |
4140 } // namespace internal | 4140 } // namespace internal |
4141 } // namespace v8 | 4141 } // namespace v8 |
4142 | 4142 |
4143 #endif // V8_TARGET_ARCH_IA32 | 4143 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |