| Index: src/parsing/parser.cc
|
| diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc
|
| index 8005479a32670b05c34eef744975b0d47d86af17..46f6bc22f2582c1f45aad8fa81e3cbedee41ce01 100644
|
| --- a/src/parsing/parser.cc
|
| +++ b/src/parsing/parser.cc
|
| @@ -6577,16 +6577,17 @@ void ParserTraits::BuildIteratorCloseForCompletion(
|
| //
|
| // let iteratorReturn = iterator.return;
|
| // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
|
| - // let output;
|
| // if (completion === BODY_THREW) {
|
| // if (!IS_CALLABLE(iteratorReturn)) {
|
| // throw MakeTypeError(kReturnMethodNotCallable);
|
| // }
|
| - // try { output = %_Call(iteratorReturn, iterator) } catch (_) { }
|
| + // try { %_Call(iteratorReturn, iterator) } catch (_) { }
|
| // } else {
|
| - // output = %_Call(iteratorReturn, iterator);
|
| + // let output = %_Call(iteratorReturn, iterator);
|
| + // if (!IS_RECEIVER(output)) {
|
| + // %ThrowIterResultNotAnObject(output);
|
| + // }
|
| // }
|
| - // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
|
| // }
|
| //
|
|
|
| @@ -6596,11 +6597,9 @@ void ParserTraits::BuildIteratorCloseForCompletion(
|
| auto scope = parser_->scope_;
|
| auto zone = parser_->zone();
|
|
|
| - // let output;
|
| - Variable* var_output = scope->NewTemporary(avfactory->empty_string());
|
|
|
| // let iteratorReturn = iterator.return;
|
| - Variable* var_return = var_output; // Reusing the output variable.
|
| + Variable* var_return = scope->NewTemporary(avfactory->empty_string());
|
| Statement* get_return;
|
| {
|
| Expression* iterator_proxy = factory->NewVariableProxy(iterator);
|
| @@ -6625,22 +6624,7 @@ void ParserTraits::BuildIteratorCloseForCompletion(
|
| check_return_callable = CheckCallable(var_return, throw_expr);
|
| }
|
|
|
| - // output = %_Call(iteratorReturn, iterator);
|
| - Statement* call_return;
|
| - {
|
| - auto args = new (zone) ZoneList<Expression*>(2, zone);
|
| - args->Add(factory->NewVariableProxy(var_return), zone);
|
| - args->Add(factory->NewVariableProxy(iterator), zone);
|
| - Expression* call =
|
| - factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
|
| -
|
| - Expression* output_proxy = factory->NewVariableProxy(var_output);
|
| - Expression* assignment = factory->NewAssignment(
|
| - Token::ASSIGN, output_proxy, call, nopos);
|
| - call_return = factory->NewExpressionStatement(assignment, nopos);
|
| - }
|
| -
|
| - // try { output = %_Call(iteratorReturn, iterator) } catch (_) { }
|
| + // try { %_Call(iteratorReturn, iterator) } catch (_) { }
|
| Statement* try_call_return;
|
| {
|
| auto args = new (zone) ZoneList<Expression*>(2, zone);
|
| @@ -6649,12 +6633,10 @@ void ParserTraits::BuildIteratorCloseForCompletion(
|
|
|
| Expression* call =
|
| factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
|
| - Expression* assignment = factory->NewAssignment(
|
| - Token::ASSIGN, factory->NewVariableProxy(var_output), call, nopos);
|
|
|
| Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
|
| - try_block->statements()->Add(
|
| - factory->NewExpressionStatement(assignment, nopos), zone);
|
| + try_block->statements()->Add(factory->NewExpressionStatement(call, nopos),
|
| + zone);
|
|
|
| Block* catch_block = factory->NewBlock(nullptr, 0, false, nopos);
|
|
|
| @@ -6667,29 +6649,27 @@ void ParserTraits::BuildIteratorCloseForCompletion(
|
| try_block, catch_scope, catch_variable, catch_block, nopos);
|
| }
|
|
|
| - // if (completion === ABRUPT_THROW) {
|
| - // #check_return_callable;
|
| - // #try_call_return;
|
| - // } else {
|
| - // #call_return;
|
| + // let output = %_Call(iteratorReturn, iterator);
|
| + // if (!IS_RECEIVER(output)) {
|
| + // %ThrowIteratorResultNotAnObject(output);
|
| // }
|
| - Statement* call_return_carefully;
|
| + Block* validate_return;
|
| {
|
| - Expression* condition = factory->NewCompareOperation(
|
| - Token::EQ_STRICT, factory->NewVariableProxy(completion),
|
| - factory->NewSmiLiteral(BODY_THREW, nopos), nopos);
|
| -
|
| - Block* then_block = factory->NewBlock(nullptr, 2, false, nopos);
|
| - then_block->statements()->Add(check_return_callable, zone);
|
| - then_block->statements()->Add(try_call_return, zone);
|
| + Variable* var_output = scope->NewTemporary(avfactory->empty_string());
|
| + Statement* call_return;
|
| + {
|
| + auto args = new (zone) ZoneList<Expression*>(2, zone);
|
| + args->Add(factory->NewVariableProxy(var_return), zone);
|
| + args->Add(factory->NewVariableProxy(iterator), zone);
|
| + Expression* call =
|
| + factory->NewCallRuntime(Runtime::kInlineCall, args, nopos);
|
|
|
| - call_return_carefully =
|
| - factory->NewIfStatement(condition, then_block, call_return, nopos);
|
| - }
|
| + Expression* output_proxy = factory->NewVariableProxy(var_output);
|
| + Expression* assignment =
|
| + factory->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
|
| + call_return = factory->NewExpressionStatement(assignment, nopos);
|
| + }
|
|
|
| - // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output);
|
| - Statement* validate_output;
|
| - {
|
| Expression* is_receiver_call;
|
| {
|
| auto args = new (zone) ZoneList<Expression*>(1, zone);
|
| @@ -6707,8 +6687,32 @@ void ParserTraits::BuildIteratorCloseForCompletion(
|
| throw_call = factory->NewExpressionStatement(call, nopos);
|
| }
|
|
|
| - validate_output = factory->NewIfStatement(
|
| + Statement* check_return = factory->NewIfStatement(
|
| is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos);
|
| +
|
| + validate_return = factory->NewBlock(nullptr, 2, false, nopos);
|
| + validate_return->statements()->Add(call_return, zone);
|
| + validate_return->statements()->Add(check_return, zone);
|
| + }
|
| +
|
| + // if (completion === BODY_THREW) {
|
| + // #check_return_callable;
|
| + // #try_call_return;
|
| + // } else {
|
| + // #validate_return;
|
| + // }
|
| + Statement* call_return_carefully;
|
| + {
|
| + Expression* condition = factory->NewCompareOperation(
|
| + Token::EQ_STRICT, factory->NewVariableProxy(completion),
|
| + factory->NewSmiLiteral(BODY_THREW, nopos), nopos);
|
| +
|
| + Block* then_block = factory->NewBlock(nullptr, 2, false, nopos);
|
| + then_block->statements()->Add(check_return_callable, zone);
|
| + then_block->statements()->Add(try_call_return, zone);
|
| +
|
| + call_return_carefully =
|
| + factory->NewIfStatement(condition, then_block, validate_return, nopos);
|
| }
|
|
|
| // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... }
|
| @@ -6718,12 +6722,9 @@ void ParserTraits::BuildIteratorCloseForCompletion(
|
| Token::EQ, factory->NewVariableProxy(var_return),
|
| factory->NewNullLiteral(nopos), nopos);
|
|
|
| - Block* block = factory->NewBlock(nullptr, 2, false, nopos);
|
| - block->statements()->Add(call_return_carefully, zone);
|
| - block->statements()->Add(validate_output, zone);
|
| -
|
| - maybe_call_return = factory->NewIfStatement(
|
| - condition, factory->NewEmptyStatement(nopos), block, nopos);
|
| + maybe_call_return =
|
| + factory->NewIfStatement(condition, factory->NewEmptyStatement(nopos),
|
| + call_return_carefully, nopos);
|
| }
|
|
|
|
|
| @@ -6746,7 +6747,7 @@ Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) {
|
| // throw e;
|
| // } finally {
|
| // if (!(completion === BODY_COMPLETED || IS_UNDEFINED(#iterator))) {
|
| - // #BuildIteratorClose(#iterator, completion) // See above.
|
| + // #BuildIteratorCloseForCompletion(#iterator, completion)
|
| // }
|
| // }
|
| //
|
| @@ -6793,7 +6794,7 @@ Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) {
|
| }
|
|
|
| // if (!(completion === BODY_COMPLETED || IS_UNDEFINED(#iterator))) {
|
| - // #BuildIteratorClose(#iterator, completion)
|
| + // #BuildIteratorCloseForCompletion(#iterator, completion)
|
| // }
|
| Block* maybe_close;
|
| {
|
|
|