| 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 |