OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/ast/ast-expression-rewriter.h" | 10 #include "src/ast/ast-expression-rewriter.h" |
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
546 info->extension() == nullptr && can_compile_lazily; | 546 info->extension() == nullptr && can_compile_lazily; |
547 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); | 547 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); |
548 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && | 548 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && |
549 info->isolate()->is_tail_call_elimination_enabled()); | 549 info->isolate()->is_tail_call_elimination_enabled()); |
550 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); | 550 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); |
551 set_allow_harmony_function_sent(FLAG_harmony_function_sent); | 551 set_allow_harmony_function_sent(FLAG_harmony_function_sent); |
552 set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators); | 552 set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators); |
553 set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas); | 553 set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas); |
554 set_allow_harmony_class_fields(FLAG_harmony_class_fields); | 554 set_allow_harmony_class_fields(FLAG_harmony_class_fields); |
555 set_allow_harmony_object_rest_spread(FLAG_harmony_object_rest_spread); | 555 set_allow_harmony_object_rest_spread(FLAG_harmony_object_rest_spread); |
556 set_allow_harmony_async_iteration(FLAG_harmony_async_iteration); | |
556 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 557 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
557 ++feature) { | 558 ++feature) { |
558 use_counts_[feature] = 0; | 559 use_counts_[feature] = 0; |
559 } | 560 } |
560 if (info->ast_value_factory() == NULL) { | 561 if (info->ast_value_factory() == NULL) { |
561 // info takes ownership of AstValueFactory. | 562 // info takes ownership of AstValueFactory. |
562 info->set_ast_value_factory(new AstValueFactory( | 563 info->set_ast_value_factory(new AstValueFactory( |
563 zone(), info->isolate()->ast_string_constants(), info->hash_seed())); | 564 zone(), info->isolate()->ast_string_constants(), info->hash_seed())); |
564 info->set_ast_value_factory_owned(); | 565 info->set_ast_value_factory_owned(); |
565 ast_value_factory_ = info->ast_value_factory(); | 566 ast_value_factory_ = info->ast_value_factory(); |
(...skipping 1182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1748 DCHECK_NOT_NULL(catch_info.variable); | 1749 DCHECK_NOT_NULL(catch_info.variable); |
1749 return factory()->NewTryCatchStatement( | 1750 return factory()->NewTryCatchStatement( |
1750 try_block, catch_info.scope, catch_info.variable, catch_block, pos); | 1751 try_block, catch_info.scope, catch_info.variable, catch_block, pos); |
1751 } else { | 1752 } else { |
1752 DCHECK_NOT_NULL(finally_block); | 1753 DCHECK_NOT_NULL(finally_block); |
1753 return factory()->NewTryFinallyStatement(try_block, finally_block, pos); | 1754 return factory()->NewTryFinallyStatement(try_block, finally_block, pos); |
1754 } | 1755 } |
1755 } | 1756 } |
1756 | 1757 |
1757 // !%_IsJSReceiver(result = iterator.next()) && | 1758 // !%_IsJSReceiver(result = iterator.next()) && |
1758 // %ThrowIteratorResultNotAnObject(result) | 1759 // %ThrowIteratorResultNotAnObject(result) |
neis
2017/01/20 14:38:15
Comment needs an update.
| |
1759 Expression* Parser::BuildIteratorNextResult(Expression* iterator, | 1760 Expression* Parser::BuildIteratorNextResult(Expression* iterator, |
1760 Variable* result, int pos) { | 1761 Variable* result, IteratorType type, |
1762 int pos) { | |
1761 Expression* next_literal = factory()->NewStringLiteral( | 1763 Expression* next_literal = factory()->NewStringLiteral( |
1762 ast_value_factory()->next_string(), kNoSourcePosition); | 1764 ast_value_factory()->next_string(), kNoSourcePosition); |
1763 Expression* next_property = | 1765 Expression* next_property = |
1764 factory()->NewProperty(iterator, next_literal, kNoSourcePosition); | 1766 factory()->NewProperty(iterator, next_literal, kNoSourcePosition); |
1765 ZoneList<Expression*>* next_arguments = | 1767 ZoneList<Expression*>* next_arguments = |
1766 new (zone()) ZoneList<Expression*>(0, zone()); | 1768 new (zone()) ZoneList<Expression*>(0, zone()); |
1767 Expression* next_call = | 1769 Expression* next_call = |
1768 factory()->NewCall(next_property, next_arguments, pos); | 1770 factory()->NewCall(next_property, next_arguments, pos); |
1771 if (type == IteratorType::kAsync) { | |
1772 next_call = RewriteAwaitExpression(next_call, pos); | |
1773 } | |
1769 Expression* result_proxy = factory()->NewVariableProxy(result); | 1774 Expression* result_proxy = factory()->NewVariableProxy(result); |
1770 Expression* left = | 1775 Expression* left = |
1771 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos); | 1776 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos); |
1772 | 1777 |
1773 // %_IsJSReceiver(...) | 1778 // %_IsJSReceiver(...) |
1774 ZoneList<Expression*>* is_spec_object_args = | 1779 ZoneList<Expression*>* is_spec_object_args = |
1775 new (zone()) ZoneList<Expression*>(1, zone()); | 1780 new (zone()) ZoneList<Expression*>(1, zone()); |
1776 is_spec_object_args->Add(left, zone()); | 1781 is_spec_object_args->Add(left, zone()); |
1777 Expression* is_spec_object_call = factory()->NewCallRuntime( | 1782 Expression* is_spec_object_call = factory()->NewCallRuntime( |
1778 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos); | 1783 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos); |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1964 // If finalize is true, also instrument the loop with code that performs the | 1969 // If finalize is true, also instrument the loop with code that performs the |
1965 // proper ES6 iterator finalization. In that case, the result is not | 1970 // proper ES6 iterator finalization. In that case, the result is not |
1966 // immediately a ForOfStatement. | 1971 // immediately a ForOfStatement. |
1967 | 1972 |
1968 const int nopos = kNoSourcePosition; | 1973 const int nopos = kNoSourcePosition; |
1969 auto avfactory = ast_value_factory(); | 1974 auto avfactory = ast_value_factory(); |
1970 | 1975 |
1971 Variable* iterator = NewTemporary(avfactory->dot_iterator_string()); | 1976 Variable* iterator = NewTemporary(avfactory->dot_iterator_string()); |
1972 Variable* result = NewTemporary(avfactory->dot_result_string()); | 1977 Variable* result = NewTemporary(avfactory->dot_result_string()); |
1973 Variable* completion = NewTemporary(avfactory->empty_string()); | 1978 Variable* completion = NewTemporary(avfactory->empty_string()); |
1974 | 1979 |
neis
2017/01/20 14:38:15
Comment needs an update.
| |
1975 // iterator = GetIterator(iterable) | 1980 // iterator = GetIterator(iterable) |
1976 Expression* assign_iterator; | 1981 Expression* assign_iterator; |
1977 { | 1982 { |
1978 assign_iterator = factory()->NewAssignment( | 1983 assign_iterator = factory()->NewAssignment( |
1979 Token::ASSIGN, factory()->NewVariableProxy(iterator), | 1984 Token::ASSIGN, factory()->NewVariableProxy(iterator), |
1980 factory()->NewGetIterator(iterable, iterable->position()), | 1985 factory()->NewGetIterator(iterable, GetIterator::kNormal, |
1986 iterable->position()), | |
1981 iterable->position()); | 1987 iterable->position()); |
1982 } | 1988 } |
1983 | 1989 |
1984 // !%_IsJSReceiver(result = iterator.next()) && | 1990 // !%_IsJSReceiver(result = iterator.next()) && |
1985 // %ThrowIteratorResultNotAnObject(result) | 1991 // %ThrowIteratorResultNotAnObject(result) |
1986 Expression* next_result; | 1992 Expression* next_result; |
1987 { | 1993 { |
1988 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 1994 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
1989 next_result = | 1995 next_result = BuildIteratorNextResult( |
1990 BuildIteratorNextResult(iterator_proxy, result, next_result_pos); | 1996 iterator_proxy, result, IteratorType::kNormal, next_result_pos); |
1991 } | 1997 } |
1992 | 1998 |
1993 // result.done | 1999 // result.done |
1994 Expression* result_done; | 2000 Expression* result_done; |
1995 { | 2001 { |
1996 Expression* done_literal = factory()->NewStringLiteral( | 2002 Expression* done_literal = factory()->NewStringLiteral( |
1997 ast_value_factory()->done_string(), kNoSourcePosition); | 2003 ast_value_factory()->done_string(), kNoSourcePosition); |
1998 Expression* result_proxy = factory()->NewVariableProxy(result); | 2004 Expression* result_proxy = factory()->NewVariableProxy(result); |
1999 result_done = | 2005 result_done = |
2000 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition); | 2006 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2068 // Statement* body (gets overwritten) | 2074 // Statement* body (gets overwritten) |
2069 if (finalize) { | 2075 if (finalize) { |
2070 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); | 2076 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); |
2071 block->statements()->Add(body, zone()); | 2077 block->statements()->Add(body, zone()); |
2072 block->statements()->Add(set_completion_normal, zone()); | 2078 block->statements()->Add(set_completion_normal, zone()); |
2073 body = block; | 2079 body = block; |
2074 } | 2080 } |
2075 | 2081 |
2076 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, | 2082 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, |
2077 assign_each); | 2083 assign_each); |
2078 return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of; | 2084 return finalize ? FinalizeForOfStatement(for_of, completion, |
2085 IteratorType::kNormal, nopos) | |
2086 : for_of; | |
2087 } | |
2088 | |
2089 Statement* Parser::InitializeForAwaitOfStatement(ForEachStatement* for_each, | |
neis
2017/01/20 14:38:15
Can't you just parameterize the existing Initializ
caitp
2017/01/20 17:05:34
It's doable, but harder to read IMO
. Whatever peo
caitp
2017/01/20 20:17:19
Eh, it actually gets pretty ugly to try to do it t
| |
2090 Expression* each, | |
2091 Expression* iterable, | |
2092 Statement* body, bool finalize, | |
2093 int next_result_pos) { | |
2094 // Create the auxiliary expressions needed for iterating over the iterable, | |
2095 // and initialize the given ForOfStatement with them. | |
2096 // If finalize is true, also instrument the loop with code that performs the | |
2097 // proper ES6 iterator finalization. In that case, the result is not | |
2098 // immediately a ForOfStatement. | |
2099 | |
2100 ForOfStatement* for_of = for_each->AsForOfStatement(); | |
2101 DCHECK_NOT_NULL(for_of); | |
2102 | |
2103 const int nopos = kNoSourcePosition; | |
2104 auto avfactory = ast_value_factory(); | |
2105 | |
2106 Variable* iterator = NewTemporary(avfactory->dot_iterator_string()); | |
2107 Variable* result = NewTemporary(avfactory->dot_result_string()); | |
2108 Variable* completion = NewTemporary(avfactory->empty_string()); | |
2109 | |
2110 // iterator = GetIterator(iterable) | |
neis
2017/01/20 14:38:16
Comment needs an update.
| |
2111 Expression* assign_iterator; | |
2112 { | |
2113 assign_iterator = factory()->NewAssignment( | |
2114 Token::ASSIGN, factory()->NewVariableProxy(iterator), | |
2115 factory()->NewGetIterator(iterable, GetIterator::kAsync, | |
2116 iterable->position()), | |
2117 iterable->position()); | |
2118 } | |
2119 | |
2120 // !%_IsJSReceiver(result = iterator.next()) && | |
2121 // %ThrowIteratorResultNotAnObject(result) | |
neis
2017/01/20 14:38:15
Comment needs an update.
| |
2122 Expression* next_result; | |
2123 { | |
2124 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | |
2125 next_result = BuildIteratorNextResult( | |
2126 iterator_proxy, result, IteratorType::kAsync, next_result_pos); | |
2127 } | |
2128 | |
2129 // result.done | |
2130 Expression* result_done; | |
2131 { | |
2132 Expression* done_literal = factory()->NewStringLiteral( | |
2133 ast_value_factory()->done_string(), kNoSourcePosition); | |
2134 Expression* result_proxy = factory()->NewVariableProxy(result); | |
2135 result_done = | |
2136 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition); | |
2137 } | |
2138 | |
2139 // result.value | |
2140 Expression* result_value; | |
2141 { | |
2142 Expression* value_literal = | |
2143 factory()->NewStringLiteral(avfactory->value_string(), nopos); | |
2144 Expression* result_proxy = factory()->NewVariableProxy(result); | |
2145 result_value = factory()->NewProperty(result_proxy, value_literal, nopos); | |
2146 } | |
2147 | |
2148 // {{completion = kAbruptCompletion;}} | |
2149 Statement* set_completion_abrupt; | |
2150 if (finalize) { | |
2151 Expression* proxy = factory()->NewVariableProxy(completion); | |
2152 Expression* assignment = factory()->NewAssignment( | |
2153 Token::ASSIGN, proxy, | |
2154 factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos); | |
2155 | |
2156 Block* block = factory()->NewBlock(nullptr, 1, true, nopos); | |
2157 block->statements()->Add( | |
2158 factory()->NewExpressionStatement(assignment, nopos), zone()); | |
2159 set_completion_abrupt = block; | |
2160 } | |
2161 | |
2162 // do { let tmp = #result_value; #set_completion_abrupt; tmp } | |
2163 // Expression* result_value (gets overwritten) | |
2164 if (finalize) { | |
2165 Variable* var_tmp = NewTemporary(avfactory->empty_string()); | |
2166 Expression* tmp = factory()->NewVariableProxy(var_tmp); | |
2167 Expression* assignment = | |
2168 factory()->NewAssignment(Token::ASSIGN, tmp, result_value, nopos); | |
2169 | |
2170 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); | |
2171 block->statements()->Add( | |
2172 factory()->NewExpressionStatement(assignment, nopos), zone()); | |
2173 block->statements()->Add(set_completion_abrupt, zone()); | |
2174 | |
2175 result_value = factory()->NewDoExpression(block, var_tmp, nopos); | |
2176 } | |
2177 | |
2178 // each = #result_value; | |
2179 Expression* assign_each; | |
2180 { | |
2181 assign_each = | |
2182 factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos); | |
2183 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { | |
2184 assign_each = PatternRewriter::RewriteDestructuringAssignment( | |
2185 this, assign_each->AsAssignment(), scope()); | |
2186 } | |
2187 } | |
2188 | |
2189 // {{completion = kNormalCompletion;}} | |
2190 Statement* set_completion_normal; | |
2191 if (finalize) { | |
2192 Expression* proxy = factory()->NewVariableProxy(completion); | |
2193 Expression* assignment = factory()->NewAssignment( | |
2194 Token::ASSIGN, proxy, | |
2195 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); | |
2196 | |
2197 Block* block = factory()->NewBlock(nullptr, 1, true, nopos); | |
2198 block->statements()->Add( | |
2199 factory()->NewExpressionStatement(assignment, nopos), zone()); | |
2200 set_completion_normal = block; | |
2201 } | |
2202 | |
2203 // { #loop-body; #set_completion_normal } | |
2204 // Statement* body (gets overwritten) | |
2205 if (finalize) { | |
2206 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); | |
2207 block->statements()->Add(body, zone()); | |
2208 block->statements()->Add(set_completion_normal, zone()); | |
2209 body = block; | |
2210 } | |
2211 | |
2212 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, | |
2213 assign_each); | |
2214 return finalize ? FinalizeForOfStatement(for_of, completion, | |
2215 IteratorType::kAsync, nopos) | |
2216 : for_of; | |
2079 } | 2217 } |
2080 | 2218 |
2081 Statement* Parser::DesugarLexicalBindingsInForStatement( | 2219 Statement* Parser::DesugarLexicalBindingsInForStatement( |
2082 ForStatement* loop, Statement* init, Expression* cond, Statement* next, | 2220 ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
2083 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) { | 2221 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) { |
2084 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are | 2222 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are |
2085 // copied into a new environment. Moreover, the "next" statement must be | 2223 // copied into a new environment. Moreover, the "next" statement must be |
2086 // evaluated not in the environment of the just completed iteration but in | 2224 // evaluated not in the environment of the just completed iteration but in |
2087 // that of the upcoming one. We achieve this with the following desugaring. | 2225 // that of the upcoming one. We achieve this with the following desugaring. |
2088 // Extra care is needed to preserve the completion value of the original loop. | 2226 // Extra care is needed to preserve the completion value of the original loop. |
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2733 reusable_preparser_ = new PreParser( | 2871 reusable_preparser_ = new PreParser( |
2734 zone(), &scanner_, stack_limit_, ast_value_factory(), | 2872 zone(), &scanner_, stack_limit_, ast_value_factory(), |
2735 &pending_error_handler_, runtime_call_stats_, parsing_on_main_thread_); | 2873 &pending_error_handler_, runtime_call_stats_, parsing_on_main_thread_); |
2736 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); | 2874 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); |
2737 SET_ALLOW(natives); | 2875 SET_ALLOW(natives); |
2738 SET_ALLOW(harmony_do_expressions); | 2876 SET_ALLOW(harmony_do_expressions); |
2739 SET_ALLOW(harmony_function_sent); | 2877 SET_ALLOW(harmony_function_sent); |
2740 SET_ALLOW(harmony_trailing_commas); | 2878 SET_ALLOW(harmony_trailing_commas); |
2741 SET_ALLOW(harmony_class_fields); | 2879 SET_ALLOW(harmony_class_fields); |
2742 SET_ALLOW(harmony_object_rest_spread); | 2880 SET_ALLOW(harmony_object_rest_spread); |
2881 SET_ALLOW(harmony_async_iteration); | |
2743 #undef SET_ALLOW | 2882 #undef SET_ALLOW |
2744 } | 2883 } |
2745 // Aborting inner function preparsing would leave scopes in an inconsistent | 2884 // Aborting inner function preparsing would leave scopes in an inconsistent |
2746 // state; we don't parse inner functions in the abortable mode anyway. | 2885 // state; we don't parse inner functions in the abortable mode anyway. |
2747 DCHECK(!is_inner_function || !may_abort); | 2886 DCHECK(!is_inner_function || !may_abort); |
2748 | 2887 |
2749 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( | 2888 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( |
2750 kind, function_scope, parsing_module_, is_inner_function, may_abort, | 2889 kind, function_scope, parsing_module_, is_inner_function, may_abort, |
2751 use_counts_); | 2890 use_counts_); |
2752 | 2891 |
(...skipping 1585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4338 Expression* assignment = | 4477 Expression* assignment = |
4339 factory()->NewAssignment(Token::ASSIGN, output_proxy, | 4478 factory()->NewAssignment(Token::ASSIGN, output_proxy, |
4340 factory()->NewUndefinedLiteral(nopos), nopos); | 4479 factory()->NewUndefinedLiteral(nopos), nopos); |
4341 initialize_output = factory()->NewExpressionStatement(assignment, nopos); | 4480 initialize_output = factory()->NewExpressionStatement(assignment, nopos); |
4342 } | 4481 } |
4343 | 4482 |
4344 // let iterator = GetIterator(iterable); | 4483 // let iterator = GetIterator(iterable); |
4345 Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string()); | 4484 Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string()); |
4346 Statement* get_iterator; | 4485 Statement* get_iterator; |
4347 { | 4486 { |
4348 Expression* iterator = factory()->NewGetIterator(iterable, nopos); | 4487 Expression* iterator = |
4488 factory()->NewGetIterator(iterable, GetIterator::kNormal, nopos); | |
4349 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); | 4489 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); |
4350 Expression* assignment = factory()->NewAssignment( | 4490 Expression* assignment = factory()->NewAssignment( |
4351 Token::ASSIGN, iterator_proxy, iterator, nopos); | 4491 Token::ASSIGN, iterator_proxy, iterator, nopos); |
4352 get_iterator = factory()->NewExpressionStatement(assignment, nopos); | 4492 get_iterator = factory()->NewExpressionStatement(assignment, nopos); |
4353 } | 4493 } |
4354 | 4494 |
4355 // output = iterator.next(input); | 4495 // output = iterator.next(input); |
4356 Statement* call_next; | 4496 Statement* call_next; |
4357 { | 4497 { |
4358 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); | 4498 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4420 Token::EQ, factory()->NewVariableProxy(var_throw), | 4560 Token::EQ, factory()->NewVariableProxy(var_throw), |
4421 factory()->NewNullLiteral(nopos), nopos); | 4561 factory()->NewNullLiteral(nopos), nopos); |
4422 Expression* call = | 4562 Expression* call = |
4423 NewThrowTypeError(MessageTemplate::kThrowMethodMissing, | 4563 NewThrowTypeError(MessageTemplate::kThrowMethodMissing, |
4424 ast_value_factory()->empty_string(), nopos); | 4564 ast_value_factory()->empty_string(), nopos); |
4425 Statement* throw_call = factory()->NewExpressionStatement(call, nopos); | 4565 Statement* throw_call = factory()->NewExpressionStatement(call, nopos); |
4426 | 4566 |
4427 Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos); | 4567 Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos); |
4428 BuildIteratorCloseForCompletion( | 4568 BuildIteratorCloseForCompletion( |
4429 scope(), then->statements(), var_iterator, | 4569 scope(), then->statements(), var_iterator, |
4430 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos)); | 4570 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), |
4571 IteratorType::kNormal); | |
4431 then->statements()->Add(throw_call, zone()); | 4572 then->statements()->Add(throw_call, zone()); |
4432 check_throw = factory()->NewIfStatement( | 4573 check_throw = factory()->NewIfStatement( |
4433 condition, then, factory()->NewEmptyStatement(nopos), nopos); | 4574 condition, then, factory()->NewEmptyStatement(nopos), nopos); |
4434 } | 4575 } |
4435 | 4576 |
4436 // output = %_Call(iteratorThrow, iterator, input); | 4577 // output = %_Call(iteratorThrow, iterator, input); |
4437 Statement* call_throw; | 4578 Statement* call_throw; |
4438 { | 4579 { |
4439 auto args = new (zone()) ZoneList<Expression*>(3, zone()); | 4580 auto args = new (zone()) ZoneList<Expression*>(3, zone()); |
4440 args->Add(factory()->NewVariableProxy(var_throw), zone()); | 4581 args->Add(factory()->NewVariableProxy(var_throw), zone()); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4606 | 4747 |
4607 // switch (mode) { ... } | 4748 // switch (mode) { ... } |
4608 SwitchStatement* switch_mode = factory()->NewSwitchStatement(nullptr, nopos); | 4749 SwitchStatement* switch_mode = factory()->NewSwitchStatement(nullptr, nopos); |
4609 { | 4750 { |
4610 auto case_next = new (zone()) ZoneList<Statement*>(3, zone()); | 4751 auto case_next = new (zone()) ZoneList<Statement*>(3, zone()); |
4611 case_next->Add(call_next, zone()); | 4752 case_next->Add(call_next, zone()); |
4612 case_next->Add(validate_next_output, zone()); | 4753 case_next->Add(validate_next_output, zone()); |
4613 case_next->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); | 4754 case_next->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); |
4614 | 4755 |
4615 auto case_return = new (zone()) ZoneList<Statement*>(5, zone()); | 4756 auto case_return = new (zone()) ZoneList<Statement*>(5, zone()); |
4616 BuildIteratorClose(case_return, var_iterator, var_input, var_output); | 4757 BuildIteratorClose(case_return, var_iterator, var_input, var_output, |
4758 IteratorType::kNormal); | |
4617 case_return->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); | 4759 case_return->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); |
4618 | 4760 |
4619 auto case_throw = new (zone()) ZoneList<Statement*>(5, zone()); | 4761 auto case_throw = new (zone()) ZoneList<Statement*>(5, zone()); |
4620 case_throw->Add(get_throw, zone()); | 4762 case_throw->Add(get_throw, zone()); |
4621 case_throw->Add(check_throw, zone()); | 4763 case_throw->Add(check_throw, zone()); |
4622 case_throw->Add(call_throw, zone()); | 4764 case_throw->Add(call_throw, zone()); |
4623 case_throw->Add(validate_throw_output, zone()); | 4765 case_throw->Add(validate_throw_output, zone()); |
4624 case_throw->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); | 4766 case_throw->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); |
4625 | 4767 |
4626 auto cases = new (zone()) ZoneList<CaseClause*>(3, zone()); | 4768 auto cases = new (zone()) ZoneList<CaseClause*>(3, zone()); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4690 Statement* throw_call = factory()->NewExpressionStatement(error, pos); | 4832 Statement* throw_call = factory()->NewExpressionStatement(error, pos); |
4691 | 4833 |
4692 validate_var = factory()->NewIfStatement( | 4834 validate_var = factory()->NewIfStatement( |
4693 condition, factory()->NewEmptyStatement(nopos), throw_call, nopos); | 4835 condition, factory()->NewEmptyStatement(nopos), throw_call, nopos); |
4694 } | 4836 } |
4695 return validate_var; | 4837 return validate_var; |
4696 } | 4838 } |
4697 | 4839 |
4698 void Parser::BuildIteratorClose(ZoneList<Statement*>* statements, | 4840 void Parser::BuildIteratorClose(ZoneList<Statement*>* statements, |
4699 Variable* iterator, Variable* input, | 4841 Variable* iterator, Variable* input, |
4700 Variable* var_output) { | 4842 Variable* var_output, IteratorType type) { |
4701 // | 4843 // |
neis
2017/01/20 14:38:15
This function is only used in RewriteYieldStar and
caitp
2017/01/20 17:05:34
That may be a bug then. You're supposed to Iterato
| |
4702 // This function adds four statements to [statements], corresponding to the | 4844 // This function adds four statements to [statements], corresponding to the |
4703 // following code: | 4845 // following code: |
4704 // | 4846 // |
4705 // let iteratorReturn = iterator.return; | 4847 // let iteratorReturn = iterator.return; |
4706 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { | 4848 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { |
4707 // return {value: input, done: true}; | 4849 // return {value: input, done: true}; |
4708 // } | 4850 // } |
4709 // output = %_Call(iteratorReturn, iterator, input); | 4851 // |
4852 // [if (IteratorType == kAsync)] | |
4853 // output = Await(%_Call(iteratorReturn, iterator, input)); | |
4854 // [else] | |
4855 // output = %_Call(iteratorReturn, iterator, input); | |
4856 // [endif] | |
4857 // | |
4710 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); | 4858 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); |
4711 // | 4859 // |
4712 | 4860 |
4713 const int nopos = kNoSourcePosition; | 4861 const int nopos = kNoSourcePosition; |
4714 | 4862 |
4715 // let iteratorReturn = iterator.return; | 4863 // let iteratorReturn = iterator.return; |
4716 Variable* var_return = var_output; // Reusing the output variable. | 4864 Variable* var_return = var_output; // Reusing the output variable. |
4717 Statement* get_return; | 4865 Statement* get_return; |
4718 { | 4866 { |
4719 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 4867 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
(...skipping 28 matching lines...) Expand all Loading... | |
4748 // output = %_Call(iteratorReturn, iterator, input); | 4896 // output = %_Call(iteratorReturn, iterator, input); |
4749 Statement* call_return; | 4897 Statement* call_return; |
4750 { | 4898 { |
4751 auto args = new (zone()) ZoneList<Expression*>(3, zone()); | 4899 auto args = new (zone()) ZoneList<Expression*>(3, zone()); |
4752 args->Add(factory()->NewVariableProxy(var_return), zone()); | 4900 args->Add(factory()->NewVariableProxy(var_return), zone()); |
4753 args->Add(factory()->NewVariableProxy(iterator), zone()); | 4901 args->Add(factory()->NewVariableProxy(iterator), zone()); |
4754 args->Add(factory()->NewVariableProxy(input), zone()); | 4902 args->Add(factory()->NewVariableProxy(input), zone()); |
4755 | 4903 |
4756 Expression* call = | 4904 Expression* call = |
4757 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 4905 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
4906 if (type == IteratorType::kAsync) { | |
4907 call = RewriteAwaitExpression(call, nopos); | |
4908 } | |
4909 | |
4758 Expression* output_proxy = factory()->NewVariableProxy(var_output); | 4910 Expression* output_proxy = factory()->NewVariableProxy(var_output); |
4759 Expression* assignment = | 4911 Expression* assignment = |
4760 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); | 4912 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); |
4761 call_return = factory()->NewExpressionStatement(assignment, nopos); | 4913 call_return = factory()->NewExpressionStatement(assignment, nopos); |
4762 } | 4914 } |
4763 | 4915 |
4764 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output); | 4916 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output); |
4765 Statement* validate_output; | 4917 Statement* validate_output; |
4766 { | 4918 { |
4767 Expression* is_receiver_call; | 4919 Expression* is_receiver_call; |
(...skipping 19 matching lines...) Expand all Loading... | |
4787 } | 4939 } |
4788 | 4940 |
4789 statements->Add(get_return, zone()); | 4941 statements->Add(get_return, zone()); |
4790 statements->Add(check_return, zone()); | 4942 statements->Add(check_return, zone()); |
4791 statements->Add(call_return, zone()); | 4943 statements->Add(call_return, zone()); |
4792 statements->Add(validate_output, zone()); | 4944 statements->Add(validate_output, zone()); |
4793 } | 4945 } |
4794 | 4946 |
4795 void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion, | 4947 void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion, |
4796 Expression* condition, Variable* iter, | 4948 Expression* condition, Variable* iter, |
4797 Block* iterator_use, Block* target) { | 4949 Block* iterator_use, Block* target, |
4950 IteratorType type) { | |
4798 // | 4951 // |
4799 // This function adds two statements to [target], corresponding to the | 4952 // This function adds two statements to [target], corresponding to the |
4800 // following code: | 4953 // following code: |
4801 // | 4954 // |
4802 // completion = kNormalCompletion; | 4955 // completion = kNormalCompletion; |
4803 // try { | 4956 // try { |
4804 // try { | 4957 // try { |
4805 // iterator_use | 4958 // iterator_use |
4806 // } catch(e) { | 4959 // } catch(e) { |
4807 // if (completion === kAbruptCompletion) completion = kThrowCompletion; | 4960 // if (completion === kAbruptCompletion) completion = kThrowCompletion; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4843 condition, statement, factory()->NewEmptyStatement(nopos), nopos); | 4996 condition, statement, factory()->NewEmptyStatement(nopos), nopos); |
4844 } | 4997 } |
4845 | 4998 |
4846 // if (condition) { | 4999 // if (condition) { |
4847 // #BuildIteratorCloseForCompletion(iter, completion) | 5000 // #BuildIteratorCloseForCompletion(iter, completion) |
4848 // } | 5001 // } |
4849 Block* maybe_close; | 5002 Block* maybe_close; |
4850 { | 5003 { |
4851 Block* block = factory()->NewBlock(nullptr, 2, true, nopos); | 5004 Block* block = factory()->NewBlock(nullptr, 2, true, nopos); |
4852 Expression* proxy = factory()->NewVariableProxy(completion); | 5005 Expression* proxy = factory()->NewVariableProxy(completion); |
4853 BuildIteratorCloseForCompletion(use_scope, block->statements(), iter, | 5006 BuildIteratorCloseForCompletion(use_scope, block->statements(), iter, proxy, |
4854 proxy); | 5007 type); |
4855 DCHECK(block->statements()->length() == 2); | 5008 DCHECK(block->statements()->length() == 2); |
4856 | 5009 |
4857 maybe_close = factory()->NewBlock(nullptr, 1, true, nopos); | 5010 maybe_close = factory()->NewBlock(nullptr, 1, true, nopos); |
4858 maybe_close->statements()->Add( | 5011 maybe_close->statements()->Add( |
4859 factory()->NewIfStatement(condition, block, | 5012 factory()->NewIfStatement(condition, block, |
4860 factory()->NewEmptyStatement(nopos), nopos), | 5013 factory()->NewEmptyStatement(nopos), nopos), |
4861 zone()); | 5014 zone()); |
4862 } | 5015 } |
4863 | 5016 |
4864 // try { #try_block } | 5017 // try { #try_block } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4903 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos); | 5056 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos); |
4904 } | 5057 } |
4905 | 5058 |
4906 target->statements()->Add(initialize_completion, zone()); | 5059 target->statements()->Add(initialize_completion, zone()); |
4907 target->statements()->Add(try_finally, zone()); | 5060 target->statements()->Add(try_finally, zone()); |
4908 } | 5061 } |
4909 | 5062 |
4910 void Parser::BuildIteratorCloseForCompletion(Scope* scope, | 5063 void Parser::BuildIteratorCloseForCompletion(Scope* scope, |
4911 ZoneList<Statement*>* statements, | 5064 ZoneList<Statement*>* statements, |
4912 Variable* iterator, | 5065 Variable* iterator, |
4913 Expression* completion) { | 5066 Expression* completion, |
5067 IteratorType type) { | |
4914 // | 5068 // |
4915 // This function adds two statements to [statements], corresponding to the | 5069 // This function adds two statements to [statements], corresponding to the |
4916 // following code: | 5070 // following code: |
4917 // | 5071 // |
4918 // let iteratorReturn = iterator.return; | 5072 // let iteratorReturn = iterator.return; |
4919 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { | 5073 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { |
4920 // if (completion === kThrowCompletion) { | 5074 // if (completion === kThrowCompletion) { |
4921 // if (!IS_CALLABLE(iteratorReturn)) { | 5075 // if (!IS_CALLABLE(iteratorReturn)) { |
4922 // throw MakeTypeError(kReturnMethodNotCallable); | 5076 // throw MakeTypeError(kReturnMethodNotCallable); |
4923 // } | 5077 // } |
4924 // try { %_Call(iteratorReturn, iterator) } catch (_) { } | 5078 // try { %_Call(iteratorReturn, iterator) } catch (_) { } |
4925 // } else { | 5079 // } else { |
4926 // let output = %_Call(iteratorReturn, iterator); | 5080 // let output = %_Call(iteratorReturn, iterator); |
4927 // if (!IS_RECEIVER(output)) { | 5081 // if (!IS_RECEIVER(output)) { |
4928 // %ThrowIterResultNotAnObject(output); | 5082 // %ThrowIterResultNotAnObject(output); |
4929 // } | 5083 // } |
4930 // } | 5084 // } |
4931 // } | 5085 // } |
4932 // | 5086 // |
neis
2017/01/20 14:38:15
Comment needs an update.
| |
4933 | 5087 |
4934 const int nopos = kNoSourcePosition; | 5088 const int nopos = kNoSourcePosition; |
4935 // let iteratorReturn = iterator.return; | 5089 // let iteratorReturn = iterator.return; |
4936 Variable* var_return = NewTemporary(ast_value_factory()->empty_string()); | 5090 Variable* var_return = NewTemporary(ast_value_factory()->empty_string()); |
4937 Statement* get_return; | 5091 Statement* get_return; |
4938 { | 5092 { |
4939 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 5093 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
4940 Expression* literal = factory()->NewStringLiteral( | 5094 Expression* literal = factory()->NewStringLiteral( |
4941 ast_value_factory()->return_string(), nopos); | 5095 ast_value_factory()->return_string(), nopos); |
4942 Expression* property = | 5096 Expression* property = |
4943 factory()->NewProperty(iterator_proxy, literal, nopos); | 5097 factory()->NewProperty(iterator_proxy, literal, nopos); |
4944 Expression* return_proxy = factory()->NewVariableProxy(var_return); | 5098 Expression* return_proxy = factory()->NewVariableProxy(var_return); |
4945 Expression* assignment = | 5099 Expression* assignment = |
4946 factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos); | 5100 factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos); |
4947 get_return = factory()->NewExpressionStatement(assignment, nopos); | 5101 get_return = factory()->NewExpressionStatement(assignment, nopos); |
4948 } | 5102 } |
4949 | 5103 |
4950 // if (!IS_CALLABLE(iteratorReturn)) { | 5104 // if (!IS_CALLABLE(iteratorReturn)) { |
4951 // throw MakeTypeError(kReturnMethodNotCallable); | 5105 // throw MakeTypeError(kReturnMethodNotCallable); |
4952 // } | 5106 // } |
4953 Statement* check_return_callable; | 5107 Statement* check_return_callable; |
4954 { | 5108 { |
4955 Expression* throw_expr = | 5109 Expression* throw_expr = |
4956 NewThrowTypeError(MessageTemplate::kReturnMethodNotCallable, | 5110 NewThrowTypeError(MessageTemplate::kReturnMethodNotCallable, |
4957 ast_value_factory()->empty_string(), nopos); | 5111 ast_value_factory()->empty_string(), nopos); |
4958 check_return_callable = CheckCallable(var_return, throw_expr, nopos); | 5112 check_return_callable = CheckCallable(var_return, throw_expr, nopos); |
4959 } | 5113 } |
4960 | 5114 |
4961 // try { %_Call(iteratorReturn, iterator) } catch (_) { } | 5115 // try { %_Call(iteratorReturn, iterator) } catch (_) { } |
neis
2017/01/20 14:38:15
Comment needs an update.
| |
4962 Statement* try_call_return; | 5116 Statement* try_call_return; |
4963 { | 5117 { |
4964 auto args = new (zone()) ZoneList<Expression*>(2, zone()); | 5118 auto args = new (zone()) ZoneList<Expression*>(2, zone()); |
4965 args->Add(factory()->NewVariableProxy(var_return), zone()); | 5119 args->Add(factory()->NewVariableProxy(var_return), zone()); |
4966 args->Add(factory()->NewVariableProxy(iterator), zone()); | 5120 args->Add(factory()->NewVariableProxy(iterator), zone()); |
4967 | 5121 |
4968 Expression* call = | 5122 Expression* call = |
4969 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 5123 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
4970 | 5124 |
5125 if (type == IteratorType::kAsync) { | |
5126 call = RewriteAwaitExpression(call, nopos); | |
5127 } | |
5128 | |
4971 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); | 5129 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); |
4972 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos), | 5130 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos), |
4973 zone()); | 5131 zone()); |
4974 | 5132 |
4975 Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos); | 5133 Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos); |
4976 | 5134 |
4977 Scope* catch_scope = NewScopeWithParent(scope, CATCH_SCOPE); | 5135 Scope* catch_scope = NewScopeWithParent(scope, CATCH_SCOPE); |
4978 Variable* catch_variable = | 5136 Variable* catch_variable = |
4979 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR); | 5137 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR); |
4980 catch_scope->set_is_hidden(); | 5138 catch_scope->set_is_hidden(); |
(...skipping 14 matching lines...) Expand all Loading... | |
4995 auto args = new (zone()) ZoneList<Expression*>(2, zone()); | 5153 auto args = new (zone()) ZoneList<Expression*>(2, zone()); |
4996 args->Add(factory()->NewVariableProxy(var_return), zone()); | 5154 args->Add(factory()->NewVariableProxy(var_return), zone()); |
4997 args->Add(factory()->NewVariableProxy(iterator), zone()); | 5155 args->Add(factory()->NewVariableProxy(iterator), zone()); |
4998 Expression* call = | 5156 Expression* call = |
4999 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); | 5157 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); |
5000 | 5158 |
5001 Expression* output_proxy = factory()->NewVariableProxy(var_output); | 5159 Expression* output_proxy = factory()->NewVariableProxy(var_output); |
5002 Expression* assignment = | 5160 Expression* assignment = |
5003 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); | 5161 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); |
5004 call_return = factory()->NewExpressionStatement(assignment, nopos); | 5162 call_return = factory()->NewExpressionStatement(assignment, nopos); |
5005 } | 5163 } |
neis
2017/01/20 14:38:15
We must also do await on the result of this call.
caitp
2017/01/23 14:18:15
Done.
| |
5006 | 5164 |
5007 Expression* is_receiver_call; | 5165 Expression* is_receiver_call; |
5008 { | 5166 { |
5009 auto args = new (zone()) ZoneList<Expression*>(1, zone()); | 5167 auto args = new (zone()) ZoneList<Expression*>(1, zone()); |
5010 args->Add(factory()->NewVariableProxy(var_output), zone()); | 5168 args->Add(factory()->NewVariableProxy(var_output), zone()); |
5011 is_receiver_call = | 5169 is_receiver_call = |
5012 factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); | 5170 factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); |
5013 } | 5171 } |
5014 | 5172 |
5015 Statement* throw_call; | 5173 Statement* throw_call; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5060 maybe_call_return = factory()->NewIfStatement( | 5218 maybe_call_return = factory()->NewIfStatement( |
5061 condition, factory()->NewEmptyStatement(nopos), call_return_carefully, | 5219 condition, factory()->NewEmptyStatement(nopos), call_return_carefully, |
5062 nopos); | 5220 nopos); |
5063 } | 5221 } |
5064 | 5222 |
5065 statements->Add(get_return, zone()); | 5223 statements->Add(get_return, zone()); |
5066 statements->Add(maybe_call_return, zone()); | 5224 statements->Add(maybe_call_return, zone()); |
5067 } | 5225 } |
5068 | 5226 |
5069 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop, | 5227 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop, |
5070 Variable* var_completion, int pos) { | 5228 Variable* var_completion, |
5229 IteratorType type, int pos) { | |
5071 // | 5230 // |
5072 // This function replaces the loop with the following wrapping: | 5231 // This function replaces the loop with the following wrapping: |
5073 // | 5232 // |
5074 // completion = kNormalCompletion; | 5233 // completion = kNormalCompletion; |
5075 // try { | 5234 // try { |
5076 // try { | 5235 // try { |
5077 // #loop; | 5236 // #loop; |
5078 // } catch(e) { | 5237 // } catch(e) { |
5079 // if (completion === kAbruptCompletion) completion = kThrowCompletion; | 5238 // if (completion === kAbruptCompletion) completion = kThrowCompletion; |
5080 // %ReThrow(e); | 5239 // %ReThrow(e); |
5081 // } | 5240 // } |
5082 // } finally { | 5241 // } finally { |
5083 // if (!(completion === kNormalCompletion)) { | 5242 // if (!(completion === kNormalCompletion)) { |
5084 // #BuildIteratorCloseForCompletion(#iterator, completion) | 5243 // #BuildIteratorCloseForCompletion(#iterator, completion) |
neis
2017/01/20 14:38:15
Comment needs an update.
| |
5085 // } | 5244 // } |
5086 // } | 5245 // } |
5087 // | 5246 // |
5088 // Note that the loop's body and its assign_each already contain appropriate | 5247 // Note that the loop's body and its assign_each already contain appropriate |
5089 // assignments to completion (see InitializeForOfStatement). | 5248 // assignments to completion (see InitializeForOfStatement). |
5090 // | 5249 // |
5091 | 5250 |
5092 const int nopos = kNoSourcePosition; | 5251 const int nopos = kNoSourcePosition; |
5093 | 5252 |
5094 // !(completion === kNormalCompletion) | 5253 // !(completion === kNormalCompletion) |
5095 Expression* closing_condition; | 5254 Expression* closing_condition; |
5096 { | 5255 { |
5097 Expression* cmp = factory()->NewCompareOperation( | 5256 Expression* cmp = factory()->NewCompareOperation( |
5098 Token::EQ_STRICT, factory()->NewVariableProxy(var_completion), | 5257 Token::EQ_STRICT, factory()->NewVariableProxy(var_completion), |
5099 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); | 5258 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); |
5100 closing_condition = factory()->NewUnaryOperation(Token::NOT, cmp, nopos); | 5259 closing_condition = factory()->NewUnaryOperation(Token::NOT, cmp, nopos); |
5101 } | 5260 } |
5102 | 5261 |
5103 Block* final_loop = factory()->NewBlock(nullptr, 2, false, nopos); | 5262 Block* final_loop = factory()->NewBlock(nullptr, 2, false, nopos); |
5104 { | 5263 { |
5105 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); | 5264 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); |
5106 try_block->statements()->Add(loop, zone()); | 5265 try_block->statements()->Add(loop, zone()); |
5107 | 5266 |
5108 // The scope in which the parser creates this loop. | 5267 // The scope in which the parser creates this loop. |
5109 Scope* loop_scope = scope()->outer_scope(); | 5268 Scope* loop_scope = scope()->outer_scope(); |
5110 DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE); | 5269 DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE); |
5111 DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE); | 5270 DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE); |
5112 | 5271 |
5113 FinalizeIteratorUse(loop_scope, var_completion, closing_condition, | 5272 FinalizeIteratorUse(loop_scope, var_completion, closing_condition, |
5114 loop->iterator(), try_block, final_loop); | 5273 loop->iterator(), try_block, final_loop, type); |
5115 } | 5274 } |
5116 | 5275 |
5117 return final_loop; | 5276 return final_loop; |
5118 } | 5277 } |
5119 | 5278 |
5120 #undef CHECK_OK | 5279 #undef CHECK_OK |
5121 #undef CHECK_OK_VOID | 5280 #undef CHECK_OK_VOID |
5122 #undef CHECK_FAILED | 5281 #undef CHECK_FAILED |
5123 | 5282 |
5124 } // namespace internal | 5283 } // namespace internal |
5125 } // namespace v8 | 5284 } // namespace v8 |
OLD | NEW |