Chromium Code Reviews| 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 |
| 2004 Expression* result_done; | 2009 Expression* result_done; |
| 2005 { | 2010 { |
| 2006 Expression* done_literal = factory()->NewStringLiteral( | 2011 Expression* done_literal = factory()->NewStringLiteral( |
| 2007 ast_value_factory()->done_string(), kNoSourcePosition); | 2012 ast_value_factory()->done_string(), kNoSourcePosition); |
| 2008 Expression* result_proxy = factory()->NewVariableProxy(result); | 2013 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2009 result_done = | 2014 result_done = |
| 2010 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... | |
| 2078 // Statement* body (gets overwritten) | 2083 // Statement* body (gets overwritten) |
| 2079 if (finalize) { | 2084 if (finalize) { |
| 2080 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); | 2085 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); |
| 2081 block->statements()->Add(body, zone()); | 2086 block->statements()->Add(body, zone()); |
| 2082 block->statements()->Add(set_completion_normal, zone()); | 2087 block->statements()->Add(set_completion_normal, zone()); |
| 2083 body = block; | 2088 body = block; |
| 2084 } | 2089 } |
| 2085 | 2090 |
| 2086 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, | 2091 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, |
| 2087 assign_each); | 2092 assign_each); |
| 2088 return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of; | 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) { | |
|
Dan Ehrenberg
2017/01/13 22:09:02
This is really similar to Parser::InitializeForOf
caitp
2017/01/13 22:33:30
I'm undecided on this.
I think the code is easier
Dan Ehrenberg
2017/01/14 00:48:38
For me, it's easier to understand code when it's n
| |
| 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 | |
| 2137 Expression* result_done; | |
| 2138 { | |
| 2139 Expression* done_literal = factory()->NewStringLiteral( | |
| 2140 ast_value_factory()->done_string(), kNoSourcePosition); | |
| 2141 Expression* result_proxy = factory()->NewVariableProxy(result); | |
| 2142 result_done = | |
| 2143 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition); | |
| 2144 } | |
| 2145 | |
| 2146 // result.value | |
| 2147 Expression* result_value; | |
| 2148 { | |
| 2149 Expression* value_literal = | |
| 2150 factory()->NewStringLiteral(avfactory->value_string(), nopos); | |
| 2151 Expression* result_proxy = factory()->NewVariableProxy(result); | |
| 2152 result_value = factory()->NewProperty(result_proxy, value_literal, nopos); | |
| 2153 } | |
| 2154 | |
| 2155 // {{completion = kAbruptCompletion;}} | |
| 2156 Statement* set_completion_abrupt; | |
| 2157 if (finalize) { | |
| 2158 Expression* proxy = factory()->NewVariableProxy(completion); | |
| 2159 Expression* assignment = factory()->NewAssignment( | |
| 2160 Token::ASSIGN, proxy, | |
| 2161 factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos); | |
| 2162 | |
| 2163 Block* block = factory()->NewBlock(nullptr, 1, true, nopos); | |
| 2164 block->statements()->Add( | |
| 2165 factory()->NewExpressionStatement(assignment, nopos), zone()); | |
| 2166 set_completion_abrupt = block; | |
| 2167 } | |
| 2168 | |
| 2169 // do { let tmp = #result_value; #set_completion_abrupt; tmp } | |
| 2170 // Expression* result_value (gets overwritten) | |
| 2171 if (finalize) { | |
| 2172 Variable* var_tmp = NewTemporary(avfactory->empty_string()); | |
| 2173 Expression* tmp = factory()->NewVariableProxy(var_tmp); | |
| 2174 Expression* assignment = | |
| 2175 factory()->NewAssignment(Token::ASSIGN, tmp, result_value, nopos); | |
| 2176 | |
| 2177 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); | |
| 2178 block->statements()->Add( | |
| 2179 factory()->NewExpressionStatement(assignment, nopos), zone()); | |
| 2180 block->statements()->Add(set_completion_abrupt, zone()); | |
| 2181 | |
| 2182 result_value = factory()->NewDoExpression(block, var_tmp, nopos); | |
| 2183 } | |
| 2184 | |
| 2185 // each = #result_value; | |
| 2186 Expression* assign_each; | |
| 2187 { | |
| 2188 assign_each = | |
| 2189 factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos); | |
| 2190 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { | |
| 2191 assign_each = PatternRewriter::RewriteDestructuringAssignment( | |
| 2192 this, assign_each->AsAssignment(), scope()); | |
| 2193 } | |
| 2194 } | |
| 2195 | |
| 2196 // {{completion = kNormalCompletion;}} | |
| 2197 Statement* set_completion_normal; | |
| 2198 if (finalize) { | |
| 2199 Expression* proxy = factory()->NewVariableProxy(completion); | |
| 2200 Expression* assignment = factory()->NewAssignment( | |
| 2201 Token::ASSIGN, proxy, | |
| 2202 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); | |
| 2203 | |
| 2204 Block* block = factory()->NewBlock(nullptr, 1, true, nopos); | |
| 2205 block->statements()->Add( | |
| 2206 factory()->NewExpressionStatement(assignment, nopos), zone()); | |
| 2207 set_completion_normal = block; | |
| 2208 } | |
| 2209 | |
| 2210 // { #loop-body; #set_completion_normal } | |
| 2211 // Statement* body (gets overwritten) | |
| 2212 if (finalize) { | |
| 2213 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); | |
| 2214 block->statements()->Add(body, zone()); | |
| 2215 block->statements()->Add(set_completion_normal, zone()); | |
| 2216 body = block; | |
| 2217 } | |
| 2218 | |
| 2219 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, | |
| 2220 assign_each); | |
| 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); | |
|
Dan Ehrenberg
2017/01/13 22:09:02
Why don't you have to apply the same sort of block
caitp
2017/01/13 22:33:30
I haven't tested any of this with the inspector ye
Dan Ehrenberg
2017/01/14 00:48:38
I'm confused; if you wanted to minimize the amount
| |
| 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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4503 factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos); | 4665 factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos); |
| 4504 Expression* assignment = | 4666 Expression* assignment = |
| 4505 factory()->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos); | 4667 factory()->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos); |
| 4506 set_mode_return = factory()->NewExpressionStatement(assignment, nopos); | 4668 set_mode_return = factory()->NewExpressionStatement(assignment, nopos); |
| 4507 } | 4669 } |
| 4508 | 4670 |
| 4509 // Yield(output); | 4671 // Yield(output); |
| 4510 Statement* yield_output; | 4672 Statement* yield_output; |
| 4511 { | 4673 { |
| 4512 Expression* output_proxy = factory()->NewVariableProxy(var_output); | 4674 Expression* output_proxy = factory()->NewVariableProxy(var_output); |
| 4513 Yield* yield = factory()->NewYield(generator, output_proxy, nopos, | 4675 Yield* yield = |
| 4514 Yield::kOnExceptionThrow); | 4676 factory()->NewYield(generator, output_proxy, nopos, |
| 4677 Yield::kOnExceptionThrow, Yield::kDelegate); | |
| 4515 yield_output = factory()->NewExpressionStatement(yield, nopos); | 4678 yield_output = factory()->NewExpressionStatement(yield, nopos); |
| 4516 } | 4679 } |
| 4517 | 4680 |
| 4518 // mode = kNext; | 4681 // mode = kNext; |
| 4519 Statement* set_mode_next; | 4682 Statement* set_mode_next; |
| 4520 { | 4683 { |
| 4521 Expression* mode_proxy = factory()->NewVariableProxy(var_mode); | 4684 Expression* mode_proxy = factory()->NewVariableProxy(var_mode); |
| 4522 Expression* knext = | 4685 Expression* knext = |
| 4523 factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos); | 4686 factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos); |
| 4524 Expression* assignment = | 4687 Expression* assignment = |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4617 | 4780 |
| 4618 // switch (mode) { ... } | 4781 // switch (mode) { ... } |
| 4619 SwitchStatement* switch_mode = factory()->NewSwitchStatement(nullptr, nopos); | 4782 SwitchStatement* switch_mode = factory()->NewSwitchStatement(nullptr, nopos); |
| 4620 { | 4783 { |
| 4621 auto case_next = new (zone()) ZoneList<Statement*>(3, zone()); | 4784 auto case_next = new (zone()) ZoneList<Statement*>(3, zone()); |
| 4622 case_next->Add(call_next, zone()); | 4785 case_next->Add(call_next, zone()); |
| 4623 case_next->Add(validate_next_output, zone()); | 4786 case_next->Add(validate_next_output, zone()); |
| 4624 case_next->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); | 4787 case_next->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); |
| 4625 | 4788 |
| 4626 auto case_return = new (zone()) ZoneList<Statement*>(5, zone()); | 4789 auto case_return = new (zone()) ZoneList<Statement*>(5, zone()); |
| 4627 BuildIteratorClose(case_return, var_iterator, var_input, var_output); | 4790 BuildIteratorClose(case_return, var_iterator, var_input, var_output, type); |
| 4628 case_return->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); | 4791 case_return->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); |
| 4629 | 4792 |
| 4630 auto case_throw = new (zone()) ZoneList<Statement*>(5, zone()); | 4793 auto case_throw = new (zone()) ZoneList<Statement*>(5, zone()); |
| 4631 case_throw->Add(get_throw, zone()); | 4794 case_throw->Add(get_throw, zone()); |
| 4632 case_throw->Add(check_throw, zone()); | 4795 case_throw->Add(check_throw, zone()); |
| 4633 case_throw->Add(call_throw, zone()); | 4796 case_throw->Add(call_throw, zone()); |
| 4634 case_throw->Add(validate_throw_output, zone()); | 4797 case_throw->Add(validate_throw_output, zone()); |
| 4635 case_throw->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); | 4798 case_throw->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); |
| 4636 | 4799 |
| 4637 auto cases = new (zone()) ZoneList<CaseClause*>(3, zone()); | 4800 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); | 4864 Statement* throw_call = factory()->NewExpressionStatement(error, pos); |
| 4702 | 4865 |
| 4703 validate_var = factory()->NewIfStatement( | 4866 validate_var = factory()->NewIfStatement( |
| 4704 condition, factory()->NewEmptyStatement(nopos), throw_call, nopos); | 4867 condition, factory()->NewEmptyStatement(nopos), throw_call, nopos); |
| 4705 } | 4868 } |
| 4706 return validate_var; | 4869 return validate_var; |
| 4707 } | 4870 } |
| 4708 | 4871 |
| 4709 void Parser::BuildIteratorClose(ZoneList<Statement*>* statements, | 4872 void Parser::BuildIteratorClose(ZoneList<Statement*>* statements, |
| 4710 Variable* iterator, Variable* input, | 4873 Variable* iterator, Variable* input, |
| 4711 Variable* var_output) { | 4874 Variable* var_output, IteratorType type) { |
| 4712 // | 4875 // |
| 4713 // This function adds four statements to [statements], corresponding to the | 4876 // This function adds four statements to [statements], corresponding to the |
| 4714 // following code: | 4877 // following code: |
| 4715 // | 4878 // |
| 4716 // let iteratorReturn = iterator.return; | 4879 // let iteratorReturn = iterator.return; |
| 4717 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { | 4880 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { |
| 4718 // return {value: input, done: true}; | 4881 // return {value: input, done: true}; |
| 4719 // } | 4882 // } |
| 4720 // output = %_Call(iteratorReturn, iterator, input); | 4883 // output = %_Call(iteratorReturn, iterator, input); |
| 4884 // if (IteratorType == kAsync) { | |
| 4885 // output = Await(output) | |
| 4886 // } | |
| 4721 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 4887 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); |
| 4722 // | 4888 |
| 4889 // output = Await(%_Call(iteratorReturn, iterator, input)); | |
|
Dan Ehrenberg
2017/01/13 19:41:09
Comment nit: should be if (IteratorType == kAsync)
caitp
2017/01/13 20:11:52
It kind of gives the impression that the desugarin
Dan Ehrenberg
2017/01/13 22:09:02
I was just copying the way that you wrote the synt
| |
| 4723 | 4890 |
| 4724 const int nopos = kNoSourcePosition; | 4891 const int nopos = kNoSourcePosition; |
| 4725 | 4892 |
| 4726 // let iteratorReturn = iterator.return; | 4893 // let iteratorReturn = iterator.return; |
| 4727 Variable* var_return = var_output; // Reusing the output variable. | 4894 Variable* var_return = var_output; // Reusing the output variable. |
| 4728 Statement* get_return; | 4895 Statement* get_return; |
| 4729 { | 4896 { |
| 4730 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 4897 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 4731 Expression* literal = factory()->NewStringLiteral( | 4898 Expression* literal = factory()->NewStringLiteral( |
| 4732 ast_value_factory()->return_string(), nopos); | 4899 ast_value_factory()->return_string(), nopos); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 4759 // output = %_Call(iteratorReturn, iterator, input); | 4926 // output = %_Call(iteratorReturn, iterator, input); |
| 4760 Statement* call_return; | 4927 Statement* call_return; |
| 4761 { | 4928 { |
| 4762 auto args = new (zone()) ZoneList<Expression*>(3, zone()); | 4929 auto args = new (zone()) ZoneList<Expression*>(3, zone()); |
| 4763 args->Add(factory()->NewVariableProxy(var_return), zone()); | 4930 args->Add(factory()->NewVariableProxy(var_return), zone()); |
| 4764 args->Add(factory()->NewVariableProxy(iterator), zone()); | 4931 args->Add(factory()->NewVariableProxy(iterator), zone()); |
| 4765 args->Add(factory()->NewVariableProxy(input), zone()); | 4932 args->Add(factory()->NewVariableProxy(input), zone()); |
| 4766 | 4933 |
| 4767 Expression* call = | 4934 Expression* call = |
| 4768 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 4935 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
| 4936 if (type == IteratorType::kAsync) { | |
| 4937 call = RewriteAwaitExpression(call, nopos); | |
| 4938 } | |
| 4769 Expression* output_proxy = factory()->NewVariableProxy(var_output); | 4939 Expression* output_proxy = factory()->NewVariableProxy(var_output); |
| 4770 Expression* assignment = | 4940 Expression* assignment = |
| 4771 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); | 4941 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); |
| 4772 call_return = factory()->NewExpressionStatement(assignment, nopos); | 4942 call_return = factory()->NewExpressionStatement(assignment, nopos); |
| 4773 } | 4943 } |
| 4774 | 4944 |
| 4775 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output); | 4945 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output); |
| 4776 Statement* validate_output; | 4946 Statement* validate_output; |
| 4777 { | 4947 { |
| 4778 Expression* is_receiver_call; | 4948 Expression* is_receiver_call; |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 4798 } | 4968 } |
| 4799 | 4969 |
| 4800 statements->Add(get_return, zone()); | 4970 statements->Add(get_return, zone()); |
| 4801 statements->Add(check_return, zone()); | 4971 statements->Add(check_return, zone()); |
| 4802 statements->Add(call_return, zone()); | 4972 statements->Add(call_return, zone()); |
| 4803 statements->Add(validate_output, zone()); | 4973 statements->Add(validate_output, zone()); |
| 4804 } | 4974 } |
| 4805 | 4975 |
| 4806 void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion, | 4976 void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion, |
| 4807 Expression* condition, Variable* iter, | 4977 Expression* condition, Variable* iter, |
| 4808 Block* iterator_use, Block* target) { | 4978 Block* iterator_use, Block* target, |
| 4979 IteratorType type) { | |
| 4809 // | 4980 // |
| 4810 // This function adds two statements to [target], corresponding to the | 4981 // This function adds two statements to [target], corresponding to the |
| 4811 // following code: | 4982 // following code: |
| 4812 // | 4983 // |
| 4813 // completion = kNormalCompletion; | 4984 // completion = kNormalCompletion; |
| 4814 // try { | 4985 // try { |
| 4815 // try { | 4986 // try { |
| 4816 // iterator_use | 4987 // iterator_use |
| 4817 // } catch(e) { | 4988 // } catch(e) { |
| 4818 // if (completion === kAbruptCompletion) completion = kThrowCompletion; | 4989 // 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); | 5025 condition, statement, factory()->NewEmptyStatement(nopos), nopos); |
| 4855 } | 5026 } |
| 4856 | 5027 |
| 4857 // if (condition) { | 5028 // if (condition) { |
| 4858 // #BuildIteratorCloseForCompletion(iter, completion) | 5029 // #BuildIteratorCloseForCompletion(iter, completion) |
| 4859 // } | 5030 // } |
| 4860 Block* maybe_close; | 5031 Block* maybe_close; |
| 4861 { | 5032 { |
| 4862 Block* block = factory()->NewBlock(nullptr, 2, true, nopos); | 5033 Block* block = factory()->NewBlock(nullptr, 2, true, nopos); |
| 4863 Expression* proxy = factory()->NewVariableProxy(completion); | 5034 Expression* proxy = factory()->NewVariableProxy(completion); |
| 4864 BuildIteratorCloseForCompletion(use_scope, block->statements(), iter, | 5035 BuildIteratorCloseForCompletion(use_scope, block->statements(), iter, proxy, |
| 4865 proxy); | 5036 type); |
| 4866 DCHECK(block->statements()->length() == 2); | 5037 DCHECK(block->statements()->length() == 2); |
| 4867 | 5038 |
| 4868 maybe_close = factory()->NewBlock(nullptr, 1, true, nopos); | 5039 maybe_close = factory()->NewBlock(nullptr, 1, true, nopos); |
| 4869 maybe_close->statements()->Add( | 5040 maybe_close->statements()->Add( |
| 4870 factory()->NewIfStatement(condition, block, | 5041 factory()->NewIfStatement(condition, block, |
| 4871 factory()->NewEmptyStatement(nopos), nopos), | 5042 factory()->NewEmptyStatement(nopos), nopos), |
| 4872 zone()); | 5043 zone()); |
| 4873 } | 5044 } |
| 4874 | 5045 |
| 4875 // try { #try_block } | 5046 // try { #try_block } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4915 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos); | 5086 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos); |
| 4916 } | 5087 } |
| 4917 | 5088 |
| 4918 target->statements()->Add(initialize_completion, zone()); | 5089 target->statements()->Add(initialize_completion, zone()); |
| 4919 target->statements()->Add(try_finally, zone()); | 5090 target->statements()->Add(try_finally, zone()); |
| 4920 } | 5091 } |
| 4921 | 5092 |
| 4922 void Parser::BuildIteratorCloseForCompletion(Scope* scope, | 5093 void Parser::BuildIteratorCloseForCompletion(Scope* scope, |
| 4923 ZoneList<Statement*>* statements, | 5094 ZoneList<Statement*>* statements, |
| 4924 Variable* iterator, | 5095 Variable* iterator, |
| 4925 Expression* completion) { | 5096 Expression* completion, |
| 5097 IteratorType type) { | |
| 4926 // | 5098 // |
| 4927 // This function adds two statements to [statements], corresponding to the | 5099 // This function adds two statements to [statements], corresponding to the |
| 4928 // following code: | 5100 // following code: |
| 4929 // | 5101 // |
| 4930 // let iteratorReturn = iterator.return; | 5102 // let iteratorReturn = iterator.return; |
| 4931 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { | 5103 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { |
| 4932 // if (completion === kThrowCompletion) { | 5104 // if (completion === kThrowCompletion) { |
| 4933 // if (!IS_CALLABLE(iteratorReturn)) { | 5105 // if (!IS_CALLABLE(iteratorReturn)) { |
| 4934 // throw MakeTypeError(kReturnMethodNotCallable); | 5106 // throw MakeTypeError(kReturnMethodNotCallable); |
| 4935 // } | 5107 // } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4973 // try { %_Call(iteratorReturn, iterator) } catch (_) { } | 5145 // try { %_Call(iteratorReturn, iterator) } catch (_) { } |
| 4974 Statement* try_call_return; | 5146 Statement* try_call_return; |
| 4975 { | 5147 { |
| 4976 auto args = new (zone()) ZoneList<Expression*>(2, zone()); | 5148 auto args = new (zone()) ZoneList<Expression*>(2, zone()); |
| 4977 args->Add(factory()->NewVariableProxy(var_return), zone()); | 5149 args->Add(factory()->NewVariableProxy(var_return), zone()); |
| 4978 args->Add(factory()->NewVariableProxy(iterator), zone()); | 5150 args->Add(factory()->NewVariableProxy(iterator), zone()); |
| 4979 | 5151 |
| 4980 Expression* call = | 5152 Expression* call = |
| 4981 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 5153 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
| 4982 | 5154 |
| 5155 if (type == IteratorType::kAsync) { | |
| 5156 call = RewriteAwaitExpression(call, nopos); | |
| 5157 } | |
| 5158 | |
| 4983 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); | 5159 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); |
| 4984 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos), | 5160 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos), |
| 4985 zone()); | 5161 zone()); |
| 4986 | 5162 |
| 4987 Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos); | 5163 Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos); |
| 4988 | 5164 |
| 4989 Scope* catch_scope = NewScopeWithParent(scope, CATCH_SCOPE); | 5165 Scope* catch_scope = NewScopeWithParent(scope, CATCH_SCOPE); |
| 4990 Variable* catch_variable = | 5166 Variable* catch_variable = |
| 4991 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR, | 5167 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR, |
| 4992 kCreatedInitialized, NORMAL_VARIABLE); | 5168 kCreatedInitialized, NORMAL_VARIABLE); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5073 maybe_call_return = factory()->NewIfStatement( | 5249 maybe_call_return = factory()->NewIfStatement( |
| 5074 condition, factory()->NewEmptyStatement(nopos), call_return_carefully, | 5250 condition, factory()->NewEmptyStatement(nopos), call_return_carefully, |
| 5075 nopos); | 5251 nopos); |
| 5076 } | 5252 } |
| 5077 | 5253 |
| 5078 statements->Add(get_return, zone()); | 5254 statements->Add(get_return, zone()); |
| 5079 statements->Add(maybe_call_return, zone()); | 5255 statements->Add(maybe_call_return, zone()); |
| 5080 } | 5256 } |
| 5081 | 5257 |
| 5082 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop, | 5258 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop, |
| 5083 Variable* var_completion, int pos) { | 5259 Variable* var_completion, |
| 5260 IteratorType type, int pos) { | |
| 5084 // | 5261 // |
| 5085 // This function replaces the loop with the following wrapping: | 5262 // This function replaces the loop with the following wrapping: |
| 5086 // | 5263 // |
| 5087 // completion = kNormalCompletion; | 5264 // completion = kNormalCompletion; |
| 5088 // try { | 5265 // try { |
| 5089 // try { | 5266 // try { |
| 5090 // #loop; | 5267 // #loop; |
| 5091 // } catch(e) { | 5268 // } catch(e) { |
| 5092 // if (completion === kAbruptCompletion) completion = kThrowCompletion; | 5269 // if (completion === kAbruptCompletion) completion = kThrowCompletion; |
| 5093 // %ReThrow(e); | 5270 // %ReThrow(e); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 5117 { | 5294 { |
| 5118 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); | 5295 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); |
| 5119 try_block->statements()->Add(loop, zone()); | 5296 try_block->statements()->Add(loop, zone()); |
| 5120 | 5297 |
| 5121 // The scope in which the parser creates this loop. | 5298 // The scope in which the parser creates this loop. |
| 5122 Scope* loop_scope = scope()->outer_scope(); | 5299 Scope* loop_scope = scope()->outer_scope(); |
| 5123 DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE); | 5300 DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE); |
| 5124 DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE); | 5301 DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE); |
| 5125 | 5302 |
| 5126 FinalizeIteratorUse(loop_scope, var_completion, closing_condition, | 5303 FinalizeIteratorUse(loop_scope, var_completion, closing_condition, |
| 5127 loop->iterator(), try_block, final_loop); | 5304 loop->iterator(), try_block, final_loop, type); |
| 5128 } | 5305 } |
| 5129 | 5306 |
| 5130 return final_loop; | 5307 return final_loop; |
| 5131 } | 5308 } |
| 5132 | 5309 |
| 5133 #undef CHECK_OK | 5310 #undef CHECK_OK |
| 5134 #undef CHECK_OK_VOID | 5311 #undef CHECK_OK_VOID |
| 5135 #undef CHECK_FAILED | 5312 #undef CHECK_FAILED |
| 5136 | 5313 |
| 5137 } // namespace internal | 5314 } // namespace internal |
| 5138 } // namespace v8 | 5315 } // namespace v8 |
| OLD | NEW |