| 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM | 7 #if V8_TARGET_ARCH_ARM |
| 8 | 8 |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 2216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2227 Expression *value, | 2227 Expression *value, |
| 2228 JSGeneratorObject::ResumeMode resume_mode) { | 2228 JSGeneratorObject::ResumeMode resume_mode) { |
| 2229 // The value stays in r0, and is ultimately read by the resumed generator, as | 2229 // The value stays in r0, and is ultimately read by the resumed generator, as |
| 2230 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it | 2230 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it |
| 2231 // is read to throw the value when the resumed generator is already closed. | 2231 // is read to throw the value when the resumed generator is already closed. |
| 2232 // r1 will hold the generator object until the activation has been resumed. | 2232 // r1 will hold the generator object until the activation has been resumed. |
| 2233 VisitForStackValue(generator); | 2233 VisitForStackValue(generator); |
| 2234 VisitForAccumulatorValue(value); | 2234 VisitForAccumulatorValue(value); |
| 2235 __ pop(r1); | 2235 __ pop(r1); |
| 2236 | 2236 |
| 2237 // Check generator state. | |
| 2238 Label wrong_state, closed_state, done; | |
| 2239 __ ldr(r3, FieldMemOperand(r1, JSGeneratorObject::kContinuationOffset)); | |
| 2240 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); | |
| 2241 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0); | |
| 2242 __ cmp(r3, Operand(Smi::FromInt(0))); | |
| 2243 __ b(eq, &closed_state); | |
| 2244 __ b(lt, &wrong_state); | |
| 2245 | |
| 2246 // Load suspended function and context. | 2237 // Load suspended function and context. |
| 2247 __ ldr(cp, FieldMemOperand(r1, JSGeneratorObject::kContextOffset)); | 2238 __ ldr(cp, FieldMemOperand(r1, JSGeneratorObject::kContextOffset)); |
| 2248 __ ldr(r4, FieldMemOperand(r1, JSGeneratorObject::kFunctionOffset)); | 2239 __ ldr(r4, FieldMemOperand(r1, JSGeneratorObject::kFunctionOffset)); |
| 2249 | 2240 |
| 2250 // Load receiver and store as the first argument. | 2241 // Load receiver and store as the first argument. |
| 2251 __ ldr(r2, FieldMemOperand(r1, JSGeneratorObject::kReceiverOffset)); | 2242 __ ldr(r2, FieldMemOperand(r1, JSGeneratorObject::kReceiverOffset)); |
| 2252 __ push(r2); | 2243 __ push(r2); |
| 2253 | 2244 |
| 2254 // Push holes for the rest of the arguments to the generator function. | 2245 // Push holes for the rest of the arguments to the generator function. |
| 2255 __ ldr(r3, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); | 2246 __ ldr(r3, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); |
| 2256 __ ldr(r3, | 2247 __ ldr(r3, |
| 2257 FieldMemOperand(r3, SharedFunctionInfo::kFormalParameterCountOffset)); | 2248 FieldMemOperand(r3, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 2258 __ LoadRoot(r2, Heap::kTheHoleValueRootIndex); | 2249 __ LoadRoot(r2, Heap::kTheHoleValueRootIndex); |
| 2259 Label push_argument_holes, push_frame; | 2250 Label push_argument_holes, push_frame; |
| 2260 __ bind(&push_argument_holes); | 2251 __ bind(&push_argument_holes); |
| 2261 __ sub(r3, r3, Operand(Smi::FromInt(1)), SetCC); | 2252 __ sub(r3, r3, Operand(Smi::FromInt(1)), SetCC); |
| 2262 __ b(mi, &push_frame); | 2253 __ b(mi, &push_frame); |
| 2263 __ push(r2); | 2254 __ push(r2); |
| 2264 __ jmp(&push_argument_holes); | 2255 __ jmp(&push_argument_holes); |
| 2265 | 2256 |
| 2266 // Enter a new JavaScript frame, and initialize its slots as they were when | 2257 // Enter a new JavaScript frame, and initialize its slots as they were when |
| 2267 // the generator was suspended. | 2258 // the generator was suspended. |
| 2268 Label resume_frame; | 2259 Label resume_frame, done; |
| 2269 __ bind(&push_frame); | 2260 __ bind(&push_frame); |
| 2270 __ bl(&resume_frame); | 2261 __ bl(&resume_frame); |
| 2271 __ jmp(&done); | 2262 __ jmp(&done); |
| 2272 __ bind(&resume_frame); | 2263 __ bind(&resume_frame); |
| 2273 // lr = return address. | 2264 // lr = return address. |
| 2274 // fp = caller's frame pointer. | 2265 // fp = caller's frame pointer. |
| 2275 // pp = caller's constant pool (if FLAG_enable_ool_constant_pool), | 2266 // pp = caller's constant pool (if FLAG_enable_ool_constant_pool), |
| 2276 // cp = callee's context, | 2267 // cp = callee's context, |
| 2277 // r4 = callee's JS function. | 2268 // r4 = callee's JS function. |
| 2278 __ PushFixedFrame(r4); | 2269 __ PushFixedFrame(r4); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2318 __ push(r2); | 2309 __ push(r2); |
| 2319 __ b(&push_operand_holes); | 2310 __ b(&push_operand_holes); |
| 2320 __ bind(&call_resume); | 2311 __ bind(&call_resume); |
| 2321 DCHECK(!result_register().is(r1)); | 2312 DCHECK(!result_register().is(r1)); |
| 2322 __ Push(r1, result_register()); | 2313 __ Push(r1, result_register()); |
| 2323 __ Push(Smi::FromInt(resume_mode)); | 2314 __ Push(Smi::FromInt(resume_mode)); |
| 2324 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); | 2315 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); |
| 2325 // Not reached: the runtime call returns elsewhere. | 2316 // Not reached: the runtime call returns elsewhere. |
| 2326 __ stop("not-reached"); | 2317 __ stop("not-reached"); |
| 2327 | 2318 |
| 2328 // Reach here when generator is closed. | |
| 2329 __ bind(&closed_state); | |
| 2330 if (resume_mode == JSGeneratorObject::NEXT) { | |
| 2331 // Return completed iterator result when generator is closed. | |
| 2332 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | |
| 2333 __ push(r2); | |
| 2334 // Pop value from top-of-stack slot; box result into result register. | |
| 2335 EmitCreateIteratorResult(true); | |
| 2336 } else { | |
| 2337 // Throw the provided value. | |
| 2338 __ push(r0); | |
| 2339 __ CallRuntime(Runtime::kThrow, 1); | |
| 2340 } | |
| 2341 __ jmp(&done); | |
| 2342 | |
| 2343 // Throw error if we attempt to operate on a running generator. | |
| 2344 __ bind(&wrong_state); | |
| 2345 __ push(r1); | |
| 2346 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); | |
| 2347 | |
| 2348 __ bind(&done); | 2319 __ bind(&done); |
| 2349 context()->Plug(result_register()); | 2320 context()->Plug(result_register()); |
| 2350 } | 2321 } |
| 2351 | 2322 |
| 2352 | 2323 |
| 2353 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { | 2324 void FullCodeGenerator::EmitCreateIteratorResult(bool done) { |
| 2354 Label gc_required; | 2325 Label gc_required; |
| 2355 Label allocated; | 2326 Label allocated; |
| 2356 | 2327 |
| 2357 const int instance_size = 5 * kPointerSize; | 2328 const int instance_size = 5 * kPointerSize; |
| (...skipping 3008 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5366 | 5337 |
| 5367 DCHECK(interrupt_address == | 5338 DCHECK(interrupt_address == |
| 5368 isolate->builtins()->OsrAfterStackCheck()->entry()); | 5339 isolate->builtins()->OsrAfterStackCheck()->entry()); |
| 5369 return OSR_AFTER_STACK_CHECK; | 5340 return OSR_AFTER_STACK_CHECK; |
| 5370 } | 5341 } |
| 5371 | 5342 |
| 5372 | 5343 |
| 5373 } } // namespace v8::internal | 5344 } } // namespace v8::internal |
| 5374 | 5345 |
| 5375 #endif // V8_TARGET_ARCH_ARM | 5346 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |