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_spread(FLAG_harmony_object_spread); | 555 set_allow_harmony_object_spread(FLAG_harmony_object_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(zone(), info->hash_seed())); | 563 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); |
563 info->set_ast_value_factory_owned(); | 564 info->set_ast_value_factory_owned(); |
564 ast_value_factory_ = info->ast_value_factory(); | 565 ast_value_factory_ = info->ast_value_factory(); |
565 ast_node_factory_.set_ast_value_factory(ast_value_factory_); | 566 ast_node_factory_.set_ast_value_factory(ast_value_factory_); |
(...skipping 1194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1760 try_block, catch_info.scope, catch_info.variable, catch_block, pos); | 1761 try_block, catch_info.scope, catch_info.variable, catch_block, pos); |
1761 } else { | 1762 } else { |
1762 DCHECK_NOT_NULL(finally_block); | 1763 DCHECK_NOT_NULL(finally_block); |
1763 return factory()->NewTryFinallyStatement(try_block, finally_block, pos); | 1764 return factory()->NewTryFinallyStatement(try_block, finally_block, pos); |
1764 } | 1765 } |
1765 } | 1766 } |
1766 | 1767 |
1767 // !%_IsJSReceiver(result = iterator.next()) && | 1768 // !%_IsJSReceiver(result = iterator.next()) && |
1768 // %ThrowIteratorResultNotAnObject(result) | 1769 // %ThrowIteratorResultNotAnObject(result) |
1769 Expression* Parser::BuildIteratorNextResult(Expression* iterator, | 1770 Expression* Parser::BuildIteratorNextResult(Expression* iterator, |
1770 Variable* result, int pos) { | 1771 Variable* result, IteratorType type, |
| 1772 int pos) { |
1771 Expression* next_literal = factory()->NewStringLiteral( | 1773 Expression* next_literal = factory()->NewStringLiteral( |
1772 ast_value_factory()->next_string(), kNoSourcePosition); | 1774 ast_value_factory()->next_string(), kNoSourcePosition); |
1773 Expression* next_property = | 1775 Expression* next_property = |
1774 factory()->NewProperty(iterator, next_literal, kNoSourcePosition); | 1776 factory()->NewProperty(iterator, next_literal, kNoSourcePosition); |
1775 ZoneList<Expression*>* next_arguments = | 1777 ZoneList<Expression*>* next_arguments = |
1776 new (zone()) ZoneList<Expression*>(0, zone()); | 1778 new (zone()) ZoneList<Expression*>(0, zone()); |
1777 Expression* next_call = | 1779 Expression* next_call = |
1778 factory()->NewCall(next_property, next_arguments, pos); | 1780 factory()->NewCall(next_property, next_arguments, pos); |
| 1781 if (type == IteratorType::kAsync) { |
| 1782 next_call = RewriteAwaitExpression(next_call, pos); |
| 1783 } |
1779 Expression* result_proxy = factory()->NewVariableProxy(result); | 1784 Expression* result_proxy = factory()->NewVariableProxy(result); |
1780 Expression* left = | 1785 Expression* left = |
1781 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos); | 1786 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos); |
1782 | 1787 |
1783 // %_IsJSReceiver(...) | 1788 // %_IsJSReceiver(...) |
1784 ZoneList<Expression*>* is_spec_object_args = | 1789 ZoneList<Expression*>* is_spec_object_args = |
1785 new (zone()) ZoneList<Expression*>(1, zone()); | 1790 new (zone()) ZoneList<Expression*>(1, zone()); |
1786 is_spec_object_args->Add(left, zone()); | 1791 is_spec_object_args->Add(left, zone()); |
1787 Expression* is_spec_object_call = factory()->NewCallRuntime( | 1792 Expression* is_spec_object_call = factory()->NewCallRuntime( |
1788 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos); | 1793 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos); |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1989 Token::ASSIGN, factory()->NewVariableProxy(iterator), | 1994 Token::ASSIGN, factory()->NewVariableProxy(iterator), |
1990 factory()->NewGetIterator(iterable, iterable->position()), | 1995 factory()->NewGetIterator(iterable, iterable->position()), |
1991 iterable->position()); | 1996 iterable->position()); |
1992 } | 1997 } |
1993 | 1998 |
1994 // !%_IsJSReceiver(result = iterator.next()) && | 1999 // !%_IsJSReceiver(result = iterator.next()) && |
1995 // %ThrowIteratorResultNotAnObject(result) | 2000 // %ThrowIteratorResultNotAnObject(result) |
1996 Expression* next_result; | 2001 Expression* next_result; |
1997 { | 2002 { |
1998 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2003 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
1999 next_result = | 2004 next_result = BuildIteratorNextResult( |
2000 BuildIteratorNextResult(iterator_proxy, result, next_result_pos); | 2005 iterator_proxy, result, IteratorType::kNormal, next_result_pos); |
2001 } | 2006 } |
2002 | 2007 |
2003 // result.done | 2008 // result.done |
| 2009 Expression* result_done; |
| 2010 { |
| 2011 Expression* done_literal = factory()->NewStringLiteral( |
| 2012 ast_value_factory()->done_string(), kNoSourcePosition); |
| 2013 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2014 result_done = |
| 2015 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition); |
| 2016 } |
| 2017 |
| 2018 // result.value |
| 2019 Expression* result_value; |
| 2020 { |
| 2021 Expression* value_literal = |
| 2022 factory()->NewStringLiteral(avfactory->value_string(), nopos); |
| 2023 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2024 result_value = factory()->NewProperty(result_proxy, value_literal, nopos); |
| 2025 } |
| 2026 |
| 2027 // {{completion = kAbruptCompletion;}} |
| 2028 Statement* set_completion_abrupt; |
| 2029 if (finalize) { |
| 2030 Expression* proxy = factory()->NewVariableProxy(completion); |
| 2031 Expression* assignment = factory()->NewAssignment( |
| 2032 Token::ASSIGN, proxy, |
| 2033 factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos); |
| 2034 |
| 2035 Block* block = factory()->NewBlock(nullptr, 1, true, nopos); |
| 2036 block->statements()->Add( |
| 2037 factory()->NewExpressionStatement(assignment, nopos), zone()); |
| 2038 set_completion_abrupt = block; |
| 2039 } |
| 2040 |
| 2041 // do { let tmp = #result_value; #set_completion_abrupt; tmp } |
| 2042 // Expression* result_value (gets overwritten) |
| 2043 if (finalize) { |
| 2044 Variable* var_tmp = NewTemporary(avfactory->empty_string()); |
| 2045 Expression* tmp = factory()->NewVariableProxy(var_tmp); |
| 2046 Expression* assignment = |
| 2047 factory()->NewAssignment(Token::ASSIGN, tmp, result_value, nopos); |
| 2048 |
| 2049 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); |
| 2050 block->statements()->Add( |
| 2051 factory()->NewExpressionStatement(assignment, nopos), zone()); |
| 2052 block->statements()->Add(set_completion_abrupt, zone()); |
| 2053 |
| 2054 result_value = factory()->NewDoExpression(block, var_tmp, nopos); |
| 2055 } |
| 2056 |
| 2057 // each = #result_value; |
| 2058 Expression* assign_each; |
| 2059 { |
| 2060 assign_each = |
| 2061 factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos); |
| 2062 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { |
| 2063 assign_each = PatternRewriter::RewriteDestructuringAssignment( |
| 2064 this, assign_each->AsAssignment(), scope()); |
| 2065 } |
| 2066 } |
| 2067 |
| 2068 // {{completion = kNormalCompletion;}} |
| 2069 Statement* set_completion_normal; |
| 2070 if (finalize) { |
| 2071 Expression* proxy = factory()->NewVariableProxy(completion); |
| 2072 Expression* assignment = factory()->NewAssignment( |
| 2073 Token::ASSIGN, proxy, |
| 2074 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); |
| 2075 |
| 2076 Block* block = factory()->NewBlock(nullptr, 1, true, nopos); |
| 2077 block->statements()->Add( |
| 2078 factory()->NewExpressionStatement(assignment, nopos), zone()); |
| 2079 set_completion_normal = block; |
| 2080 } |
| 2081 |
| 2082 // { #loop-body; #set_completion_normal } |
| 2083 // Statement* body (gets overwritten) |
| 2084 if (finalize) { |
| 2085 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); |
| 2086 block->statements()->Add(body, zone()); |
| 2087 block->statements()->Add(set_completion_normal, zone()); |
| 2088 body = block; |
| 2089 } |
| 2090 |
| 2091 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, |
| 2092 assign_each); |
| 2093 return finalize ? FinalizeForOfStatement(for_of, completion, |
| 2094 IteratorType::kNormal, nopos) |
| 2095 : for_of; |
| 2096 } |
| 2097 |
| 2098 Statement* Parser::InitializeForAwaitOfStatement(ForEachStatement* stmt, |
| 2099 Expression* each, |
| 2100 Expression* iterable, |
| 2101 Statement* body, bool finalize, |
| 2102 int next_result_pos) { |
| 2103 DCHECK(stmt->IsForOfStatement()); |
| 2104 ForOfStatement* for_of = stmt->AsForOfStatement(); |
| 2105 |
| 2106 // Create the auxiliary expressions needed for iterating over the iterable, |
| 2107 // and initialize the given ForOfStatement with them. |
| 2108 // If finalize is true, also instrument the loop with code that performs the |
| 2109 // proper ES6 iterator finalization. In that case, the result is not |
| 2110 // immediately a ForOfStatement. |
| 2111 |
| 2112 const int nopos = kNoSourcePosition; |
| 2113 auto avfactory = ast_value_factory(); |
| 2114 |
| 2115 Variable* iterator = NewTemporary(ast_value_factory()->dot_iterator_string()); |
| 2116 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); |
| 2117 Variable* completion = NewTemporary(avfactory->empty_string()); |
| 2118 |
| 2119 // iterator = GetIterator(iterable, async) |
| 2120 Expression* assign_iterator; |
| 2121 { |
| 2122 assign_iterator = factory()->NewAssignment( |
| 2123 Token::ASSIGN, factory()->NewVariableProxy(iterator), |
| 2124 factory()->NewGetIterator(iterable, GetIterator::kAsync, |
| 2125 iterable->position()), |
| 2126 iterable->position()); |
| 2127 } |
| 2128 |
| 2129 Expression* next_result; |
| 2130 { |
| 2131 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 2132 next_result = BuildIteratorNextResult( |
| 2133 iterator_proxy, result, IteratorType::kAsync, next_result_pos); |
| 2134 } |
| 2135 |
| 2136 // result.done |
2004 Expression* result_done; | 2137 Expression* result_done; |
2005 { | 2138 { |
2006 Expression* done_literal = factory()->NewStringLiteral( | 2139 Expression* done_literal = factory()->NewStringLiteral( |
2007 ast_value_factory()->done_string(), kNoSourcePosition); | 2140 ast_value_factory()->done_string(), kNoSourcePosition); |
2008 Expression* result_proxy = factory()->NewVariableProxy(result); | 2141 Expression* result_proxy = factory()->NewVariableProxy(result); |
2009 result_done = | 2142 result_done = |
2010 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition); | 2143 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition); |
2011 } | 2144 } |
2012 | 2145 |
2013 // result.value | 2146 // result.value |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2078 // Statement* body (gets overwritten) | 2211 // Statement* body (gets overwritten) |
2079 if (finalize) { | 2212 if (finalize) { |
2080 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); | 2213 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); |
2081 block->statements()->Add(body, zone()); | 2214 block->statements()->Add(body, zone()); |
2082 block->statements()->Add(set_completion_normal, zone()); | 2215 block->statements()->Add(set_completion_normal, zone()); |
2083 body = block; | 2216 body = block; |
2084 } | 2217 } |
2085 | 2218 |
2086 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, | 2219 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, |
2087 assign_each); | 2220 assign_each); |
2088 return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of; | 2221 return finalize ? FinalizeForOfStatement(for_of, completion, |
| 2222 IteratorType::kAsync, nopos) |
| 2223 : for_of; |
2089 } | 2224 } |
2090 | 2225 |
2091 Statement* Parser::DesugarLexicalBindingsInForStatement( | 2226 Statement* Parser::DesugarLexicalBindingsInForStatement( |
2092 ForStatement* loop, Statement* init, Expression* cond, Statement* next, | 2227 ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
2093 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) { | 2228 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) { |
2094 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are | 2229 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are |
2095 // copied into a new environment. Moreover, the "next" statement must be | 2230 // copied into a new environment. Moreover, the "next" statement must be |
2096 // evaluated not in the environment of the just completed iteration but in | 2231 // evaluated not in the environment of the just completed iteration but in |
2097 // that of the upcoming one. We achieve this with the following desugaring. | 2232 // that of the upcoming one. We achieve this with the following desugaring. |
2098 // Extra care is needed to preserve the completion value of the original loop. | 2233 // 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... |
2743 reusable_preparser_ = new PreParser( | 2878 reusable_preparser_ = new PreParser( |
2744 zone(), &scanner_, stack_limit_, ast_value_factory(), | 2879 zone(), &scanner_, stack_limit_, ast_value_factory(), |
2745 &pending_error_handler_, runtime_call_stats_, parsing_on_main_thread_); | 2880 &pending_error_handler_, runtime_call_stats_, parsing_on_main_thread_); |
2746 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); | 2881 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); |
2747 SET_ALLOW(natives); | 2882 SET_ALLOW(natives); |
2748 SET_ALLOW(harmony_do_expressions); | 2883 SET_ALLOW(harmony_do_expressions); |
2749 SET_ALLOW(harmony_function_sent); | 2884 SET_ALLOW(harmony_function_sent); |
2750 SET_ALLOW(harmony_trailing_commas); | 2885 SET_ALLOW(harmony_trailing_commas); |
2751 SET_ALLOW(harmony_class_fields); | 2886 SET_ALLOW(harmony_class_fields); |
2752 SET_ALLOW(harmony_object_spread); | 2887 SET_ALLOW(harmony_object_spread); |
| 2888 SET_ALLOW(harmony_async_iteration); |
2753 #undef SET_ALLOW | 2889 #undef SET_ALLOW |
2754 } | 2890 } |
2755 // Aborting inner function preparsing would leave scopes in an inconsistent | 2891 // Aborting inner function preparsing would leave scopes in an inconsistent |
2756 // state; we don't parse inner functions in the abortable mode anyway. | 2892 // state; we don't parse inner functions in the abortable mode anyway. |
2757 DCHECK(!is_inner_function || !may_abort); | 2893 DCHECK(!is_inner_function || !may_abort); |
2758 | 2894 |
2759 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( | 2895 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( |
2760 kind, function_scope, parsing_module_, is_inner_function, may_abort, | 2896 kind, function_scope, parsing_module_, is_inner_function, may_abort, |
2761 use_counts_); | 2897 use_counts_); |
2762 | 2898 |
(...skipping 1150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3913 // The operand needs to be evaluated on a separate statement in order to get | 4049 // The operand needs to be evaluated on a separate statement in order to get |
3914 // a break location, and the .promise needs to be read earlier so that it | 4050 // a break location, and the .promise needs to be read earlier so that it |
3915 // doesn't insert a false location. | 4051 // doesn't insert a false location. |
3916 // TODO(littledan): investigate why this ordering is needed in more detail. | 4052 // TODO(littledan): investigate why this ordering is needed in more detail. |
3917 Variable* generator_object_variable = | 4053 Variable* generator_object_variable = |
3918 function_state_->generator_object_variable(); | 4054 function_state_->generator_object_variable(); |
3919 DCHECK_NOT_NULL(generator_object_variable); | 4055 DCHECK_NOT_NULL(generator_object_variable); |
3920 | 4056 |
3921 const int nopos = kNoSourcePosition; | 4057 const int nopos = kNoSourcePosition; |
3922 | 4058 |
| 4059 if (is_async_generator()) { |
| 4060 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); |
| 4061 Expression* generator_object = |
| 4062 factory()->NewVariableProxy(generator_object_variable); |
| 4063 args->Add(generator_object, zone()); |
| 4064 args->Add(value, zone()); |
| 4065 |
| 4066 Expression* await = factory()->NewCallRuntime( |
| 4067 Context::ASYNC_GENERATOR_AWAIT_CAUGHT, args, nopos); |
| 4068 |
| 4069 return factory()->NewYield(generator_object, await, nopos, |
| 4070 Yield::kOnExceptionRethrow, Yield::kAwait); |
| 4071 } |
| 4072 |
3923 Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos); | 4073 Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos); |
3924 | 4074 |
3925 Variable* promise = PromiseVariable(); | 4075 Variable* promise = PromiseVariable(); |
3926 | 4076 |
3927 // Wrap value evaluation to provide a break location. | 4077 // Wrap value evaluation to provide a break location. |
3928 Variable* temp_var = NewTemporary(ast_value_factory()->empty_string()); | 4078 Variable* temp_var = NewTemporary(ast_value_factory()->empty_string()); |
3929 Expression* value_assignment = factory()->NewAssignment( | 4079 Expression* value_assignment = factory()->NewAssignment( |
3930 Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos); | 4080 Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos); |
3931 do_block->statements()->Add( | 4081 do_block->statements()->Add( |
3932 factory()->NewExpressionStatement(value_assignment, value->position()), | 4082 factory()->NewExpressionStatement(value_assignment, value->position()), |
(...skipping 15 matching lines...) Expand all Loading... |
3948 async_function_await_args, nopos); | 4098 async_function_await_args, nopos); |
3949 do_block->statements()->Add( | 4099 do_block->statements()->Add( |
3950 factory()->NewExpressionStatement(async_function_await, await_pos), | 4100 factory()->NewExpressionStatement(async_function_await, await_pos), |
3951 zone()); | 4101 zone()); |
3952 | 4102 |
3953 // Wrap await to provide a break location between value evaluation and yield. | 4103 // Wrap await to provide a break location between value evaluation and yield. |
3954 Expression* do_expr = factory()->NewDoExpression(do_block, promise, nopos); | 4104 Expression* do_expr = factory()->NewDoExpression(do_block, promise, nopos); |
3955 | 4105 |
3956 generator_object = factory()->NewVariableProxy(generator_object_variable); | 4106 generator_object = factory()->NewVariableProxy(generator_object_variable); |
3957 return factory()->NewYield(generator_object, do_expr, nopos, | 4107 return factory()->NewYield(generator_object, do_expr, nopos, |
3958 Yield::kOnExceptionRethrow); | 4108 Yield::kOnExceptionRethrow, Yield::kAwait); |
3959 } | 4109 } |
3960 | 4110 |
3961 class NonPatternRewriter : public AstExpressionRewriter { | 4111 class NonPatternRewriter : public AstExpressionRewriter { |
3962 public: | 4112 public: |
3963 NonPatternRewriter(uintptr_t stack_limit, Parser* parser) | 4113 NonPatternRewriter(uintptr_t stack_limit, Parser* parser) |
3964 : AstExpressionRewriter(stack_limit), parser_(parser) {} | 4114 : AstExpressionRewriter(stack_limit), parser_(parser) {} |
3965 ~NonPatternRewriter() override {} | 4115 ~NonPatternRewriter() override {} |
3966 | 4116 |
3967 private: | 4117 private: |
3968 bool RewriteExpression(Expression* expr) override { | 4118 bool RewriteExpression(Expression* expr) override { |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4306 // IteratorClose(iterator, input, output) expands to the following: | 4456 // IteratorClose(iterator, input, output) expands to the following: |
4307 // | 4457 // |
4308 // let iteratorReturn = iterator.return; | 4458 // let iteratorReturn = iterator.return; |
4309 // if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input; | 4459 // if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input; |
4310 // output = %_Call(iteratorReturn, iterator, input); | 4460 // output = %_Call(iteratorReturn, iterator, input); |
4311 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 4461 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); |
4312 | 4462 |
4313 Expression* Parser::RewriteYieldStar(Expression* generator, | 4463 Expression* Parser::RewriteYieldStar(Expression* generator, |
4314 Expression* iterable, int pos) { | 4464 Expression* iterable, int pos) { |
4315 const int nopos = kNoSourcePosition; | 4465 const int nopos = kNoSourcePosition; |
| 4466 IteratorType type = |
| 4467 is_async_generator() ? IteratorType::kAsync : IteratorType::kNormal; |
4316 | 4468 |
4317 // Forward definition for break/continue statements. | 4469 // Forward definition for break/continue statements. |
4318 WhileStatement* loop = factory()->NewWhileStatement(nullptr, nopos); | 4470 WhileStatement* loop = factory()->NewWhileStatement(nullptr, nopos); |
4319 | 4471 |
4320 // let input = undefined; | 4472 // let input = undefined; |
4321 Variable* var_input = NewTemporary(ast_value_factory()->empty_string()); | 4473 Variable* var_input = NewTemporary(ast_value_factory()->empty_string()); |
4322 Statement* initialize_input; | 4474 Statement* initialize_input; |
4323 { | 4475 { |
4324 Expression* input_proxy = factory()->NewVariableProxy(var_input); | 4476 Expression* input_proxy = factory()->NewVariableProxy(var_input); |
4325 Expression* assignment = | 4477 Expression* assignment = |
(...skipping 22 matching lines...) Expand all Loading... |
4348 Expression* assignment = | 4500 Expression* assignment = |
4349 factory()->NewAssignment(Token::ASSIGN, output_proxy, | 4501 factory()->NewAssignment(Token::ASSIGN, output_proxy, |
4350 factory()->NewUndefinedLiteral(nopos), nopos); | 4502 factory()->NewUndefinedLiteral(nopos), nopos); |
4351 initialize_output = factory()->NewExpressionStatement(assignment, nopos); | 4503 initialize_output = factory()->NewExpressionStatement(assignment, nopos); |
4352 } | 4504 } |
4353 | 4505 |
4354 // let iterator = GetIterator(iterable); | 4506 // let iterator = GetIterator(iterable); |
4355 Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string()); | 4507 Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string()); |
4356 Statement* get_iterator; | 4508 Statement* get_iterator; |
4357 { | 4509 { |
4358 Expression* iterator = factory()->NewGetIterator(iterable, nopos); | 4510 GetIterator::Hint hint = GetIterator::kNormal; |
| 4511 if (type == IteratorType::kAsync) { |
| 4512 hint = GetIterator::kAsync; |
| 4513 } |
| 4514 Expression* iterator = factory()->NewGetIterator(iterable, hint, nopos); |
4359 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); | 4515 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); |
4360 Expression* assignment = factory()->NewAssignment( | 4516 Expression* assignment = factory()->NewAssignment( |
4361 Token::ASSIGN, iterator_proxy, iterator, nopos); | 4517 Token::ASSIGN, iterator_proxy, iterator, nopos); |
4362 get_iterator = factory()->NewExpressionStatement(assignment, nopos); | 4518 get_iterator = factory()->NewExpressionStatement(assignment, nopos); |
4363 } | 4519 } |
4364 | 4520 |
4365 // output = iterator.next(input); | 4521 // output = iterator.next(input); |
4366 Statement* call_next; | 4522 Statement* call_next; |
4367 { | 4523 { |
4368 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); | 4524 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); |
4369 Expression* literal = | 4525 Expression* literal = |
4370 factory()->NewStringLiteral(ast_value_factory()->next_string(), nopos); | 4526 factory()->NewStringLiteral(ast_value_factory()->next_string(), nopos); |
4371 Expression* next_property = | 4527 Expression* next_property = |
4372 factory()->NewProperty(iterator_proxy, literal, nopos); | 4528 factory()->NewProperty(iterator_proxy, literal, nopos); |
4373 Expression* input_proxy = factory()->NewVariableProxy(var_input); | 4529 Expression* input_proxy = factory()->NewVariableProxy(var_input); |
4374 auto args = new (zone()) ZoneList<Expression*>(1, zone()); | 4530 auto args = new (zone()) ZoneList<Expression*>(1, zone()); |
4375 args->Add(input_proxy, zone()); | 4531 args->Add(input_proxy, zone()); |
4376 Expression* call = factory()->NewCall(next_property, args, nopos); | 4532 Expression* call = factory()->NewCall(next_property, args, nopos); |
| 4533 if (type == IteratorType::kAsync) { |
| 4534 call = RewriteAwaitExpression(call, nopos); |
| 4535 } |
4377 Expression* output_proxy = factory()->NewVariableProxy(var_output); | 4536 Expression* output_proxy = factory()->NewVariableProxy(var_output); |
4378 Expression* assignment = | 4537 Expression* assignment = |
4379 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); | 4538 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); |
4380 call_next = factory()->NewExpressionStatement(assignment, nopos); | 4539 call_next = factory()->NewExpressionStatement(assignment, nopos); |
4381 } | 4540 } |
4382 | 4541 |
4383 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 4542 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); |
4384 Statement* validate_next_output; | 4543 Statement* validate_next_output; |
4385 { | 4544 { |
4386 Expression* is_receiver_call; | 4545 Expression* is_receiver_call; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4430 Token::EQ, factory()->NewVariableProxy(var_throw), | 4589 Token::EQ, factory()->NewVariableProxy(var_throw), |
4431 factory()->NewNullLiteral(nopos), nopos); | 4590 factory()->NewNullLiteral(nopos), nopos); |
4432 Expression* call = | 4591 Expression* call = |
4433 NewThrowTypeError(MessageTemplate::kThrowMethodMissing, | 4592 NewThrowTypeError(MessageTemplate::kThrowMethodMissing, |
4434 ast_value_factory()->empty_string(), nopos); | 4593 ast_value_factory()->empty_string(), nopos); |
4435 Statement* throw_call = factory()->NewExpressionStatement(call, nopos); | 4594 Statement* throw_call = factory()->NewExpressionStatement(call, nopos); |
4436 | 4595 |
4437 Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos); | 4596 Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos); |
4438 BuildIteratorCloseForCompletion( | 4597 BuildIteratorCloseForCompletion( |
4439 scope(), then->statements(), var_iterator, | 4598 scope(), then->statements(), var_iterator, |
4440 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos)); | 4599 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), type); |
4441 then->statements()->Add(throw_call, zone()); | 4600 then->statements()->Add(throw_call, zone()); |
4442 check_throw = factory()->NewIfStatement( | 4601 check_throw = factory()->NewIfStatement( |
4443 condition, then, factory()->NewEmptyStatement(nopos), nopos); | 4602 condition, then, factory()->NewEmptyStatement(nopos), nopos); |
4444 } | 4603 } |
4445 | 4604 |
4446 // output = %_Call(iteratorThrow, iterator, input); | 4605 // output = %_Call(iteratorThrow, iterator, input); |
4447 Statement* call_throw; | 4606 Statement* call_throw; |
4448 { | 4607 { |
4449 auto args = new (zone()) ZoneList<Expression*>(3, zone()); | 4608 auto args = new (zone()) ZoneList<Expression*>(3, zone()); |
4450 args->Add(factory()->NewVariableProxy(var_throw), zone()); | 4609 args->Add(factory()->NewVariableProxy(var_throw), zone()); |
4451 args->Add(factory()->NewVariableProxy(var_iterator), zone()); | 4610 args->Add(factory()->NewVariableProxy(var_iterator), zone()); |
4452 args->Add(factory()->NewVariableProxy(var_input), zone()); | 4611 args->Add(factory()->NewVariableProxy(var_input), zone()); |
4453 Expression* call = | 4612 Expression* call = |
4454 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 4613 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
| 4614 if (type == IteratorType::kAsync) { |
| 4615 call = RewriteAwaitExpression(call, nopos); |
| 4616 } |
4455 Expression* assignment = factory()->NewAssignment( | 4617 Expression* assignment = factory()->NewAssignment( |
4456 Token::ASSIGN, factory()->NewVariableProxy(var_output), call, nopos); | 4618 Token::ASSIGN, factory()->NewVariableProxy(var_output), call, nopos); |
4457 call_throw = factory()->NewExpressionStatement(assignment, nopos); | 4619 call_throw = factory()->NewExpressionStatement(assignment, nopos); |
4458 } | 4620 } |
4459 | 4621 |
4460 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 4622 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); |
4461 Statement* validate_throw_output; | 4623 Statement* validate_throw_output; |
4462 { | 4624 { |
4463 Expression* is_receiver_call; | 4625 Expression* is_receiver_call; |
4464 { | 4626 { |
(...skipping 18 matching lines...) Expand all Loading... |
4483 } | 4645 } |
4484 | 4646 |
4485 // if (output.done) break; | 4647 // if (output.done) break; |
4486 Statement* if_done; | 4648 Statement* if_done; |
4487 { | 4649 { |
4488 Expression* output_proxy = factory()->NewVariableProxy(var_output); | 4650 Expression* output_proxy = factory()->NewVariableProxy(var_output); |
4489 Expression* literal = | 4651 Expression* literal = |
4490 factory()->NewStringLiteral(ast_value_factory()->done_string(), nopos); | 4652 factory()->NewStringLiteral(ast_value_factory()->done_string(), nopos); |
4491 Expression* property = factory()->NewProperty(output_proxy, literal, nopos); | 4653 Expression* property = factory()->NewProperty(output_proxy, literal, nopos); |
4492 BreakStatement* break_loop = factory()->NewBreakStatement(loop, nopos); | 4654 BreakStatement* break_loop = factory()->NewBreakStatement(loop, nopos); |
| 4655 |
4493 if_done = factory()->NewIfStatement( | 4656 if_done = factory()->NewIfStatement( |
4494 property, break_loop, factory()->NewEmptyStatement(nopos), nopos); | 4657 property, break_loop, factory()->NewEmptyStatement(nopos), nopos); |
4495 } | 4658 } |
4496 | 4659 |
4497 | 4660 |
4498 // mode = kReturn; | 4661 // mode = kReturn; |
4499 Statement* set_mode_return; | 4662 Statement* set_mode_return; |
4500 { | 4663 { |
4501 Expression* mode_proxy = factory()->NewVariableProxy(var_mode); | 4664 Expression* mode_proxy = factory()->NewVariableProxy(var_mode); |
4502 Expression* kreturn = | 4665 Expression* kreturn = |
4503 factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos); | 4666 factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos); |
4504 Expression* assignment = | 4667 Expression* assignment = |
4505 factory()->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos); | 4668 factory()->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos); |
4506 set_mode_return = factory()->NewExpressionStatement(assignment, nopos); | 4669 set_mode_return = factory()->NewExpressionStatement(assignment, nopos); |
4507 } | 4670 } |
4508 | 4671 |
4509 // Yield(output); | 4672 // Yield(output); |
4510 Statement* yield_output; | 4673 Statement* yield_output; |
4511 { | 4674 { |
4512 Expression* output_proxy = factory()->NewVariableProxy(var_output); | 4675 Expression* output_proxy = factory()->NewVariableProxy(var_output); |
4513 Yield* yield = factory()->NewYield(generator, output_proxy, nopos, | 4676 Yield* yield = |
4514 Yield::kOnExceptionThrow); | 4677 factory()->NewYield(generator, output_proxy, nopos, |
| 4678 Yield::kOnExceptionThrow, Yield::kDelegate); |
4515 yield_output = factory()->NewExpressionStatement(yield, nopos); | 4679 yield_output = factory()->NewExpressionStatement(yield, nopos); |
4516 } | 4680 } |
4517 | 4681 |
4518 // mode = kNext; | 4682 // mode = kNext; |
4519 Statement* set_mode_next; | 4683 Statement* set_mode_next; |
4520 { | 4684 { |
4521 Expression* mode_proxy = factory()->NewVariableProxy(var_mode); | 4685 Expression* mode_proxy = factory()->NewVariableProxy(var_mode); |
4522 Expression* knext = | 4686 Expression* knext = |
4523 factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos); | 4687 factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos); |
4524 Expression* assignment = | 4688 Expression* assignment = |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4617 | 4781 |
4618 // switch (mode) { ... } | 4782 // switch (mode) { ... } |
4619 SwitchStatement* switch_mode = factory()->NewSwitchStatement(nullptr, nopos); | 4783 SwitchStatement* switch_mode = factory()->NewSwitchStatement(nullptr, nopos); |
4620 { | 4784 { |
4621 auto case_next = new (zone()) ZoneList<Statement*>(3, zone()); | 4785 auto case_next = new (zone()) ZoneList<Statement*>(3, zone()); |
4622 case_next->Add(call_next, zone()); | 4786 case_next->Add(call_next, zone()); |
4623 case_next->Add(validate_next_output, zone()); | 4787 case_next->Add(validate_next_output, zone()); |
4624 case_next->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); | 4788 case_next->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); |
4625 | 4789 |
4626 auto case_return = new (zone()) ZoneList<Statement*>(5, zone()); | 4790 auto case_return = new (zone()) ZoneList<Statement*>(5, zone()); |
4627 BuildIteratorClose(case_return, var_iterator, var_input, var_output); | 4791 BuildIteratorClose(case_return, var_iterator, var_input, var_output, type); |
4628 case_return->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); | 4792 case_return->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); |
4629 | 4793 |
4630 auto case_throw = new (zone()) ZoneList<Statement*>(5, zone()); | 4794 auto case_throw = new (zone()) ZoneList<Statement*>(5, zone()); |
4631 case_throw->Add(get_throw, zone()); | 4795 case_throw->Add(get_throw, zone()); |
4632 case_throw->Add(check_throw, zone()); | 4796 case_throw->Add(check_throw, zone()); |
4633 case_throw->Add(call_throw, zone()); | 4797 case_throw->Add(call_throw, zone()); |
4634 case_throw->Add(validate_throw_output, zone()); | 4798 case_throw->Add(validate_throw_output, zone()); |
4635 case_throw->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); | 4799 case_throw->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); |
4636 | 4800 |
4637 auto cases = new (zone()) ZoneList<CaseClause*>(3, zone()); | 4801 auto cases = new (zone()) ZoneList<CaseClause*>(3, zone()); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4701 Statement* throw_call = factory()->NewExpressionStatement(error, pos); | 4865 Statement* throw_call = factory()->NewExpressionStatement(error, pos); |
4702 | 4866 |
4703 validate_var = factory()->NewIfStatement( | 4867 validate_var = factory()->NewIfStatement( |
4704 condition, factory()->NewEmptyStatement(nopos), throw_call, nopos); | 4868 condition, factory()->NewEmptyStatement(nopos), throw_call, nopos); |
4705 } | 4869 } |
4706 return validate_var; | 4870 return validate_var; |
4707 } | 4871 } |
4708 | 4872 |
4709 void Parser::BuildIteratorClose(ZoneList<Statement*>* statements, | 4873 void Parser::BuildIteratorClose(ZoneList<Statement*>* statements, |
4710 Variable* iterator, Variable* input, | 4874 Variable* iterator, Variable* input, |
4711 Variable* var_output) { | 4875 Variable* var_output, IteratorType type) { |
4712 // | 4876 // |
4713 // This function adds four statements to [statements], corresponding to the | 4877 // This function adds four statements to [statements], corresponding to the |
4714 // following code: | 4878 // following code: |
4715 // | 4879 // |
4716 // let iteratorReturn = iterator.return; | 4880 // let iteratorReturn = iterator.return; |
4717 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { | 4881 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { |
4718 // return {value: input, done: true}; | 4882 // return {value: input, done: true}; |
4719 // } | 4883 // } |
4720 // output = %_Call(iteratorReturn, iterator, input); | 4884 // output = %_Call(iteratorReturn, iterator, input); |
| 4885 // if (IteratorType == kAsync) { |
| 4886 // output = Await(output) |
| 4887 // } |
4721 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 4888 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); |
4722 // | 4889 |
| 4890 // output = Await(%_Call(iteratorReturn, iterator, input)); |
4723 | 4891 |
4724 const int nopos = kNoSourcePosition; | 4892 const int nopos = kNoSourcePosition; |
4725 | 4893 |
4726 // let iteratorReturn = iterator.return; | 4894 // let iteratorReturn = iterator.return; |
4727 Variable* var_return = var_output; // Reusing the output variable. | 4895 Variable* var_return = var_output; // Reusing the output variable. |
4728 Statement* get_return; | 4896 Statement* get_return; |
4729 { | 4897 { |
4730 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 4898 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
4731 Expression* literal = factory()->NewStringLiteral( | 4899 Expression* literal = factory()->NewStringLiteral( |
4732 ast_value_factory()->return_string(), nopos); | 4900 ast_value_factory()->return_string(), nopos); |
(...skipping 26 matching lines...) Expand all Loading... |
4759 // output = %_Call(iteratorReturn, iterator, input); | 4927 // output = %_Call(iteratorReturn, iterator, input); |
4760 Statement* call_return; | 4928 Statement* call_return; |
4761 { | 4929 { |
4762 auto args = new (zone()) ZoneList<Expression*>(3, zone()); | 4930 auto args = new (zone()) ZoneList<Expression*>(3, zone()); |
4763 args->Add(factory()->NewVariableProxy(var_return), zone()); | 4931 args->Add(factory()->NewVariableProxy(var_return), zone()); |
4764 args->Add(factory()->NewVariableProxy(iterator), zone()); | 4932 args->Add(factory()->NewVariableProxy(iterator), zone()); |
4765 args->Add(factory()->NewVariableProxy(input), zone()); | 4933 args->Add(factory()->NewVariableProxy(input), zone()); |
4766 | 4934 |
4767 Expression* call = | 4935 Expression* call = |
4768 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 4936 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
| 4937 if (type == IteratorType::kAsync) { |
| 4938 call = RewriteAwaitExpression(call, nopos); |
| 4939 } |
4769 Expression* output_proxy = factory()->NewVariableProxy(var_output); | 4940 Expression* output_proxy = factory()->NewVariableProxy(var_output); |
4770 Expression* assignment = | 4941 Expression* assignment = |
4771 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); | 4942 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); |
4772 call_return = factory()->NewExpressionStatement(assignment, nopos); | 4943 call_return = factory()->NewExpressionStatement(assignment, nopos); |
4773 } | 4944 } |
4774 | 4945 |
4775 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output); | 4946 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output); |
4776 Statement* validate_output; | 4947 Statement* validate_output; |
4777 { | 4948 { |
4778 Expression* is_receiver_call; | 4949 Expression* is_receiver_call; |
(...skipping 19 matching lines...) Expand all Loading... |
4798 } | 4969 } |
4799 | 4970 |
4800 statements->Add(get_return, zone()); | 4971 statements->Add(get_return, zone()); |
4801 statements->Add(check_return, zone()); | 4972 statements->Add(check_return, zone()); |
4802 statements->Add(call_return, zone()); | 4973 statements->Add(call_return, zone()); |
4803 statements->Add(validate_output, zone()); | 4974 statements->Add(validate_output, zone()); |
4804 } | 4975 } |
4805 | 4976 |
4806 void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion, | 4977 void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion, |
4807 Expression* condition, Variable* iter, | 4978 Expression* condition, Variable* iter, |
4808 Block* iterator_use, Block* target) { | 4979 Block* iterator_use, Block* target, |
| 4980 IteratorType type) { |
4809 // | 4981 // |
4810 // This function adds two statements to [target], corresponding to the | 4982 // This function adds two statements to [target], corresponding to the |
4811 // following code: | 4983 // following code: |
4812 // | 4984 // |
4813 // completion = kNormalCompletion; | 4985 // completion = kNormalCompletion; |
4814 // try { | 4986 // try { |
4815 // try { | 4987 // try { |
4816 // iterator_use | 4988 // iterator_use |
4817 // } catch(e) { | 4989 // } catch(e) { |
4818 // if (completion === kAbruptCompletion) completion = kThrowCompletion; | 4990 // if (completion === kAbruptCompletion) completion = kThrowCompletion; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4854 condition, statement, factory()->NewEmptyStatement(nopos), nopos); | 5026 condition, statement, factory()->NewEmptyStatement(nopos), nopos); |
4855 } | 5027 } |
4856 | 5028 |
4857 // if (condition) { | 5029 // if (condition) { |
4858 // #BuildIteratorCloseForCompletion(iter, completion) | 5030 // #BuildIteratorCloseForCompletion(iter, completion) |
4859 // } | 5031 // } |
4860 Block* maybe_close; | 5032 Block* maybe_close; |
4861 { | 5033 { |
4862 Block* block = factory()->NewBlock(nullptr, 2, true, nopos); | 5034 Block* block = factory()->NewBlock(nullptr, 2, true, nopos); |
4863 Expression* proxy = factory()->NewVariableProxy(completion); | 5035 Expression* proxy = factory()->NewVariableProxy(completion); |
4864 BuildIteratorCloseForCompletion(use_scope, block->statements(), iter, | 5036 BuildIteratorCloseForCompletion(use_scope, block->statements(), iter, proxy, |
4865 proxy); | 5037 type); |
4866 DCHECK(block->statements()->length() == 2); | 5038 DCHECK(block->statements()->length() == 2); |
4867 | 5039 |
4868 maybe_close = factory()->NewBlock(nullptr, 1, true, nopos); | 5040 maybe_close = factory()->NewBlock(nullptr, 1, true, nopos); |
4869 maybe_close->statements()->Add( | 5041 maybe_close->statements()->Add( |
4870 factory()->NewIfStatement(condition, block, | 5042 factory()->NewIfStatement(condition, block, |
4871 factory()->NewEmptyStatement(nopos), nopos), | 5043 factory()->NewEmptyStatement(nopos), nopos), |
4872 zone()); | 5044 zone()); |
4873 } | 5045 } |
4874 | 5046 |
4875 // try { #try_block } | 5047 // try { #try_block } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4915 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos); | 5087 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos); |
4916 } | 5088 } |
4917 | 5089 |
4918 target->statements()->Add(initialize_completion, zone()); | 5090 target->statements()->Add(initialize_completion, zone()); |
4919 target->statements()->Add(try_finally, zone()); | 5091 target->statements()->Add(try_finally, zone()); |
4920 } | 5092 } |
4921 | 5093 |
4922 void Parser::BuildIteratorCloseForCompletion(Scope* scope, | 5094 void Parser::BuildIteratorCloseForCompletion(Scope* scope, |
4923 ZoneList<Statement*>* statements, | 5095 ZoneList<Statement*>* statements, |
4924 Variable* iterator, | 5096 Variable* iterator, |
4925 Expression* completion) { | 5097 Expression* completion, |
| 5098 IteratorType type) { |
4926 // | 5099 // |
4927 // This function adds two statements to [statements], corresponding to the | 5100 // This function adds two statements to [statements], corresponding to the |
4928 // following code: | 5101 // following code: |
4929 // | 5102 // |
4930 // let iteratorReturn = iterator.return; | 5103 // let iteratorReturn = iterator.return; |
4931 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { | 5104 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { |
4932 // if (completion === kThrowCompletion) { | 5105 // if (completion === kThrowCompletion) { |
4933 // if (!IS_CALLABLE(iteratorReturn)) { | 5106 // if (!IS_CALLABLE(iteratorReturn)) { |
4934 // throw MakeTypeError(kReturnMethodNotCallable); | 5107 // throw MakeTypeError(kReturnMethodNotCallable); |
4935 // } | 5108 // } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4973 // try { %_Call(iteratorReturn, iterator) } catch (_) { } | 5146 // try { %_Call(iteratorReturn, iterator) } catch (_) { } |
4974 Statement* try_call_return; | 5147 Statement* try_call_return; |
4975 { | 5148 { |
4976 auto args = new (zone()) ZoneList<Expression*>(2, zone()); | 5149 auto args = new (zone()) ZoneList<Expression*>(2, zone()); |
4977 args->Add(factory()->NewVariableProxy(var_return), zone()); | 5150 args->Add(factory()->NewVariableProxy(var_return), zone()); |
4978 args->Add(factory()->NewVariableProxy(iterator), zone()); | 5151 args->Add(factory()->NewVariableProxy(iterator), zone()); |
4979 | 5152 |
4980 Expression* call = | 5153 Expression* call = |
4981 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 5154 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
4982 | 5155 |
| 5156 if (type == IteratorType::kAsync) { |
| 5157 call = RewriteAwaitExpression(call, nopos); |
| 5158 } |
| 5159 |
4983 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); | 5160 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); |
4984 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos), | 5161 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos), |
4985 zone()); | 5162 zone()); |
4986 | 5163 |
4987 Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos); | 5164 Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos); |
4988 | 5165 |
4989 Scope* catch_scope = NewScopeWithParent(scope, CATCH_SCOPE); | 5166 Scope* catch_scope = NewScopeWithParent(scope, CATCH_SCOPE); |
4990 Variable* catch_variable = | 5167 Variable* catch_variable = |
4991 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR, | 5168 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR, |
4992 kCreatedInitialized, NORMAL_VARIABLE); | 5169 kCreatedInitialized, NORMAL_VARIABLE); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5073 maybe_call_return = factory()->NewIfStatement( | 5250 maybe_call_return = factory()->NewIfStatement( |
5074 condition, factory()->NewEmptyStatement(nopos), call_return_carefully, | 5251 condition, factory()->NewEmptyStatement(nopos), call_return_carefully, |
5075 nopos); | 5252 nopos); |
5076 } | 5253 } |
5077 | 5254 |
5078 statements->Add(get_return, zone()); | 5255 statements->Add(get_return, zone()); |
5079 statements->Add(maybe_call_return, zone()); | 5256 statements->Add(maybe_call_return, zone()); |
5080 } | 5257 } |
5081 | 5258 |
5082 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop, | 5259 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop, |
5083 Variable* var_completion, int pos) { | 5260 Variable* var_completion, |
| 5261 IteratorType type, int pos) { |
5084 // | 5262 // |
5085 // This function replaces the loop with the following wrapping: | 5263 // This function replaces the loop with the following wrapping: |
5086 // | 5264 // |
5087 // completion = kNormalCompletion; | 5265 // completion = kNormalCompletion; |
5088 // try { | 5266 // try { |
5089 // try { | 5267 // try { |
5090 // #loop; | 5268 // #loop; |
5091 // } catch(e) { | 5269 // } catch(e) { |
5092 // if (completion === kAbruptCompletion) completion = kThrowCompletion; | 5270 // if (completion === kAbruptCompletion) completion = kThrowCompletion; |
5093 // %ReThrow(e); | 5271 // %ReThrow(e); |
(...skipping 23 matching lines...) Expand all Loading... |
5117 { | 5295 { |
5118 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); | 5296 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); |
5119 try_block->statements()->Add(loop, zone()); | 5297 try_block->statements()->Add(loop, zone()); |
5120 | 5298 |
5121 // The scope in which the parser creates this loop. | 5299 // The scope in which the parser creates this loop. |
5122 Scope* loop_scope = scope()->outer_scope(); | 5300 Scope* loop_scope = scope()->outer_scope(); |
5123 DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE); | 5301 DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE); |
5124 DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE); | 5302 DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE); |
5125 | 5303 |
5126 FinalizeIteratorUse(loop_scope, var_completion, closing_condition, | 5304 FinalizeIteratorUse(loop_scope, var_completion, closing_condition, |
5127 loop->iterator(), try_block, final_loop); | 5305 loop->iterator(), try_block, final_loop, type); |
5128 } | 5306 } |
5129 | 5307 |
5130 return final_loop; | 5308 return final_loop; |
5131 } | 5309 } |
5132 | 5310 |
5133 #undef CHECK_OK | 5311 #undef CHECK_OK |
5134 #undef CHECK_OK_VOID | 5312 #undef CHECK_OK_VOID |
5135 #undef CHECK_FAILED | 5313 #undef CHECK_FAILED |
5136 | 5314 |
5137 } // namespace internal | 5315 } // namespace internal |
5138 } // namespace v8 | 5316 } // namespace v8 |
OLD | NEW |