| Index: src/parsing/parser.cc
|
| diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc
|
| index 5c6f1aa8f433229e9426c96f236d748684af70cc..b16771dc0b49c0344c2610a4fc1c80b8f1bad807 100644
|
| --- a/src/parsing/parser.cc
|
| +++ b/src/parsing/parser.cc
|
| @@ -6049,9 +6049,8 @@ Expression* ParserTraits::RewriteYieldStar(
|
|
|
| Block* then = factory->NewBlock(nullptr, 4+1, false, nopos);
|
| Variable* var_tmp = scope->NewTemporary(avfactory->empty_string());
|
| - BuildIteratorClose(
|
| - then->statements(), var_iterator, factory->NewUndefinedLiteral(nopos),
|
| - var_tmp);
|
| + BuildIteratorClose(then->statements(), var_iterator, Nothing<Variable*>(),
|
| + var_tmp);
|
| then->statements()->Add(throw_call, zone);
|
| check_throw = factory->NewIfStatement(
|
| condition, then, factory->NewEmptyStatement(nopos), nopos);
|
| @@ -6226,8 +6225,7 @@ Expression* ParserTraits::RewriteYieldStar(
|
| case_next->Add(factory->NewBreakStatement(switch_mode, nopos), zone);
|
|
|
| auto case_return = new (zone) ZoneList<Statement*>(5, zone);
|
| - BuildIteratorClose(case_return, var_iterator,
|
| - factory->NewVariableProxy(var_input, nopos), var_output);
|
| + BuildIteratorClose(case_return, var_iterator, Just(var_input), var_output);
|
| case_return->Add(factory->NewBreakStatement(switch_mode, nopos), zone);
|
|
|
| auto case_throw = new (zone) ZoneList<Statement*>(5, zone);
|
| @@ -6472,17 +6470,21 @@ Statement* ParserTraits::CheckCallable(Variable* var, Expression* error) {
|
|
|
| void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements,
|
| Variable* iterator,
|
| - Expression* input,
|
| + Maybe<Variable*> input,
|
| Variable* var_output) {
|
| //
|
| // This function adds four statements to [statements], corresponding to the
|
| // following code:
|
| //
|
| // let iteratorReturn = iterator.return;
|
| - // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return input;
|
| - // output = %_Call(iteratorReturn, iterator);
|
| + // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return |input|;
|
| + // output = %_Call(iteratorReturn, iterator|, input|);
|
| // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
|
| //
|
| + // Here, |...| denotes optional parts, depending on the presence of the
|
| + // input variable. The reason for allowing input is that BuildIteratorClose
|
| + // can then be reused to handle the return case in yield*.
|
| + //
|
|
|
| const int nopos = RelocInfo::kNoPosition;
|
| auto factory = parser_->factory();
|
| @@ -6504,25 +6506,33 @@ void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements,
|
| get_return = factory->NewExpressionStatement(assignment, nopos);
|
| }
|
|
|
| - // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return input;
|
| + // if (IS_NULL_OR_UNDEFINED(iteratorReturn) return |input|;
|
| Statement* check_return;
|
| {
|
| Expression* condition = factory->NewCompareOperation(
|
| Token::EQ, factory->NewVariableProxy(var_return),
|
| factory->NewNullLiteral(nopos), nopos);
|
|
|
| - Statement* return_input = factory->NewReturnStatement(input, nopos);
|
| + Expression* value = input.IsJust()
|
| + ? static_cast<Expression*>(
|
| + factory->NewVariableProxy(input.FromJust()))
|
| + : factory->NewUndefinedLiteral(nopos);
|
| +
|
| + Statement* return_input = factory->NewReturnStatement(value, nopos);
|
|
|
| check_return = factory->NewIfStatement(
|
| condition, return_input, factory->NewEmptyStatement(nopos), nopos);
|
| }
|
|
|
| - // output = %_Call(iteratorReturn, iterator);
|
| + // output = %_Call(iteratorReturn, iterator, |input|);
|
| Statement* call_return;
|
| {
|
| auto args = new (zone) ZoneList<Expression*>(3, zone);
|
| args->Add(factory->NewVariableProxy(var_return), zone);
|
| args->Add(factory->NewVariableProxy(iterator), zone);
|
| + if (input.IsJust()) {
|
| + args->Add(factory->NewVariableProxy(input.FromJust()), zone);
|
| + }
|
|
|
| Expression* call =
|
| factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
|
|
|