| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1994 // this. It stays on the stack while we update the iterator. | 1994 // this. It stays on the stack while we update the iterator. |
| 1995 VisitForStackValue(expr->expression()); | 1995 VisitForStackValue(expr->expression()); |
| 1996 | 1996 |
| 1997 switch (expr->yield_kind()) { | 1997 switch (expr->yield_kind()) { |
| 1998 case Yield::SUSPEND: | 1998 case Yield::SUSPEND: |
| 1999 // Pop value from top-of-stack slot; box result into result register. | 1999 // Pop value from top-of-stack slot; box result into result register. |
| 2000 EmitCreateIteratorResult(false); | 2000 EmitCreateIteratorResult(false); |
| 2001 __ push(result_register()); | 2001 __ push(result_register()); |
| 2002 // Fall through. | 2002 // Fall through. |
| 2003 case Yield::INITIAL: { | 2003 case Yield::INITIAL: { |
| 2004 VisitForStackValue(expr->generator_object()); | 2004 Label suspend, continuation, post_runtime, resume; |
| 2005 |
| 2006 __ jmp(&suspend); |
| 2007 |
| 2008 __ bind(&continuation); |
| 2009 __ jmp(&resume); |
| 2010 |
| 2011 __ bind(&suspend); |
| 2012 VisitForAccumulatorValue(expr->generator_object()); |
| 2013 ASSERT(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); |
| 2014 __ li(a1, Operand(Smi::FromInt(continuation.pos()))); |
| 2015 __ sw(a1, FieldMemOperand(v0, JSGeneratorObject::kContinuationOffset)); |
| 2016 __ sw(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset)); |
| 2017 __ mov(a1, cp); |
| 2018 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2, |
| 2019 kRAHasBeenSaved, kDontSaveFPRegs); |
| 2020 __ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); |
| 2021 __ Branch(&post_runtime, eq, sp, Operand(a1)); |
| 2022 __ push(v0); // generator object |
| 2005 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 2023 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
| 2006 __ lw(context_register(), | 2024 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2007 MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2025 __ bind(&post_runtime); |
| 2008 | |
| 2009 Label resume; | |
| 2010 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | |
| 2011 __ Branch(&resume, ne, result_register(), Operand(at)); | |
| 2012 __ pop(result_register()); | 2026 __ pop(result_register()); |
| 2013 EmitReturnSequence(); | 2027 EmitReturnSequence(); |
| 2014 | 2028 |
| 2015 __ bind(&resume); | 2029 __ bind(&resume); |
| 2016 context()->Plug(result_register()); | 2030 context()->Plug(result_register()); |
| 2017 break; | 2031 break; |
| 2018 } | 2032 } |
| 2019 | 2033 |
| 2020 case Yield::FINAL: { | 2034 case Yield::FINAL: { |
| 2021 VisitForAccumulatorValue(expr->generator_object()); | 2035 VisitForAccumulatorValue(expr->generator_object()); |
| 2022 __ li(a1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed))); | 2036 __ li(a1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed))); |
| 2023 __ sw(a1, FieldMemOperand(result_register(), | 2037 __ sw(a1, FieldMemOperand(result_register(), |
| 2024 JSGeneratorObject::kContinuationOffset)); | 2038 JSGeneratorObject::kContinuationOffset)); |
| 2025 // Pop value from top-of-stack slot, box result into result register. | 2039 // Pop value from top-of-stack slot, box result into result register. |
| 2026 EmitCreateIteratorResult(true); | 2040 EmitCreateIteratorResult(true); |
| 2027 EmitUnwindBeforeReturn(); | 2041 EmitUnwindBeforeReturn(); |
| 2028 EmitReturnSequence(); | 2042 EmitReturnSequence(); |
| 2029 break; | 2043 break; |
| 2030 } | 2044 } |
| 2031 | 2045 |
| 2032 case Yield::DELEGATING: { | 2046 case Yield::DELEGATING: { |
| 2033 VisitForStackValue(expr->generator_object()); | 2047 VisitForStackValue(expr->generator_object()); |
| 2034 | 2048 |
| 2035 // Initial stack layout is as follows: | 2049 // Initial stack layout is as follows: |
| 2036 // [sp + 1 * kPointerSize] iter | 2050 // [sp + 1 * kPointerSize] iter |
| 2037 // [sp + 0 * kPointerSize] g | 2051 // [sp + 0 * kPointerSize] g |
| 2038 | 2052 |
| 2039 Label l_catch, l_try, l_resume, l_next, l_call, l_loop; | 2053 Label l_catch, l_try, l_suspend, l_continuation, l_resume; |
| 2054 Label l_next, l_call, l_loop; |
| 2040 // Initial send value is undefined. | 2055 // Initial send value is undefined. |
| 2041 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); | 2056 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); |
| 2042 __ Branch(&l_next); | 2057 __ Branch(&l_next); |
| 2043 | 2058 |
| 2044 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } | 2059 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } |
| 2045 __ bind(&l_catch); | 2060 __ bind(&l_catch); |
| 2046 __ mov(a0, v0); | 2061 __ mov(a0, v0); |
| 2047 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); | 2062 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); |
| 2048 __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw" | 2063 __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw" |
| 2049 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter | 2064 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter |
| 2050 __ push(a3); // iter | 2065 __ push(a3); // iter |
| 2051 __ push(a0); // exception | 2066 __ push(a0); // exception |
| 2052 __ jmp(&l_call); | 2067 __ jmp(&l_call); |
| 2053 | 2068 |
| 2054 // try { received = %yield result } | 2069 // try { received = %yield result } |
| 2055 // Shuffle the received result above a try handler and yield it without | 2070 // Shuffle the received result above a try handler and yield it without |
| 2056 // re-boxing. | 2071 // re-boxing. |
| 2057 __ bind(&l_try); | 2072 __ bind(&l_try); |
| 2058 __ pop(a0); // result | 2073 __ pop(a0); // result |
| 2059 __ PushTryHandler(StackHandler::CATCH, expr->index()); | 2074 __ PushTryHandler(StackHandler::CATCH, expr->index()); |
| 2060 const int handler_size = StackHandlerConstants::kSize; | 2075 const int handler_size = StackHandlerConstants::kSize; |
| 2061 __ push(a0); // result | 2076 __ push(a0); // result |
| 2062 __ lw(a3, MemOperand(sp, (0 + 1) * kPointerSize + handler_size)); // g | 2077 __ jmp(&l_suspend); |
| 2063 __ push(a3); // g | 2078 __ bind(&l_continuation); |
| 2079 __ mov(a0, v0); |
| 2080 __ jmp(&l_resume); |
| 2081 __ bind(&l_suspend); |
| 2082 const int generator_object_depth = kPointerSize + handler_size; |
| 2083 __ lw(a0, MemOperand(sp, generator_object_depth)); |
| 2084 __ push(a0); // g |
| 2085 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); |
| 2086 __ li(a1, Operand(Smi::FromInt(l_continuation.pos()))); |
| 2087 __ sw(a1, FieldMemOperand(a0, JSGeneratorObject::kContinuationOffset)); |
| 2088 __ sw(cp, FieldMemOperand(a0, JSGeneratorObject::kContextOffset)); |
| 2089 __ mov(a1, cp); |
| 2090 __ RecordWriteField(a0, JSGeneratorObject::kContextOffset, a1, a2, |
| 2091 kRAHasBeenSaved, kDontSaveFPRegs); |
| 2064 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 2092 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
| 2065 __ mov(a0, v0); | 2093 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2066 __ lw(context_register(), | |
| 2067 MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
| 2068 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | |
| 2069 __ Branch(&l_resume, ne, a0, Operand(at)); | |
| 2070 __ pop(v0); // result | 2094 __ pop(v0); // result |
| 2071 EmitReturnSequence(); | 2095 EmitReturnSequence(); |
| 2072 __ mov(a0, v0); | 2096 __ mov(a0, v0); |
| 2073 __ bind(&l_resume); // received in a0 | 2097 __ bind(&l_resume); // received in a0 |
| 2074 __ PopTryHandler(); | 2098 __ PopTryHandler(); |
| 2075 | 2099 |
| 2076 // receiver = iter; f = 'next'; arg = received; | 2100 // receiver = iter; f = 'next'; arg = received; |
| 2077 __ bind(&l_next); | 2101 __ bind(&l_next); |
| 2078 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next" | 2102 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next" |
| 2079 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter | 2103 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter |
| (...skipping 2847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4927 *context_length = 0; | 4951 *context_length = 0; |
| 4928 return previous_; | 4952 return previous_; |
| 4929 } | 4953 } |
| 4930 | 4954 |
| 4931 | 4955 |
| 4932 #undef __ | 4956 #undef __ |
| 4933 | 4957 |
| 4934 } } // namespace v8::internal | 4958 } } // namespace v8::internal |
| 4935 | 4959 |
| 4936 #endif // V8_TARGET_ARCH_MIPS | 4960 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |