| 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 1956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1967 __ jmp(&suspend); | 1967 __ jmp(&suspend); |
| 1968 | 1968 |
| 1969 __ bind(&continuation); | 1969 __ bind(&continuation); |
| 1970 __ jmp(&resume); | 1970 __ jmp(&resume); |
| 1971 | 1971 |
| 1972 __ bind(&suspend); | 1972 __ bind(&suspend); |
| 1973 VisitForAccumulatorValue(expr->generator_object()); | 1973 VisitForAccumulatorValue(expr->generator_object()); |
| 1974 ASSERT(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); | 1974 ASSERT(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); |
| 1975 __ Move(FieldOperand(rax, JSGeneratorObject::kContinuationOffset), | 1975 __ Move(FieldOperand(rax, JSGeneratorObject::kContinuationOffset), |
| 1976 Smi::FromInt(continuation.pos())); | 1976 Smi::FromInt(continuation.pos())); |
| 1977 if (expr->yield_kind() == Yield::INITIAL) { |
| 1978 __ Move(FieldOperand(rax, JSGeneratorObject::kSuspendedStartOffset), |
| 1979 Smi::FromInt(continuation.pos())); |
| 1980 } |
| 1977 __ movq(FieldOperand(rax, JSGeneratorObject::kContextOffset), rsi); | 1981 __ movq(FieldOperand(rax, JSGeneratorObject::kContextOffset), rsi); |
| 1978 __ movq(rcx, rsi); | 1982 __ movq(rcx, rsi); |
| 1979 __ RecordWriteField(rax, JSGeneratorObject::kContextOffset, rcx, rdx, | 1983 __ RecordWriteField(rax, JSGeneratorObject::kContextOffset, rcx, rdx, |
| 1980 kDontSaveFPRegs); | 1984 kDontSaveFPRegs); |
| 1981 __ lea(rbx, Operand(rbp, StandardFrameConstants::kExpressionsOffset)); | 1985 __ lea(rbx, Operand(rbp, StandardFrameConstants::kExpressionsOffset)); |
| 1982 __ cmpq(rsp, rbx); | 1986 __ cmpq(rsp, rbx); |
| 1983 __ j(equal, &post_runtime); | 1987 __ j(equal, &post_runtime); |
| 1984 __ push(rax); // generator object | 1988 __ push(rax); // generator object |
| 1985 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 1989 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
| 1986 __ movq(context_register(), | 1990 __ movq(context_register(), |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2099 JSGeneratorObject::ResumeMode resume_mode) { | 2103 JSGeneratorObject::ResumeMode resume_mode) { |
| 2100 // The value stays in rax, and is ultimately read by the resumed generator, as | 2104 // The value stays in rax, and is ultimately read by the resumed generator, as |
| 2101 // if the CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it | 2105 // if the CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it |
| 2102 // is read to throw the value when the resumed generator is already closed. | 2106 // is read to throw the value when the resumed generator is already closed. |
| 2103 // rbx will hold the generator object until the activation has been resumed. | 2107 // rbx will hold the generator object until the activation has been resumed. |
| 2104 VisitForStackValue(generator); | 2108 VisitForStackValue(generator); |
| 2105 VisitForAccumulatorValue(value); | 2109 VisitForAccumulatorValue(value); |
| 2106 __ pop(rbx); | 2110 __ pop(rbx); |
| 2107 | 2111 |
| 2108 // Check generator state. | 2112 // Check generator state. |
| 2109 Label wrong_state, closed_state, done; | 2113 Label wrong_state, closed_state, suspended_start_state, resume_state, done; |
| 2110 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); | 2114 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); |
| 2111 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0); | 2115 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0); |
| 2112 __ SmiCompare(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset), | 2116 __ movq(rcx, FieldOperand(rbx, JSGeneratorObject::kContinuationOffset)); |
| 2113 Smi::FromInt(0)); | 2117 __ SmiCompare(rcx, Smi::FromInt(0)); |
| 2114 __ j(equal, &closed_state); | 2118 __ j(equal, &closed_state); |
| 2115 __ j(less, &wrong_state); | 2119 __ j(less, &wrong_state); |
| 2120 __ cmpq(rcx, FieldOperand(rbx, JSGeneratorObject::kSuspendedStartOffset)); |
| 2121 __ j(equal, &suspended_start_state); |
| 2122 |
| 2123 __ bind(&resume_state); |
| 2116 | 2124 |
| 2117 // Load suspended function and context. | 2125 // Load suspended function and context. |
| 2118 __ movq(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset)); | 2126 __ movq(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset)); |
| 2119 __ movq(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset)); | 2127 __ movq(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset)); |
| 2120 | 2128 |
| 2121 // Push receiver. | 2129 // Push receiver. |
| 2122 __ push(FieldOperand(rbx, JSGeneratorObject::kReceiverOffset)); | 2130 __ push(FieldOperand(rbx, JSGeneratorObject::kReceiverOffset)); |
| 2123 | 2131 |
| 2124 // Push holes for arguments to generator function. | 2132 // Push holes for arguments to generator function. |
| 2125 __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 2133 __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2176 __ push(rcx); | 2184 __ push(rcx); |
| 2177 __ jmp(&push_operand_holes); | 2185 __ jmp(&push_operand_holes); |
| 2178 __ bind(&call_resume); | 2186 __ bind(&call_resume); |
| 2179 __ push(rbx); | 2187 __ push(rbx); |
| 2180 __ push(result_register()); | 2188 __ push(result_register()); |
| 2181 __ Push(Smi::FromInt(resume_mode)); | 2189 __ Push(Smi::FromInt(resume_mode)); |
| 2182 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); | 2190 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); |
| 2183 // Not reached: the runtime call returns elsewhere. | 2191 // Not reached: the runtime call returns elsewhere. |
| 2184 __ Abort(kGeneratorFailedToResume); | 2192 __ Abort(kGeneratorFailedToResume); |
| 2185 | 2193 |
| 2194 // Throw the provided value. |
| 2195 Label throw_provided_value; |
| 2196 __ bind(&throw_provided_value); |
| 2197 if (resume_mode != JSGeneratorObject::NEXT) { |
| 2198 __ push(rax); |
| 2199 __ CallRuntime(Runtime::kThrow, 1); |
| 2200 __ jmp(&done); |
| 2201 } |
| 2202 |
| 2203 // Reach here when calling initial resume to a generator. |
| 2204 __ bind(&suspended_start_state); |
| 2205 if (resume_mode == JSGeneratorObject::NEXT) { |
| 2206 // When value is provided and it is not undefined, throw error. |
| 2207 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); |
| 2208 __ j(equal, &resume_state); |
| 2209 __ CallRuntime(Runtime::kThrowGeneratorStartError, 0); |
| 2210 __ jmp(&done); |
| 2211 } else { |
| 2212 // Make generator's state to "closed". |
| 2213 __ Move(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset), |
| 2214 Smi::FromInt(JSGeneratorObject::kGeneratorClosed)); |
| 2215 __ jmp(&throw_provided_value); |
| 2216 } |
| 2217 |
| 2186 // Reach here when generator is closed. | 2218 // Reach here when generator is closed. |
| 2187 __ bind(&closed_state); | 2219 __ bind(&closed_state); |
| 2188 if (resume_mode == JSGeneratorObject::NEXT) { | 2220 if (resume_mode == JSGeneratorObject::NEXT) { |
| 2189 // Return completed iterator result when generator is closed. | 2221 // Return completed iterator result when generator is closed. |
| 2190 __ PushRoot(Heap::kUndefinedValueRootIndex); | 2222 __ PushRoot(Heap::kUndefinedValueRootIndex); |
| 2191 // Pop value from top-of-stack slot; box result into result register. | 2223 // Pop value from top-of-stack slot; box result into result register. |
| 2192 EmitCreateIteratorResult(true); | 2224 EmitCreateIteratorResult(true); |
| 2225 __ jmp(&done); |
| 2193 } else { | 2226 } else { |
| 2194 // Throw the provided value. | 2227 __ jmp(&throw_provided_value); |
| 2195 __ push(rax); | |
| 2196 __ CallRuntime(Runtime::kThrow, 1); | |
| 2197 } | 2228 } |
| 2198 __ jmp(&done); | |
| 2199 | 2229 |
| 2200 // Throw error if we attempt to operate on a running generator. | 2230 // Throw error if we attempt to operate on a running generator. |
| 2201 __ bind(&wrong_state); | 2231 __ bind(&wrong_state); |
| 2202 __ push(rbx); | 2232 __ push(rbx); |
| 2203 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); | 2233 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); |
| 2204 | 2234 |
| 2205 __ bind(&done); | 2235 __ bind(&done); |
| 2206 context()->Plug(result_register()); | 2236 context()->Plug(result_register()); |
| 2207 } | 2237 } |
| 2208 | 2238 |
| (...skipping 2688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4897 | 4927 |
| 4898 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4928 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
| 4899 Assembler::target_address_at(call_target_address)); | 4929 Assembler::target_address_at(call_target_address)); |
| 4900 return OSR_AFTER_STACK_CHECK; | 4930 return OSR_AFTER_STACK_CHECK; |
| 4901 } | 4931 } |
| 4902 | 4932 |
| 4903 | 4933 |
| 4904 } } // namespace v8::internal | 4934 } } // namespace v8::internal |
| 4905 | 4935 |
| 4906 #endif // V8_TARGET_ARCH_X64 | 4936 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |