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 2074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2085 break; | 2085 break; |
2086 } | 2086 } |
2087 } | 2087 } |
2088 } | 2088 } |
2089 | 2089 |
2090 | 2090 |
2091 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2091 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
2092 Expression *value, | 2092 Expression *value, |
2093 JSGeneratorObject::ResumeMode resume_mode) { | 2093 JSGeneratorObject::ResumeMode resume_mode) { |
2094 // The value stays in rax, and is ultimately read by the resumed generator, as | 2094 // The value stays in rax, and is ultimately read by the resumed generator, as |
2095 // if the CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. rbx | 2095 // if the CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or used |
2096 // will hold the generator object until the activation has been resumed. | 2096 // to throw the value when the resumed generator is already closed. rbx will |
| 2097 // hold the generator object until the activation has been resumed. |
2097 VisitForStackValue(generator); | 2098 VisitForStackValue(generator); |
2098 VisitForAccumulatorValue(value); | 2099 VisitForAccumulatorValue(value); |
2099 __ pop(rbx); | 2100 __ pop(rbx); |
2100 | 2101 |
2101 // Check generator state. | 2102 // Check generator state. |
2102 Label wrong_state, done; | 2103 Label wrong_state, closed_state, done; |
2103 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting <= 0); | 2104 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); |
2104 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed <= 0); | 2105 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0); |
2105 __ SmiCompare(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset), | 2106 __ SmiCompare(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset), |
2106 Smi::FromInt(0)); | 2107 Smi::FromInt(0)); |
2107 __ j(less_equal, &wrong_state); | 2108 __ j(equal, &closed_state); |
| 2109 __ j(less, &wrong_state); |
2108 | 2110 |
2109 // Load suspended function and context. | 2111 // Load suspended function and context. |
2110 __ movq(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset)); | 2112 __ movq(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset)); |
2111 __ movq(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset)); | 2113 __ movq(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset)); |
2112 | 2114 |
2113 // Push receiver. | 2115 // Push receiver. |
2114 __ push(FieldOperand(rbx, JSGeneratorObject::kReceiverOffset)); | 2116 __ push(FieldOperand(rbx, JSGeneratorObject::kReceiverOffset)); |
2115 | 2117 |
2116 // Push holes for arguments to generator function. | 2118 // Push holes for arguments to generator function. |
2117 __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 2119 __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2168 __ push(rcx); | 2170 __ push(rcx); |
2169 __ jmp(&push_operand_holes); | 2171 __ jmp(&push_operand_holes); |
2170 __ bind(&call_resume); | 2172 __ bind(&call_resume); |
2171 __ push(rbx); | 2173 __ push(rbx); |
2172 __ push(result_register()); | 2174 __ push(result_register()); |
2173 __ Push(Smi::FromInt(resume_mode)); | 2175 __ Push(Smi::FromInt(resume_mode)); |
2174 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); | 2176 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); |
2175 // Not reached: the runtime call returns elsewhere. | 2177 // Not reached: the runtime call returns elsewhere. |
2176 __ Abort(kGeneratorFailedToResume); | 2178 __ Abort(kGeneratorFailedToResume); |
2177 | 2179 |
| 2180 // Reach here when generator is closed. |
| 2181 __ bind(&closed_state); |
| 2182 if (resume_mode == JSGeneratorObject::NEXT) { |
| 2183 // Return completed iterator result when generator is closed. |
| 2184 __ PushRoot(Heap::kUndefinedValueRootIndex); |
| 2185 // Pop value from top-of-stack slot; box result into result register. |
| 2186 EmitCreateIteratorResult(true); |
| 2187 } else { |
| 2188 // Throw the provided value. |
| 2189 __ push(rax); |
| 2190 __ CallRuntime(Runtime::kThrow, 1); |
| 2191 } |
| 2192 __ jmp(&done); |
| 2193 |
2178 // Throw error if we attempt to operate on a running generator. | 2194 // Throw error if we attempt to operate on a running generator. |
2179 __ bind(&wrong_state); | 2195 __ bind(&wrong_state); |
2180 __ push(rbx); | 2196 __ push(rbx); |
2181 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); | 2197 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); |
2182 | 2198 |
2183 __ bind(&done); | 2199 __ bind(&done); |
2184 context()->Plug(result_register()); | 2200 context()->Plug(result_register()); |
2185 } | 2201 } |
2186 | 2202 |
2187 | 2203 |
(...skipping 2695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4883 | 4899 |
4884 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4900 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4885 Assembler::target_address_at(call_target_address)); | 4901 Assembler::target_address_at(call_target_address)); |
4886 return OSR_AFTER_STACK_CHECK; | 4902 return OSR_AFTER_STACK_CHECK; |
4887 } | 4903 } |
4888 | 4904 |
4889 | 4905 |
4890 } } // namespace v8::internal | 4906 } } // namespace v8::internal |
4891 | 4907 |
4892 #endif // V8_TARGET_ARCH_X64 | 4908 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |