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 |