Index: src/ia32/full-codegen-ia32.cc |
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc |
index 04a0f7fe75790bb931a649d15ff95f6083c6fde9..ea69f7e9fd4fb1449c09b0ac4611560e77135fae 100644 |
--- a/src/ia32/full-codegen-ia32.cc |
+++ b/src/ia32/full-codegen-ia32.cc |
@@ -2074,19 +2074,21 @@ void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
Expression *value, |
JSGeneratorObject::ResumeMode resume_mode) { |
// The value stays in eax, and is ultimately read by the resumed generator, as |
- // if the CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. ebx |
- // will hold the generator object until the activation has been resumed. |
+ // if the CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it |
+ // is read to throw the value when the resumed generator is already closed. |
+ // ebx will hold the generator object until the activation has been resumed. |
VisitForStackValue(generator); |
VisitForAccumulatorValue(value); |
__ pop(ebx); |
// Check generator state. |
- Label wrong_state, done; |
- STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting <= 0); |
- STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed <= 0); |
+ Label wrong_state, closed_state, done; |
+ STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); |
+ STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0); |
__ cmp(FieldOperand(ebx, JSGeneratorObject::kContinuationOffset), |
Immediate(Smi::FromInt(0))); |
- __ j(less_equal, &wrong_state); |
+ __ j(equal, &closed_state); |
+ __ j(less, &wrong_state); |
// Load suspended function and context. |
__ mov(esi, FieldOperand(ebx, JSGeneratorObject::kContextOffset)); |
@@ -2156,6 +2158,20 @@ void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
// Not reached: the runtime call returns elsewhere. |
__ Abort(kGeneratorFailedToResume); |
+ // Reach here when generator is closed. |
+ __ bind(&closed_state); |
+ if (resume_mode == JSGeneratorObject::NEXT) { |
+ // Return completed iterator result when generator is closed. |
+ __ push(Immediate(isolate()->factory()->undefined_value())); |
+ // Pop value from top-of-stack slot; box result into result register. |
+ EmitCreateIteratorResult(true); |
+ } else { |
+ // Throw the provided value. |
+ __ push(eax); |
+ __ CallRuntime(Runtime::kThrow, 1); |
Michael Starzinger
2014/01/14 13:17:44
I am not sure if throwing directly from within her
|
+ } |
+ __ jmp(&done); |
+ |
// Throw error if we attempt to operate on a running generator. |
__ bind(&wrong_state); |
__ push(ebx); |