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_ARM | 5 #if V8_TARGET_ARCH_ARM |
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 1833 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1844 | 1844 |
1845 | 1845 |
1846 void FullCodeGenerator::VisitYield(Yield* expr) { | 1846 void FullCodeGenerator::VisitYield(Yield* expr) { |
1847 Comment cmnt(masm_, "[ Yield"); | 1847 Comment cmnt(masm_, "[ Yield"); |
1848 SetExpressionPosition(expr); | 1848 SetExpressionPosition(expr); |
1849 | 1849 |
1850 // Evaluate yielded value first; the initial iterator definition depends on | 1850 // Evaluate yielded value first; the initial iterator definition depends on |
1851 // this. It stays on the stack while we update the iterator. | 1851 // this. It stays on the stack while we update the iterator. |
1852 VisitForStackValue(expr->expression()); | 1852 VisitForStackValue(expr->expression()); |
1853 | 1853 |
1854 switch (expr->yield_kind()) { | 1854 Label suspend, continuation, post_runtime, resume; |
1855 case Yield::kSuspend: | |
1856 // Pop value from top-of-stack slot; box result into result register. | |
1857 EmitCreateIteratorResult(false); | |
1858 PushOperand(result_register()); | |
1859 // Fall through. | |
1860 case Yield::kInitial: { | |
1861 Label suspend, continuation, post_runtime, resume; | |
1862 | 1855 |
1863 __ jmp(&suspend); | 1856 __ jmp(&suspend); |
1864 __ bind(&continuation); | 1857 __ bind(&continuation); |
1865 // When we arrive here, the stack top is the resume mode and | 1858 // When we arrive here, the stack top is the resume mode and |
1866 // result_register() holds the input value (the argument given to the | 1859 // result_register() holds the input value (the argument given to the |
1867 // respective resume operation). | 1860 // respective resume operation). |
1868 __ RecordGeneratorContinuation(); | 1861 __ RecordGeneratorContinuation(); |
1869 __ pop(r1); | 1862 __ pop(r1); |
1870 __ cmp(r1, Operand(Smi::FromInt(JSGeneratorObject::RETURN))); | 1863 __ cmp(r1, Operand(Smi::FromInt(JSGeneratorObject::RETURN))); |
1871 __ b(ne, &resume); | 1864 __ b(ne, &resume); |
1872 __ push(result_register()); | 1865 __ push(result_register()); |
1873 EmitCreateIteratorResult(true); | 1866 EmitCreateIteratorResult(true); |
1874 EmitUnwindAndReturn(); | 1867 EmitUnwindAndReturn(); |
1875 | 1868 |
1876 __ bind(&suspend); | 1869 __ bind(&suspend); |
1877 OperandStackDepthIncrement(1); // Not popped on this path. | 1870 OperandStackDepthIncrement(1); // Not popped on this path. |
1878 VisitForAccumulatorValue(expr->generator_object()); | 1871 VisitForAccumulatorValue(expr->generator_object()); |
1879 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); | 1872 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); |
1880 __ mov(r1, Operand(Smi::FromInt(continuation.pos()))); | 1873 __ mov(r1, Operand(Smi::FromInt(continuation.pos()))); |
1881 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset)); | 1874 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset)); |
1882 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset)); | 1875 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset)); |
1883 __ mov(r1, cp); | 1876 __ mov(r1, cp); |
1884 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2, | 1877 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2, |
1885 kLRHasBeenSaved, kDontSaveFPRegs); | 1878 kLRHasBeenSaved, kDontSaveFPRegs); |
1886 __ add(r1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); | 1879 __ add(r1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); |
1887 __ cmp(sp, r1); | 1880 __ cmp(sp, r1); |
1888 __ b(eq, &post_runtime); | 1881 __ b(eq, &post_runtime); |
1889 __ push(r0); // generator object | 1882 __ push(r0); // generator object |
1890 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 1883 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
1891 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1884 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
1892 __ bind(&post_runtime); | 1885 __ bind(&post_runtime); |
1893 PopOperand(result_register()); | 1886 PopOperand(result_register()); |
1894 EmitReturnSequence(); | 1887 EmitReturnSequence(); |
1895 | 1888 |
1896 __ bind(&resume); | 1889 __ bind(&resume); |
1897 context()->Plug(result_register()); | 1890 context()->Plug(result_register()); |
1898 break; | |
1899 } | |
1900 | |
1901 case Yield::kFinal: { | |
1902 // Pop value from top-of-stack slot, box result into result register. | |
1903 EmitCreateIteratorResult(true); | |
1904 EmitUnwindAndReturn(); | |
1905 break; | |
1906 } | |
1907 | |
1908 case Yield::kDelegating: | |
1909 UNREACHABLE(); | |
1910 } | |
1911 } | 1891 } |
1912 | 1892 |
1913 | 1893 |
1914 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 1894 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
1915 Expression *value, | 1895 Expression *value, |
1916 JSGeneratorObject::ResumeMode resume_mode) { | 1896 JSGeneratorObject::ResumeMode resume_mode) { |
1917 // The value stays in r0, and is ultimately read by the resumed generator, as | 1897 // The value stays in r0, and is ultimately read by the resumed generator, as |
1918 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it | 1898 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it |
1919 // is read to throw the value when the resumed generator is already closed. | 1899 // is read to throw the value when the resumed generator is already closed. |
1920 // r1 will hold the generator object until the activation has been resumed. | 1900 // r1 will hold the generator object until the activation has been resumed. |
(...skipping 2338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4259 DCHECK(interrupt_address == | 4239 DCHECK(interrupt_address == |
4260 isolate->builtins()->OsrAfterStackCheck()->entry()); | 4240 isolate->builtins()->OsrAfterStackCheck()->entry()); |
4261 return OSR_AFTER_STACK_CHECK; | 4241 return OSR_AFTER_STACK_CHECK; |
4262 } | 4242 } |
4263 | 4243 |
4264 | 4244 |
4265 } // namespace internal | 4245 } // namespace internal |
4266 } // namespace v8 | 4246 } // namespace v8 |
4267 | 4247 |
4268 #endif // V8_TARGET_ARCH_ARM | 4248 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |