Index: src/interpreter/bytecode-generator.cc |
diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc |
index f2a5d74029bc8f33726b604f218f48c0da6530be..b6960e51265abfce85f142497236f56750b18174 100644 |
--- a/src/interpreter/bytecode-generator.cc |
+++ b/src/interpreter/bytecode-generator.cc |
@@ -2183,6 +2183,26 @@ void BytecodeGenerator::BuildReturn() { |
if (info()->literal()->feedback_vector_spec()->HasTypeProfileSlot()) { |
builder()->CollectTypeProfile(info()->literal()->return_position()); |
} |
+ |
+ // For generators, wrap the result (for non-async generators) and |
+ // close the generator. |
+ if (IsGeneratorFunction(info()->literal()->kind())) { |
+ if (!IsAsyncGeneratorFunction(info()->literal()->kind())) { |
+ RegisterList args = register_allocator()->NewRegisterList(2); |
+ builder() |
+ ->StoreAccumulatorInRegister(args[0]) |
+ .LoadTrue() |
+ .StoreAccumulatorInRegister(args[1]) |
+ .CallRuntime(Runtime::kInlineCreateIterResultObject, args); |
+ } |
+ // Mark the generator as closed (making sure we do not clobber |
+ // the result). |
+ Register result = register_allocator()->NewRegister(); |
+ builder() |
+ ->StoreAccumulatorInRegister(result) |
+ .CallRuntime(Runtime::kInlineGeneratorClose, generator_object_) |
+ .LoadAccumulatorWithRegister(result); |
+ } |
builder()->Return(); |
} |
@@ -2546,6 +2566,14 @@ void BytecodeGenerator::BuildGeneratorSuspend(Suspend* expr, Register generator, |
.LoadFalse() |
.StoreAccumulatorInRegister(args[2]) |
.CallRuntime(Runtime::kInlineAsyncGeneratorResolve, args); |
+ } else if (expr->IsNonInitialGeneratorYield()) { |
+ // GeneratorYield: Wrap the value into IteratorResult. |
+ RegisterList args = register_allocator()->NewRegisterList(2); |
+ builder() |
+ ->MoveRegister(value, args[0]) |
+ .LoadFalse() |
+ .StoreAccumulatorInRegister(args[1]) |
+ .CallRuntime(Runtime::kInlineCreateIterResultObject, args); |
} else { |
builder()->LoadAccumulatorWithRegister(value); |
} |
@@ -2599,17 +2627,11 @@ void BytecodeGenerator::BuildGeneratorResume( |
.JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &resume_with_throw); |
// Fall through for resuming with return. |
+ builder()->LoadAccumulatorWithRegister(input); |
if (expr->is_async_generator()) { |
// Async generator methods will produce the iter result object. |
- builder()->LoadAccumulatorWithRegister(input); |
execution_control()->AsyncReturnAccumulator(); |
} else { |
- RegisterList args = register_allocator()->NewRegisterList(2); |
- builder() |
- ->MoveRegister(input, args[0]) |
- .LoadTrue() |
- .StoreAccumulatorInRegister(args[1]) |
- .CallRuntime(Runtime::kInlineCreateIterResultObject, args); |
execution_control()->ReturnAccumulator(); |
} |