OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/ast/ast-expression-rewriter.h" | 10 #include "src/ast/ast-expression-rewriter.h" |
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 info->extension() == nullptr && can_compile_lazily; | 546 info->extension() == nullptr && can_compile_lazily; |
547 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); | 547 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); |
548 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && | 548 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && |
549 info->isolate()->is_tail_call_elimination_enabled()); | 549 info->isolate()->is_tail_call_elimination_enabled()); |
550 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); | 550 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); |
551 set_allow_harmony_function_sent(FLAG_harmony_function_sent); | 551 set_allow_harmony_function_sent(FLAG_harmony_function_sent); |
552 set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators); | 552 set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators); |
553 set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas); | 553 set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas); |
554 set_allow_harmony_class_fields(FLAG_harmony_class_fields); | 554 set_allow_harmony_class_fields(FLAG_harmony_class_fields); |
555 set_allow_harmony_object_rest_spread(FLAG_harmony_object_rest_spread); | 555 set_allow_harmony_object_rest_spread(FLAG_harmony_object_rest_spread); |
| 556 set_allow_harmony_async_iteration(FLAG_harmony_async_iteration); |
556 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 557 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
557 ++feature) { | 558 ++feature) { |
558 use_counts_[feature] = 0; | 559 use_counts_[feature] = 0; |
559 } | 560 } |
560 if (info->ast_value_factory() == NULL) { | 561 if (info->ast_value_factory() == NULL) { |
561 // info takes ownership of AstValueFactory. | 562 // info takes ownership of AstValueFactory. |
562 info->set_ast_value_factory(new AstValueFactory( | 563 info->set_ast_value_factory(new AstValueFactory( |
563 zone(), info->isolate()->ast_string_constants(), info->hash_seed())); | 564 zone(), info->isolate()->ast_string_constants(), info->hash_seed())); |
564 info->set_ast_value_factory_owned(); | 565 info->set_ast_value_factory_owned(); |
565 ast_value_factory_ = info->ast_value_factory(); | 566 ast_value_factory_ = info->ast_value_factory(); |
(...skipping 1181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1747 DCHECK_NOT_NULL(catch_info.scope); | 1748 DCHECK_NOT_NULL(catch_info.scope); |
1748 DCHECK_NOT_NULL(catch_info.variable); | 1749 DCHECK_NOT_NULL(catch_info.variable); |
1749 return factory()->NewTryCatchStatement( | 1750 return factory()->NewTryCatchStatement( |
1750 try_block, catch_info.scope, catch_info.variable, catch_block, pos); | 1751 try_block, catch_info.scope, catch_info.variable, catch_block, pos); |
1751 } else { | 1752 } else { |
1752 DCHECK_NOT_NULL(finally_block); | 1753 DCHECK_NOT_NULL(finally_block); |
1753 return factory()->NewTryFinallyStatement(try_block, finally_block, pos); | 1754 return factory()->NewTryFinallyStatement(try_block, finally_block, pos); |
1754 } | 1755 } |
1755 } | 1756 } |
1756 | 1757 |
1757 // !%_IsJSReceiver(result = iterator.next()) && | 1758 // [if (IteratorType == kNormal)] |
1758 // %ThrowIteratorResultNotAnObject(result) | 1759 // !%_IsJSReceiver(result = iterator.next()) && |
| 1760 // %ThrowIteratorResultNotAnObject(result) |
| 1761 // [else if (IteratorType == kAsync)] |
| 1762 // !%_IsJSReceiver(result = Await(iterator.next())) && |
| 1763 // %ThrowIteratorResultNotAnObject(result) |
| 1764 // [endif] |
1759 Expression* Parser::BuildIteratorNextResult(Expression* iterator, | 1765 Expression* Parser::BuildIteratorNextResult(Expression* iterator, |
1760 Variable* result, int pos) { | 1766 Variable* result, IteratorType type, |
| 1767 int pos) { |
1761 Expression* next_literal = factory()->NewStringLiteral( | 1768 Expression* next_literal = factory()->NewStringLiteral( |
1762 ast_value_factory()->next_string(), kNoSourcePosition); | 1769 ast_value_factory()->next_string(), kNoSourcePosition); |
1763 Expression* next_property = | 1770 Expression* next_property = |
1764 factory()->NewProperty(iterator, next_literal, kNoSourcePosition); | 1771 factory()->NewProperty(iterator, next_literal, kNoSourcePosition); |
1765 ZoneList<Expression*>* next_arguments = | 1772 ZoneList<Expression*>* next_arguments = |
1766 new (zone()) ZoneList<Expression*>(0, zone()); | 1773 new (zone()) ZoneList<Expression*>(0, zone()); |
1767 Expression* next_call = | 1774 Expression* next_call = |
1768 factory()->NewCall(next_property, next_arguments, pos); | 1775 factory()->NewCall(next_property, next_arguments, pos); |
| 1776 if (type == IteratorType::kAsync) { |
| 1777 next_call = RewriteAwaitExpression(next_call, pos); |
| 1778 } |
1769 Expression* result_proxy = factory()->NewVariableProxy(result); | 1779 Expression* result_proxy = factory()->NewVariableProxy(result); |
1770 Expression* left = | 1780 Expression* left = |
1771 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos); | 1781 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos); |
1772 | 1782 |
1773 // %_IsJSReceiver(...) | 1783 // %_IsJSReceiver(...) |
1774 ZoneList<Expression*>* is_spec_object_args = | 1784 ZoneList<Expression*>* is_spec_object_args = |
1775 new (zone()) ZoneList<Expression*>(1, zone()); | 1785 new (zone()) ZoneList<Expression*>(1, zone()); |
1776 is_spec_object_args->Add(left, zone()); | 1786 is_spec_object_args->Add(left, zone()); |
1777 Expression* is_spec_object_call = factory()->NewCallRuntime( | 1787 Expression* is_spec_object_call = factory()->NewCallRuntime( |
1778 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos); | 1788 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos); |
(...skipping 14 matching lines...) Expand all Loading... |
1793 | 1803 |
1794 Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt, | 1804 Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt, |
1795 Expression* each, | 1805 Expression* each, |
1796 Expression* subject, | 1806 Expression* subject, |
1797 Statement* body, | 1807 Statement* body, |
1798 int each_keyword_pos) { | 1808 int each_keyword_pos) { |
1799 ForOfStatement* for_of = stmt->AsForOfStatement(); | 1809 ForOfStatement* for_of = stmt->AsForOfStatement(); |
1800 if (for_of != NULL) { | 1810 if (for_of != NULL) { |
1801 const bool finalize = true; | 1811 const bool finalize = true; |
1802 return InitializeForOfStatement(for_of, each, subject, body, finalize, | 1812 return InitializeForOfStatement(for_of, each, subject, body, finalize, |
1803 each_keyword_pos); | 1813 IteratorType::kNormal, each_keyword_pos); |
1804 } else { | 1814 } else { |
1805 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { | 1815 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { |
1806 Variable* temp = NewTemporary(ast_value_factory()->empty_string()); | 1816 Variable* temp = NewTemporary(ast_value_factory()->empty_string()); |
1807 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 1817 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
1808 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment( | 1818 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment( |
1809 this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy, | 1819 this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy, |
1810 kNoSourcePosition), | 1820 kNoSourcePosition), |
1811 scope()); | 1821 scope()); |
1812 auto block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition); | 1822 auto block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition); |
1813 block->statements()->Add( | 1823 block->statements()->Add( |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1947 // INTERNAL variable that's invisible to the debugger | 1957 // INTERNAL variable that's invisible to the debugger |
1948 // but visible to everything else. | 1958 // but visible to everything else. |
1949 Declaration* tdz_decl = DeclareVariable(for_info.bound_names[i], LET, | 1959 Declaration* tdz_decl = DeclareVariable(for_info.bound_names[i], LET, |
1950 kNoSourcePosition, CHECK_OK); | 1960 kNoSourcePosition, CHECK_OK); |
1951 tdz_decl->proxy()->var()->set_initializer_position(position()); | 1961 tdz_decl->proxy()->var()->set_initializer_position(position()); |
1952 } | 1962 } |
1953 } | 1963 } |
1954 return init_block; | 1964 return init_block; |
1955 } | 1965 } |
1956 | 1966 |
1957 Statement* Parser::InitializeForOfStatement(ForOfStatement* for_of, | 1967 Statement* Parser::InitializeForOfStatement( |
1958 Expression* each, | 1968 ForEachStatement* for_each, Expression* each, Expression* iterable, |
1959 Expression* iterable, | 1969 Statement* body, bool finalize, IteratorType type, int next_result_pos) { |
1960 Statement* body, bool finalize, | |
1961 int next_result_pos) { | |
1962 // Create the auxiliary expressions needed for iterating over the iterable, | 1970 // Create the auxiliary expressions needed for iterating over the iterable, |
1963 // and initialize the given ForOfStatement with them. | 1971 // and initialize the given ForOfStatement with them. |
1964 // If finalize is true, also instrument the loop with code that performs the | 1972 // If finalize is true, also instrument the loop with code that performs the |
1965 // proper ES6 iterator finalization. In that case, the result is not | 1973 // proper ES6 iterator finalization. In that case, the result is not |
1966 // immediately a ForOfStatement. | 1974 // immediately a ForOfStatement. |
| 1975 DCHECK(for_each->IsForOfStatement()); |
| 1976 ForOfStatement* for_of = for_each->AsForOfStatement(); |
1967 | 1977 |
1968 const int nopos = kNoSourcePosition; | 1978 const int nopos = kNoSourcePosition; |
1969 auto avfactory = ast_value_factory(); | 1979 auto avfactory = ast_value_factory(); |
1970 | 1980 |
1971 Variable* iterator = NewTemporary(avfactory->dot_iterator_string()); | 1981 Variable* iterator = NewTemporary(avfactory->dot_iterator_string()); |
1972 Variable* result = NewTemporary(avfactory->dot_result_string()); | 1982 Variable* result = NewTemporary(avfactory->dot_result_string()); |
1973 Variable* completion = NewTemporary(avfactory->empty_string()); | 1983 Variable* completion = NewTemporary(avfactory->empty_string()); |
1974 | 1984 |
1975 // iterator = GetIterator(iterable) | 1985 // iterator = GetIterator(iterable, type) |
1976 Expression* assign_iterator; | 1986 Expression* assign_iterator; |
1977 { | 1987 { |
1978 assign_iterator = factory()->NewAssignment( | 1988 assign_iterator = factory()->NewAssignment( |
1979 Token::ASSIGN, factory()->NewVariableProxy(iterator), | 1989 Token::ASSIGN, factory()->NewVariableProxy(iterator), |
1980 factory()->NewGetIterator(iterable, iterable->position()), | 1990 factory()->NewGetIterator(iterable, type, iterable->position()), |
1981 iterable->position()); | 1991 iterable->position()); |
1982 } | 1992 } |
1983 | 1993 |
1984 // !%_IsJSReceiver(result = iterator.next()) && | 1994 // [if (IteratorType == kNormal)] |
1985 // %ThrowIteratorResultNotAnObject(result) | 1995 // !%_IsJSReceiver(result = iterator.next()) && |
| 1996 // %ThrowIteratorResultNotAnObject(result) |
| 1997 // [else if (IteratorType == kAsync)] |
| 1998 // !%_IsJSReceiver(result = Await(iterator.next())) && |
| 1999 // %ThrowIteratorResultNotAnObject(result) |
| 2000 // [endif] |
1986 Expression* next_result; | 2001 Expression* next_result; |
1987 { | 2002 { |
1988 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2003 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
1989 next_result = | 2004 next_result = |
1990 BuildIteratorNextResult(iterator_proxy, result, next_result_pos); | 2005 BuildIteratorNextResult(iterator_proxy, result, type, next_result_pos); |
1991 } | 2006 } |
1992 | 2007 |
1993 // result.done | 2008 // result.done |
1994 Expression* result_done; | 2009 Expression* result_done; |
1995 { | 2010 { |
1996 Expression* done_literal = factory()->NewStringLiteral( | 2011 Expression* done_literal = factory()->NewStringLiteral( |
1997 ast_value_factory()->done_string(), kNoSourcePosition); | 2012 ast_value_factory()->done_string(), kNoSourcePosition); |
1998 Expression* result_proxy = factory()->NewVariableProxy(result); | 2013 Expression* result_proxy = factory()->NewVariableProxy(result); |
1999 result_done = | 2014 result_done = |
2000 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition); | 2015 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2068 // Statement* body (gets overwritten) | 2083 // Statement* body (gets overwritten) |
2069 if (finalize) { | 2084 if (finalize) { |
2070 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); | 2085 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); |
2071 block->statements()->Add(body, zone()); | 2086 block->statements()->Add(body, zone()); |
2072 block->statements()->Add(set_completion_normal, zone()); | 2087 block->statements()->Add(set_completion_normal, zone()); |
2073 body = block; | 2088 body = block; |
2074 } | 2089 } |
2075 | 2090 |
2076 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, | 2091 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, |
2077 assign_each); | 2092 assign_each); |
2078 return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of; | 2093 return finalize ? FinalizeForOfStatement(for_of, completion, type, nopos) |
| 2094 : for_of; |
2079 } | 2095 } |
2080 | 2096 |
2081 Statement* Parser::DesugarLexicalBindingsInForStatement( | 2097 Statement* Parser::DesugarLexicalBindingsInForStatement( |
2082 ForStatement* loop, Statement* init, Expression* cond, Statement* next, | 2098 ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
2083 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) { | 2099 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) { |
2084 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are | 2100 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are |
2085 // copied into a new environment. Moreover, the "next" statement must be | 2101 // copied into a new environment. Moreover, the "next" statement must be |
2086 // evaluated not in the environment of the just completed iteration but in | 2102 // evaluated not in the environment of the just completed iteration but in |
2087 // that of the upcoming one. We achieve this with the following desugaring. | 2103 // that of the upcoming one. We achieve this with the following desugaring. |
2088 // Extra care is needed to preserve the completion value of the original loop. | 2104 // Extra care is needed to preserve the completion value of the original loop. |
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2733 reusable_preparser_ = new PreParser( | 2749 reusable_preparser_ = new PreParser( |
2734 zone(), &scanner_, stack_limit_, ast_value_factory(), | 2750 zone(), &scanner_, stack_limit_, ast_value_factory(), |
2735 &pending_error_handler_, runtime_call_stats_, parsing_on_main_thread_); | 2751 &pending_error_handler_, runtime_call_stats_, parsing_on_main_thread_); |
2736 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); | 2752 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); |
2737 SET_ALLOW(natives); | 2753 SET_ALLOW(natives); |
2738 SET_ALLOW(harmony_do_expressions); | 2754 SET_ALLOW(harmony_do_expressions); |
2739 SET_ALLOW(harmony_function_sent); | 2755 SET_ALLOW(harmony_function_sent); |
2740 SET_ALLOW(harmony_trailing_commas); | 2756 SET_ALLOW(harmony_trailing_commas); |
2741 SET_ALLOW(harmony_class_fields); | 2757 SET_ALLOW(harmony_class_fields); |
2742 SET_ALLOW(harmony_object_rest_spread); | 2758 SET_ALLOW(harmony_object_rest_spread); |
| 2759 SET_ALLOW(harmony_async_iteration); |
2743 #undef SET_ALLOW | 2760 #undef SET_ALLOW |
2744 } | 2761 } |
2745 // Aborting inner function preparsing would leave scopes in an inconsistent | 2762 // Aborting inner function preparsing would leave scopes in an inconsistent |
2746 // state; we don't parse inner functions in the abortable mode anyway. | 2763 // state; we don't parse inner functions in the abortable mode anyway. |
2747 DCHECK(!is_inner_function || !may_abort); | 2764 DCHECK(!is_inner_function || !may_abort); |
2748 | 2765 |
2749 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( | 2766 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( |
2750 kind, function_scope, parsing_module_, is_inner_function, may_abort, | 2767 kind, function_scope, parsing_module_, is_inner_function, may_abort, |
2751 use_counts_); | 2768 use_counts_); |
2752 | 2769 |
(...skipping 1393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4146 factory()->NewCallRuntime(Runtime::kAppendElement, | 4163 factory()->NewCallRuntime(Runtime::kAppendElement, |
4147 append_element_args, kNoSourcePosition), | 4164 append_element_args, kNoSourcePosition), |
4148 kNoSourcePosition); | 4165 kNoSourcePosition); |
4149 } | 4166 } |
4150 // for (each of spread) %AppendElement($R, each) | 4167 // for (each of spread) %AppendElement($R, each) |
4151 ForEachStatement* loop = factory()->NewForEachStatement( | 4168 ForEachStatement* loop = factory()->NewForEachStatement( |
4152 ForEachStatement::ITERATE, nullptr, kNoSourcePosition); | 4169 ForEachStatement::ITERATE, nullptr, kNoSourcePosition); |
4153 const bool finalize = false; | 4170 const bool finalize = false; |
4154 InitializeForOfStatement(loop->AsForOfStatement(), | 4171 InitializeForOfStatement(loop->AsForOfStatement(), |
4155 factory()->NewVariableProxy(each), subject, | 4172 factory()->NewVariableProxy(each), subject, |
4156 append_body, finalize); | 4173 append_body, finalize, IteratorType::kNormal); |
4157 do_block->statements()->Add(loop, zone()); | 4174 do_block->statements()->Add(loop, zone()); |
4158 } | 4175 } |
4159 } | 4176 } |
4160 // Now, rewind the original array literal to truncate everything from the | 4177 // Now, rewind the original array literal to truncate everything from the |
4161 // first spread (included) until the end. This fixes $R's initialization. | 4178 // first spread (included) until the end. This fixes $R's initialization. |
4162 lit->RewindSpreads(); | 4179 lit->RewindSpreads(); |
4163 return factory()->NewDoExpression(do_block, result, lit->position()); | 4180 return factory()->NewDoExpression(do_block, result, lit->position()); |
4164 } | 4181 } |
4165 | 4182 |
4166 void Parser::QueueDestructuringAssignmentForRewriting(Expression* expr) { | 4183 void Parser::QueueDestructuringAssignmentForRewriting(Expression* expr) { |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4338 Expression* assignment = | 4355 Expression* assignment = |
4339 factory()->NewAssignment(Token::ASSIGN, output_proxy, | 4356 factory()->NewAssignment(Token::ASSIGN, output_proxy, |
4340 factory()->NewUndefinedLiteral(nopos), nopos); | 4357 factory()->NewUndefinedLiteral(nopos), nopos); |
4341 initialize_output = factory()->NewExpressionStatement(assignment, nopos); | 4358 initialize_output = factory()->NewExpressionStatement(assignment, nopos); |
4342 } | 4359 } |
4343 | 4360 |
4344 // let iterator = GetIterator(iterable); | 4361 // let iterator = GetIterator(iterable); |
4345 Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string()); | 4362 Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string()); |
4346 Statement* get_iterator; | 4363 Statement* get_iterator; |
4347 { | 4364 { |
4348 Expression* iterator = factory()->NewGetIterator(iterable, nopos); | 4365 Expression* iterator = |
| 4366 factory()->NewGetIterator(iterable, GetIterator::Hint::kNormal, nopos); |
4349 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); | 4367 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); |
4350 Expression* assignment = factory()->NewAssignment( | 4368 Expression* assignment = factory()->NewAssignment( |
4351 Token::ASSIGN, iterator_proxy, iterator, nopos); | 4369 Token::ASSIGN, iterator_proxy, iterator, nopos); |
4352 get_iterator = factory()->NewExpressionStatement(assignment, nopos); | 4370 get_iterator = factory()->NewExpressionStatement(assignment, nopos); |
4353 } | 4371 } |
4354 | 4372 |
4355 // output = iterator.next(input); | 4373 // output = iterator.next(input); |
4356 Statement* call_next; | 4374 Statement* call_next; |
4357 { | 4375 { |
4358 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); | 4376 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4420 Token::EQ, factory()->NewVariableProxy(var_throw), | 4438 Token::EQ, factory()->NewVariableProxy(var_throw), |
4421 factory()->NewNullLiteral(nopos), nopos); | 4439 factory()->NewNullLiteral(nopos), nopos); |
4422 Expression* call = | 4440 Expression* call = |
4423 NewThrowTypeError(MessageTemplate::kThrowMethodMissing, | 4441 NewThrowTypeError(MessageTemplate::kThrowMethodMissing, |
4424 ast_value_factory()->empty_string(), nopos); | 4442 ast_value_factory()->empty_string(), nopos); |
4425 Statement* throw_call = factory()->NewExpressionStatement(call, nopos); | 4443 Statement* throw_call = factory()->NewExpressionStatement(call, nopos); |
4426 | 4444 |
4427 Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos); | 4445 Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos); |
4428 BuildIteratorCloseForCompletion( | 4446 BuildIteratorCloseForCompletion( |
4429 scope(), then->statements(), var_iterator, | 4447 scope(), then->statements(), var_iterator, |
4430 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos)); | 4448 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), |
| 4449 IteratorType::kNormal); |
4431 then->statements()->Add(throw_call, zone()); | 4450 then->statements()->Add(throw_call, zone()); |
4432 check_throw = factory()->NewIfStatement( | 4451 check_throw = factory()->NewIfStatement( |
4433 condition, then, factory()->NewEmptyStatement(nopos), nopos); | 4452 condition, then, factory()->NewEmptyStatement(nopos), nopos); |
4434 } | 4453 } |
4435 | 4454 |
4436 // output = %_Call(iteratorThrow, iterator, input); | 4455 // output = %_Call(iteratorThrow, iterator, input); |
4437 Statement* call_throw; | 4456 Statement* call_throw; |
4438 { | 4457 { |
4439 auto args = new (zone()) ZoneList<Expression*>(3, zone()); | 4458 auto args = new (zone()) ZoneList<Expression*>(3, zone()); |
4440 args->Add(factory()->NewVariableProxy(var_throw), zone()); | 4459 args->Add(factory()->NewVariableProxy(var_throw), zone()); |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4699 Variable* iterator, Variable* input, | 4718 Variable* iterator, Variable* input, |
4700 Variable* var_output) { | 4719 Variable* var_output) { |
4701 // | 4720 // |
4702 // This function adds four statements to [statements], corresponding to the | 4721 // This function adds four statements to [statements], corresponding to the |
4703 // following code: | 4722 // following code: |
4704 // | 4723 // |
4705 // let iteratorReturn = iterator.return; | 4724 // let iteratorReturn = iterator.return; |
4706 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { | 4725 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { |
4707 // return {value: input, done: true}; | 4726 // return {value: input, done: true}; |
4708 // } | 4727 // } |
4709 // output = %_Call(iteratorReturn, iterator, input); | 4728 // |
| 4729 // [if (IteratorType == kAsync)] |
| 4730 // output = Await(%_Call(iteratorReturn, iterator, input)); |
| 4731 // [else] |
| 4732 // output = %_Call(iteratorReturn, iterator, input); |
| 4733 // [endif] |
| 4734 // |
4710 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 4735 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); |
4711 // | 4736 // |
4712 | 4737 |
4713 const int nopos = kNoSourcePosition; | 4738 const int nopos = kNoSourcePosition; |
4714 | 4739 |
4715 // let iteratorReturn = iterator.return; | 4740 // let iteratorReturn = iterator.return; |
4716 Variable* var_return = var_output; // Reusing the output variable. | 4741 Variable* var_return = var_output; // Reusing the output variable. |
4717 Statement* get_return; | 4742 Statement* get_return; |
4718 { | 4743 { |
4719 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 4744 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4787 } | 4812 } |
4788 | 4813 |
4789 statements->Add(get_return, zone()); | 4814 statements->Add(get_return, zone()); |
4790 statements->Add(check_return, zone()); | 4815 statements->Add(check_return, zone()); |
4791 statements->Add(call_return, zone()); | 4816 statements->Add(call_return, zone()); |
4792 statements->Add(validate_output, zone()); | 4817 statements->Add(validate_output, zone()); |
4793 } | 4818 } |
4794 | 4819 |
4795 void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion, | 4820 void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion, |
4796 Expression* condition, Variable* iter, | 4821 Expression* condition, Variable* iter, |
4797 Block* iterator_use, Block* target) { | 4822 Block* iterator_use, Block* target, |
| 4823 IteratorType type) { |
4798 // | 4824 // |
4799 // This function adds two statements to [target], corresponding to the | 4825 // This function adds two statements to [target], corresponding to the |
4800 // following code: | 4826 // following code: |
4801 // | 4827 // |
4802 // completion = kNormalCompletion; | 4828 // completion = kNormalCompletion; |
4803 // try { | 4829 // try { |
4804 // try { | 4830 // try { |
4805 // iterator_use | 4831 // iterator_use |
4806 // } catch(e) { | 4832 // } catch(e) { |
4807 // if (completion === kAbruptCompletion) completion = kThrowCompletion; | 4833 // if (completion === kAbruptCompletion) completion = kThrowCompletion; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4843 condition, statement, factory()->NewEmptyStatement(nopos), nopos); | 4869 condition, statement, factory()->NewEmptyStatement(nopos), nopos); |
4844 } | 4870 } |
4845 | 4871 |
4846 // if (condition) { | 4872 // if (condition) { |
4847 // #BuildIteratorCloseForCompletion(iter, completion) | 4873 // #BuildIteratorCloseForCompletion(iter, completion) |
4848 // } | 4874 // } |
4849 Block* maybe_close; | 4875 Block* maybe_close; |
4850 { | 4876 { |
4851 Block* block = factory()->NewBlock(nullptr, 2, true, nopos); | 4877 Block* block = factory()->NewBlock(nullptr, 2, true, nopos); |
4852 Expression* proxy = factory()->NewVariableProxy(completion); | 4878 Expression* proxy = factory()->NewVariableProxy(completion); |
4853 BuildIteratorCloseForCompletion(use_scope, block->statements(), iter, | 4879 BuildIteratorCloseForCompletion(use_scope, block->statements(), iter, proxy, |
4854 proxy); | 4880 type); |
4855 DCHECK(block->statements()->length() == 2); | 4881 DCHECK(block->statements()->length() == 2); |
4856 | 4882 |
4857 maybe_close = factory()->NewBlock(nullptr, 1, true, nopos); | 4883 maybe_close = factory()->NewBlock(nullptr, 1, true, nopos); |
4858 maybe_close->statements()->Add( | 4884 maybe_close->statements()->Add( |
4859 factory()->NewIfStatement(condition, block, | 4885 factory()->NewIfStatement(condition, block, |
4860 factory()->NewEmptyStatement(nopos), nopos), | 4886 factory()->NewEmptyStatement(nopos), nopos), |
4861 zone()); | 4887 zone()); |
4862 } | 4888 } |
4863 | 4889 |
4864 // try { #try_block } | 4890 // try { #try_block } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4903 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos); | 4929 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos); |
4904 } | 4930 } |
4905 | 4931 |
4906 target->statements()->Add(initialize_completion, zone()); | 4932 target->statements()->Add(initialize_completion, zone()); |
4907 target->statements()->Add(try_finally, zone()); | 4933 target->statements()->Add(try_finally, zone()); |
4908 } | 4934 } |
4909 | 4935 |
4910 void Parser::BuildIteratorCloseForCompletion(Scope* scope, | 4936 void Parser::BuildIteratorCloseForCompletion(Scope* scope, |
4911 ZoneList<Statement*>* statements, | 4937 ZoneList<Statement*>* statements, |
4912 Variable* iterator, | 4938 Variable* iterator, |
4913 Expression* completion) { | 4939 Expression* completion, |
| 4940 IteratorType type) { |
4914 // | 4941 // |
4915 // This function adds two statements to [statements], corresponding to the | 4942 // This function adds two statements to [statements], corresponding to the |
4916 // following code: | 4943 // following code: |
4917 // | 4944 // |
4918 // let iteratorReturn = iterator.return; | 4945 // let iteratorReturn = iterator.return; |
4919 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { | 4946 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { |
4920 // if (completion === kThrowCompletion) { | 4947 // if (completion === kThrowCompletion) { |
4921 // if (!IS_CALLABLE(iteratorReturn)) { | 4948 // if (!IS_CALLABLE(iteratorReturn)) { |
4922 // throw MakeTypeError(kReturnMethodNotCallable); | 4949 // throw MakeTypeError(kReturnMethodNotCallable); |
4923 // } | 4950 // } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4961 // try { %_Call(iteratorReturn, iterator) } catch (_) { } | 4988 // try { %_Call(iteratorReturn, iterator) } catch (_) { } |
4962 Statement* try_call_return; | 4989 Statement* try_call_return; |
4963 { | 4990 { |
4964 auto args = new (zone()) ZoneList<Expression*>(2, zone()); | 4991 auto args = new (zone()) ZoneList<Expression*>(2, zone()); |
4965 args->Add(factory()->NewVariableProxy(var_return), zone()); | 4992 args->Add(factory()->NewVariableProxy(var_return), zone()); |
4966 args->Add(factory()->NewVariableProxy(iterator), zone()); | 4993 args->Add(factory()->NewVariableProxy(iterator), zone()); |
4967 | 4994 |
4968 Expression* call = | 4995 Expression* call = |
4969 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 4996 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
4970 | 4997 |
| 4998 if (type == IteratorType::kAsync) { |
| 4999 call = RewriteAwaitExpression(call, nopos); |
| 5000 } |
| 5001 |
4971 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); | 5002 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); |
4972 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos), | 5003 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos), |
4973 zone()); | 5004 zone()); |
4974 | 5005 |
4975 Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos); | 5006 Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos); |
4976 | 5007 |
4977 Scope* catch_scope = NewScopeWithParent(scope, CATCH_SCOPE); | 5008 Scope* catch_scope = NewScopeWithParent(scope, CATCH_SCOPE); |
4978 Variable* catch_variable = | 5009 Variable* catch_variable = |
4979 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR); | 5010 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR); |
4980 catch_scope->set_is_hidden(); | 5011 catch_scope->set_is_hidden(); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5060 maybe_call_return = factory()->NewIfStatement( | 5091 maybe_call_return = factory()->NewIfStatement( |
5061 condition, factory()->NewEmptyStatement(nopos), call_return_carefully, | 5092 condition, factory()->NewEmptyStatement(nopos), call_return_carefully, |
5062 nopos); | 5093 nopos); |
5063 } | 5094 } |
5064 | 5095 |
5065 statements->Add(get_return, zone()); | 5096 statements->Add(get_return, zone()); |
5066 statements->Add(maybe_call_return, zone()); | 5097 statements->Add(maybe_call_return, zone()); |
5067 } | 5098 } |
5068 | 5099 |
5069 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop, | 5100 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop, |
5070 Variable* var_completion, int pos) { | 5101 Variable* var_completion, |
| 5102 IteratorType type, int pos) { |
5071 // | 5103 // |
5072 // This function replaces the loop with the following wrapping: | 5104 // This function replaces the loop with the following wrapping: |
5073 // | 5105 // |
5074 // completion = kNormalCompletion; | 5106 // completion = kNormalCompletion; |
5075 // try { | 5107 // try { |
5076 // try { | 5108 // try { |
5077 // #loop; | 5109 // #loop; |
5078 // } catch(e) { | 5110 // } catch(e) { |
5079 // if (completion === kAbruptCompletion) completion = kThrowCompletion; | 5111 // if (completion === kAbruptCompletion) completion = kThrowCompletion; |
5080 // %ReThrow(e); | 5112 // %ReThrow(e); |
(...skipping 23 matching lines...) Expand all Loading... |
5104 { | 5136 { |
5105 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); | 5137 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); |
5106 try_block->statements()->Add(loop, zone()); | 5138 try_block->statements()->Add(loop, zone()); |
5107 | 5139 |
5108 // The scope in which the parser creates this loop. | 5140 // The scope in which the parser creates this loop. |
5109 Scope* loop_scope = scope()->outer_scope(); | 5141 Scope* loop_scope = scope()->outer_scope(); |
5110 DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE); | 5142 DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE); |
5111 DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE); | 5143 DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE); |
5112 | 5144 |
5113 FinalizeIteratorUse(loop_scope, var_completion, closing_condition, | 5145 FinalizeIteratorUse(loop_scope, var_completion, closing_condition, |
5114 loop->iterator(), try_block, final_loop); | 5146 loop->iterator(), try_block, final_loop, type); |
5115 } | 5147 } |
5116 | 5148 |
5117 return final_loop; | 5149 return final_loop; |
5118 } | 5150 } |
5119 | 5151 |
5120 #undef CHECK_OK | 5152 #undef CHECK_OK |
5121 #undef CHECK_OK_VOID | 5153 #undef CHECK_OK_VOID |
5122 #undef CHECK_FAILED | 5154 #undef CHECK_FAILED |
5123 | 5155 |
5124 } // namespace internal | 5156 } // namespace internal |
5125 } // namespace v8 | 5157 } // namespace v8 |
OLD | NEW |