Index: src/full-codegen/x64/full-codegen-x64.cc |
diff --git a/src/full-codegen/x64/full-codegen-x64.cc b/src/full-codegen/x64/full-codegen-x64.cc |
index 615eb67ba6459542be354eda2ecab900a787d471..878f2566aef38cbfe21a3fb0eac612dbe7f630a0 100644 |
--- a/src/full-codegen/x64/full-codegen-x64.cc |
+++ b/src/full-codegen/x64/full-codegen-x64.cc |
@@ -1871,8 +1871,17 @@ void FullCodeGenerator::VisitYield(Yield* expr) { |
__ jmp(&suspend); |
__ bind(&continuation); |
+ // When we arrive here, the stack top is the resume mode and |
+ // result_register() holds the input value (the argument given to the |
+ // respective resume operation). |
__ RecordGeneratorContinuation(); |
- __ jmp(&resume); |
+ __ Pop(rbx); |
+ __ SmiCompare(rbx, Smi::FromInt(JSGeneratorObject::RETURN)); |
+ __ j(not_equal, &resume); |
+ __ Push(result_register()); |
+ EmitCreateIteratorResult(true); |
+ EmitUnwindBeforeReturn(); |
+ EmitReturnSequence(); |
__ bind(&suspend); |
VisitForAccumulatorValue(expr->generator_object()); |
@@ -1902,9 +1911,6 @@ void FullCodeGenerator::VisitYield(Yield* expr) { |
case Yield::kFinal: { |
VisitForAccumulatorValue(expr->generator_object()); |
- __ Move(FieldOperand(result_register(), |
- JSGeneratorObject::kContinuationOffset), |
- Smi::FromInt(JSGeneratorObject::kGeneratorClosed)); |
// Pop value from top-of-stack slot, box result into result register. |
EmitCreateIteratorResult(true); |
EmitUnwindBeforeReturn(); |
@@ -1949,6 +1955,10 @@ void FullCodeGenerator::VisitYield(Yield* expr) { |
__ jmp(&l_suspend); |
__ bind(&l_continuation); |
__ RecordGeneratorContinuation(); |
+ __ Pop(rbx); |
+ // Ignoring the resume mode here is clearly wrong. Currently, return is |
Jarin
2016/01/22 13:42:48
TODO(neis), perhaps?
|
+ // not supported for yield*. The planned desugaring of yield* using |
+ // do-expressions will naturally solve this. |
__ jmp(&l_resume); |
__ bind(&l_suspend); |
@@ -2024,8 +2034,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) { |
} |
-void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
- Expression *value, |
+void FullCodeGenerator::EmitGeneratorResume( |
+ Expression* generator, Expression* value, |
JSGeneratorObject::ResumeMode resume_mode) { |
// The value stays in rax, and is ultimately read by the resumed generator, as |
// if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it |
@@ -2083,6 +2093,7 @@ void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
__ addp(rdx, rcx); |
__ Move(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset), |
Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)); |
+ __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation. |
__ jmp(rdx); |
__ bind(&slow_resume); |
} |
@@ -2096,6 +2107,7 @@ void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
__ Push(rcx); |
__ jmp(&push_operand_holes); |
__ bind(&call_resume); |
+ __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation. |
__ Push(rbx); |
__ Push(result_register()); |
__ Push(Smi::FromInt(resume_mode)); |