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; |
{ |