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_X87 | 5 #if V8_TARGET_ARCH_X87 |
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 1740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1751 | 1751 |
1752 | 1752 |
1753 void FullCodeGenerator::VisitYield(Yield* expr) { | 1753 void FullCodeGenerator::VisitYield(Yield* expr) { |
1754 Comment cmnt(masm_, "[ Yield"); | 1754 Comment cmnt(masm_, "[ Yield"); |
1755 SetExpressionPosition(expr); | 1755 SetExpressionPosition(expr); |
1756 | 1756 |
1757 // Evaluate yielded value first; the initial iterator definition depends on | 1757 // Evaluate yielded value first; the initial iterator definition depends on |
1758 // this. It stays on the stack while we update the iterator. | 1758 // this. It stays on the stack while we update the iterator. |
1759 VisitForStackValue(expr->expression()); | 1759 VisitForStackValue(expr->expression()); |
1760 | 1760 |
1761 switch (expr->yield_kind()) { | 1761 Label suspend, continuation, post_runtime, resume; |
1762 case Yield::kSuspend: | |
1763 // Pop value from top-of-stack slot; box result into result register. | |
1764 EmitCreateIteratorResult(false); | |
1765 PushOperand(result_register()); | |
1766 // Fall through. | |
1767 case Yield::kInitial: { | |
1768 Label suspend, continuation, post_runtime, resume; | |
1769 | 1762 |
1770 __ jmp(&suspend); | 1763 __ jmp(&suspend); |
1771 __ bind(&continuation); | 1764 __ bind(&continuation); |
1772 // When we arrive here, the stack top is the resume mode and | 1765 // When we arrive here, the stack top is the resume mode and |
1773 // result_register() holds the input value (the argument given to the | 1766 // result_register() holds the input value (the argument given to the |
1774 // respective resume operation). | 1767 // respective resume operation). |
1775 __ RecordGeneratorContinuation(); | 1768 __ RecordGeneratorContinuation(); |
1776 __ pop(ebx); | 1769 __ pop(ebx); |
1777 __ cmp(ebx, Immediate(Smi::FromInt(JSGeneratorObject::RETURN))); | 1770 __ cmp(ebx, Immediate(Smi::FromInt(JSGeneratorObject::RETURN))); |
1778 __ j(not_equal, &resume); | 1771 __ j(not_equal, &resume); |
1779 __ push(result_register()); | 1772 __ push(result_register()); |
1780 EmitCreateIteratorResult(true); | 1773 EmitCreateIteratorResult(true); |
1781 EmitUnwindAndReturn(); | 1774 EmitUnwindAndReturn(); |
1782 | 1775 |
1783 __ bind(&suspend); | 1776 __ bind(&suspend); |
1784 OperandStackDepthIncrement(1); // Not popped on this path. | 1777 OperandStackDepthIncrement(1); // Not popped on this path. |
1785 VisitForAccumulatorValue(expr->generator_object()); | 1778 VisitForAccumulatorValue(expr->generator_object()); |
1786 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); | 1779 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); |
1787 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), | 1780 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), |
1788 Immediate(Smi::FromInt(continuation.pos()))); | 1781 Immediate(Smi::FromInt(continuation.pos()))); |
1789 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); | 1782 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); |
1790 __ mov(ecx, esi); | 1783 __ mov(ecx, esi); |
1791 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, | 1784 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, |
1792 kDontSaveFPRegs); | 1785 kDontSaveFPRegs); |
1793 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset)); | 1786 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset)); |
1794 __ cmp(esp, ebx); | 1787 __ cmp(esp, ebx); |
1795 __ j(equal, &post_runtime); | 1788 __ j(equal, &post_runtime); |
1796 __ push(eax); // generator object | 1789 __ push(eax); // generator object |
1797 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 1790 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
1798 __ mov(context_register(), | 1791 __ mov(context_register(), |
1799 Operand(ebp, StandardFrameConstants::kContextOffset)); | 1792 Operand(ebp, StandardFrameConstants::kContextOffset)); |
1800 __ bind(&post_runtime); | 1793 __ bind(&post_runtime); |
1801 PopOperand(result_register()); | 1794 PopOperand(result_register()); |
1802 EmitReturnSequence(); | 1795 EmitReturnSequence(); |
1803 | 1796 |
1804 __ bind(&resume); | 1797 __ bind(&resume); |
1805 context()->Plug(result_register()); | 1798 context()->Plug(result_register()); |
1806 break; | |
1807 } | |
1808 | |
1809 case Yield::kFinal: { | |
1810 // Pop value from top-of-stack slot, box result into result register. | |
1811 EmitCreateIteratorResult(true); | |
1812 EmitUnwindAndReturn(); | |
1813 break; | |
1814 } | |
1815 | |
1816 case Yield::kDelegating: | |
1817 UNREACHABLE(); | |
1818 } | |
1819 } | 1799 } |
1820 | 1800 |
1821 | 1801 |
1822 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 1802 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
1823 Expression *value, | 1803 Expression *value, |
1824 JSGeneratorObject::ResumeMode resume_mode) { | 1804 JSGeneratorObject::ResumeMode resume_mode) { |
1825 // The value stays in eax, and is ultimately read by the resumed generator, as | 1805 // The value stays in eax, and is ultimately read by the resumed generator, as |
1826 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it | 1806 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it |
1827 // is read to throw the value when the resumed generator is already closed. | 1807 // is read to throw the value when the resumed generator is already closed. |
1828 // ebx will hold the generator object until the activation has been resumed. | 1808 // ebx will hold the generator object until the activation has been resumed. |
(...skipping 2247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4076 Assembler::target_address_at(call_target_address, | 4056 Assembler::target_address_at(call_target_address, |
4077 unoptimized_code)); | 4057 unoptimized_code)); |
4078 return OSR_AFTER_STACK_CHECK; | 4058 return OSR_AFTER_STACK_CHECK; |
4079 } | 4059 } |
4080 | 4060 |
4081 | 4061 |
4082 } // namespace internal | 4062 } // namespace internal |
4083 } // namespace v8 | 4063 } // namespace v8 |
4084 | 4064 |
4085 #endif // V8_TARGET_ARCH_X87 | 4065 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |