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 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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_async_await(FLAG_harmony_async_await); | 552 set_allow_harmony_async_await(FLAG_harmony_async_await); |
553 set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators); | 553 set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators); |
554 set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas); | 554 set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas); |
555 set_allow_harmony_class_fields(FLAG_harmony_class_fields); | 555 set_allow_harmony_class_fields(FLAG_harmony_class_fields); |
556 set_allow_harmony_object_spread(FLAG_harmony_object_spread); | 556 set_allow_harmony_object_spread(FLAG_harmony_object_spread); |
| 557 set_allow_harmony_async_iteration(FLAG_harmony_async_iteration); |
557 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 558 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
558 ++feature) { | 559 ++feature) { |
559 use_counts_[feature] = 0; | 560 use_counts_[feature] = 0; |
560 } | 561 } |
561 if (info->ast_value_factory() == NULL) { | 562 if (info->ast_value_factory() == NULL) { |
562 // info takes ownership of AstValueFactory. | 563 // info takes ownership of AstValueFactory. |
563 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); | 564 info->set_ast_value_factory(new AstValueFactory(zone(), 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(); |
566 ast_node_factory_.set_ast_value_factory(ast_value_factory_); | 567 ast_node_factory_.set_ast_value_factory(ast_value_factory_); |
(...skipping 1231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1798 throw_arguments->Add(result_proxy_again, zone()); | 1799 throw_arguments->Add(result_proxy_again, zone()); |
1799 Expression* throw_call = factory()->NewCallRuntime( | 1800 Expression* throw_call = factory()->NewCallRuntime( |
1800 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos); | 1801 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos); |
1801 | 1802 |
1802 return factory()->NewBinaryOperation( | 1803 return factory()->NewBinaryOperation( |
1803 Token::AND, | 1804 Token::AND, |
1804 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos), | 1805 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos), |
1805 throw_call, pos); | 1806 throw_call, pos); |
1806 } | 1807 } |
1807 | 1808 |
| 1809 Expression* Parser::AwaitIteratorNextResult(Expression* iterator, |
| 1810 Variable* result, int pos) { |
| 1811 Expression* next_literal = factory()->NewStringLiteral( |
| 1812 ast_value_factory()->next_string(), kNoSourcePosition); |
| 1813 Expression* next_property = |
| 1814 factory()->NewProperty(iterator, next_literal, kNoSourcePosition); |
| 1815 ZoneList<Expression*>* next_arguments = |
| 1816 new (zone()) ZoneList<Expression*>(0, zone()); |
| 1817 Expression* next_call = |
| 1818 factory()->NewCall(next_property, next_arguments, pos); |
| 1819 |
| 1820 // Await(iterator.next()) |
| 1821 Expression* await_next_call = RewriteAwaitExpression(next_call, pos); |
| 1822 |
| 1823 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 1824 Expression* left = factory()->NewAssignment(Token::ASSIGN, result_proxy, |
| 1825 await_next_call, pos); |
| 1826 |
| 1827 // %_IsJSReceiver(...) |
| 1828 ZoneList<Expression*>* is_spec_object_args = |
| 1829 new (zone()) ZoneList<Expression*>(1, zone()); |
| 1830 is_spec_object_args->Add(left, zone()); |
| 1831 Expression* is_spec_object_call = factory()->NewCallRuntime( |
| 1832 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos); |
| 1833 |
| 1834 // %ThrowIteratorResultNotAnObject(result) |
| 1835 Expression* result_proxy_again = factory()->NewVariableProxy(result); |
| 1836 ZoneList<Expression*>* throw_arguments = |
| 1837 new (zone()) ZoneList<Expression*>(1, zone()); |
| 1838 throw_arguments->Add(result_proxy_again, zone()); |
| 1839 Expression* throw_call = factory()->NewCallRuntime( |
| 1840 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos); |
| 1841 |
| 1842 return factory()->NewBinaryOperation( |
| 1843 Token::AND, |
| 1844 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos), |
| 1845 throw_call, pos); |
| 1846 } |
| 1847 |
1808 Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt, | 1848 Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt, |
1809 Expression* each, | 1849 Expression* each, |
1810 Expression* subject, | 1850 Expression* subject, |
1811 Statement* body, | 1851 Statement* body, |
1812 int each_keyword_pos) { | 1852 int each_keyword_pos) { |
1813 ForOfStatement* for_of = stmt->AsForOfStatement(); | 1853 ForOfStatement* for_of = stmt->AsForOfStatement(); |
1814 if (for_of != NULL) { | 1854 if (for_of != NULL) { |
1815 const bool finalize = true; | 1855 const bool finalize = true; |
1816 return InitializeForOfStatement(for_of, each, subject, body, finalize, | 1856 return InitializeForOfStatement(for_of, each, subject, body, finalize, |
1817 each_keyword_pos); | 1857 each_keyword_pos); |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2085 block->statements()->Add(body, zone()); | 2125 block->statements()->Add(body, zone()); |
2086 block->statements()->Add(set_completion_normal, zone()); | 2126 block->statements()->Add(set_completion_normal, zone()); |
2087 body = block; | 2127 body = block; |
2088 } | 2128 } |
2089 | 2129 |
2090 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, | 2130 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, |
2091 assign_each); | 2131 assign_each); |
2092 return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of; | 2132 return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of; |
2093 } | 2133 } |
2094 | 2134 |
| 2135 Statement* Parser::InitializeForAwaitOfStatement(ForEachStatement* stmt, |
| 2136 Expression* each, |
| 2137 Expression* iterable, |
| 2138 Statement* body, bool finalize, |
| 2139 int next_result_pos) { |
| 2140 DCHECK(stmt->IsForOfStatement()); |
| 2141 ForOfStatement* for_of = stmt->AsForOfStatement(); |
| 2142 |
| 2143 // Create the auxiliary expressions needed for iterating over the iterable, |
| 2144 // and initialize the given ForOfStatement with them. |
| 2145 // If finalize is true, also instrument the loop with code that performs the |
| 2146 // proper ES6 iterator finalization. In that case, the result is not |
| 2147 // immediately a ForOfStatement. |
| 2148 |
| 2149 const int nopos = kNoSourcePosition; |
| 2150 auto avfactory = ast_value_factory(); |
| 2151 |
| 2152 Variable* iterator = NewTemporary(ast_value_factory()->dot_iterator_string()); |
| 2153 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); |
| 2154 Variable* completion = NewTemporary(avfactory->empty_string()); |
| 2155 |
| 2156 // iterator = GetIterator(iterable, async) |
| 2157 Expression* assign_iterator; |
| 2158 { |
| 2159 assign_iterator = factory()->NewAssignment( |
| 2160 Token::ASSIGN, factory()->NewVariableProxy(iterator), |
| 2161 factory()->NewGetIterator(iterable, GetIterator::kAsync, |
| 2162 iterable->position()), |
| 2163 iterable->position()); |
| 2164 } |
| 2165 |
| 2166 Expression* next_result; |
| 2167 { |
| 2168 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 2169 next_result = |
| 2170 AwaitIteratorNextResult(iterator_proxy, result, next_result_pos); |
| 2171 } |
| 2172 |
| 2173 // result.done |
| 2174 Expression* result_done; |
| 2175 { |
| 2176 Expression* done_literal = factory()->NewStringLiteral( |
| 2177 ast_value_factory()->done_string(), kNoSourcePosition); |
| 2178 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2179 result_done = |
| 2180 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition); |
| 2181 } |
| 2182 |
| 2183 // result.value |
| 2184 Expression* result_value; |
| 2185 { |
| 2186 Expression* value_literal = |
| 2187 factory()->NewStringLiteral(avfactory->value_string(), nopos); |
| 2188 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2189 result_value = factory()->NewProperty(result_proxy, value_literal, nopos); |
| 2190 } |
| 2191 |
| 2192 // {{completion = kAbruptCompletion;}} |
| 2193 Statement* set_completion_abrupt; |
| 2194 if (finalize) { |
| 2195 Expression* proxy = factory()->NewVariableProxy(completion); |
| 2196 Expression* assignment = factory()->NewAssignment( |
| 2197 Token::ASSIGN, proxy, |
| 2198 factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos); |
| 2199 |
| 2200 Block* block = factory()->NewBlock(nullptr, 1, true, nopos); |
| 2201 block->statements()->Add( |
| 2202 factory()->NewExpressionStatement(assignment, nopos), zone()); |
| 2203 set_completion_abrupt = block; |
| 2204 } |
| 2205 |
| 2206 // do { let tmp = #result_value; #set_completion_abrupt; tmp } |
| 2207 // Expression* result_value (gets overwritten) |
| 2208 if (finalize) { |
| 2209 Variable* var_tmp = NewTemporary(avfactory->empty_string()); |
| 2210 Expression* tmp = factory()->NewVariableProxy(var_tmp); |
| 2211 Expression* assignment = |
| 2212 factory()->NewAssignment(Token::ASSIGN, tmp, result_value, nopos); |
| 2213 |
| 2214 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); |
| 2215 block->statements()->Add( |
| 2216 factory()->NewExpressionStatement(assignment, nopos), zone()); |
| 2217 block->statements()->Add(set_completion_abrupt, zone()); |
| 2218 |
| 2219 result_value = factory()->NewDoExpression(block, var_tmp, nopos); |
| 2220 } |
| 2221 |
| 2222 // each = #result_value; |
| 2223 Expression* assign_each; |
| 2224 { |
| 2225 assign_each = |
| 2226 factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos); |
| 2227 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { |
| 2228 assign_each = PatternRewriter::RewriteDestructuringAssignment( |
| 2229 this, assign_each->AsAssignment(), scope()); |
| 2230 } |
| 2231 } |
| 2232 |
| 2233 // {{completion = kNormalCompletion;}} |
| 2234 Statement* set_completion_normal; |
| 2235 if (finalize) { |
| 2236 Expression* proxy = factory()->NewVariableProxy(completion); |
| 2237 Expression* assignment = factory()->NewAssignment( |
| 2238 Token::ASSIGN, proxy, |
| 2239 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); |
| 2240 |
| 2241 Block* block = factory()->NewBlock(nullptr, 1, true, nopos); |
| 2242 block->statements()->Add( |
| 2243 factory()->NewExpressionStatement(assignment, nopos), zone()); |
| 2244 set_completion_normal = block; |
| 2245 } |
| 2246 |
| 2247 // { #loop-body; #set_completion_normal } |
| 2248 // Statement* body (gets overwritten) |
| 2249 if (finalize) { |
| 2250 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); |
| 2251 block->statements()->Add(body, zone()); |
| 2252 block->statements()->Add(set_completion_normal, zone()); |
| 2253 body = block; |
| 2254 } |
| 2255 |
| 2256 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, |
| 2257 assign_each); |
| 2258 return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of; |
| 2259 } |
| 2260 |
2095 Statement* Parser::DesugarLexicalBindingsInForStatement( | 2261 Statement* Parser::DesugarLexicalBindingsInForStatement( |
2096 ForStatement* loop, Statement* init, Expression* cond, Statement* next, | 2262 ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
2097 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) { | 2263 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) { |
2098 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are | 2264 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are |
2099 // copied into a new environment. Moreover, the "next" statement must be | 2265 // copied into a new environment. Moreover, the "next" statement must be |
2100 // evaluated not in the environment of the just completed iteration but in | 2266 // evaluated not in the environment of the just completed iteration but in |
2101 // that of the upcoming one. We achieve this with the following desugaring. | 2267 // that of the upcoming one. We achieve this with the following desugaring. |
2102 // Extra care is needed to preserve the completion value of the original loop. | 2268 // Extra care is needed to preserve the completion value of the original loop. |
2103 // | 2269 // |
2104 // We are given a for statement of the form | 2270 // We are given a for statement of the form |
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2748 zone(), &scanner_, stack_limit_, ast_value_factory(), | 2914 zone(), &scanner_, stack_limit_, ast_value_factory(), |
2749 &pending_error_handler_, runtime_call_stats_, parsing_on_main_thread_); | 2915 &pending_error_handler_, runtime_call_stats_, parsing_on_main_thread_); |
2750 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); | 2916 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); |
2751 SET_ALLOW(natives); | 2917 SET_ALLOW(natives); |
2752 SET_ALLOW(harmony_do_expressions); | 2918 SET_ALLOW(harmony_do_expressions); |
2753 SET_ALLOW(harmony_function_sent); | 2919 SET_ALLOW(harmony_function_sent); |
2754 SET_ALLOW(harmony_async_await); | 2920 SET_ALLOW(harmony_async_await); |
2755 SET_ALLOW(harmony_trailing_commas); | 2921 SET_ALLOW(harmony_trailing_commas); |
2756 SET_ALLOW(harmony_class_fields); | 2922 SET_ALLOW(harmony_class_fields); |
2757 SET_ALLOW(harmony_object_spread); | 2923 SET_ALLOW(harmony_object_spread); |
| 2924 SET_ALLOW(harmony_async_iteration); |
2758 #undef SET_ALLOW | 2925 #undef SET_ALLOW |
2759 } | 2926 } |
2760 // Aborting inner function preparsing would leave scopes in an inconsistent | 2927 // Aborting inner function preparsing would leave scopes in an inconsistent |
2761 // state; we don't parse inner functions in the abortable mode anyway. | 2928 // state; we don't parse inner functions in the abortable mode anyway. |
2762 DCHECK(!is_inner_function || !may_abort); | 2929 DCHECK(!is_inner_function || !may_abort); |
2763 | 2930 |
2764 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( | 2931 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( |
2765 kind, function_scope, parsing_module_, is_inner_function, may_abort, | 2932 kind, function_scope, parsing_module_, is_inner_function, may_abort, |
2766 use_counts_); | 2933 use_counts_); |
2767 | 2934 |
(...skipping 1150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3918 // The operand needs to be evaluated on a separate statement in order to get | 4085 // The operand needs to be evaluated on a separate statement in order to get |
3919 // a break location, and the .promise needs to be read earlier so that it | 4086 // a break location, and the .promise needs to be read earlier so that it |
3920 // doesn't insert a false location. | 4087 // doesn't insert a false location. |
3921 // TODO(littledan): investigate why this ordering is needed in more detail. | 4088 // TODO(littledan): investigate why this ordering is needed in more detail. |
3922 Variable* generator_object_variable = | 4089 Variable* generator_object_variable = |
3923 function_state_->generator_object_variable(); | 4090 function_state_->generator_object_variable(); |
3924 DCHECK_NOT_NULL(generator_object_variable); | 4091 DCHECK_NOT_NULL(generator_object_variable); |
3925 | 4092 |
3926 const int nopos = kNoSourcePosition; | 4093 const int nopos = kNoSourcePosition; |
3927 | 4094 |
| 4095 if (is_async_generator()) { |
| 4096 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); |
| 4097 Expression* generator_object = |
| 4098 factory()->NewVariableProxy(generator_object_variable); |
| 4099 args->Add(generator_object, zone()); |
| 4100 args->Add(value, zone()); |
| 4101 |
| 4102 Expression* await = factory()->NewCallRuntime( |
| 4103 Context::ASYNC_GENERATOR_AWAIT_CAUGHT, args, nopos); |
| 4104 |
| 4105 return factory()->NewYield(generator_object, await, nopos, |
| 4106 Yield::kOnExceptionRethrow, Yield::kAwait); |
| 4107 } |
| 4108 |
3928 Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos); | 4109 Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos); |
3929 | 4110 |
3930 Variable* promise = PromiseVariable(); | 4111 Variable* promise = PromiseVariable(); |
3931 | 4112 |
3932 // Wrap value evaluation to provide a break location. | 4113 // Wrap value evaluation to provide a break location. |
3933 Variable* temp_var = NewTemporary(ast_value_factory()->empty_string()); | 4114 Variable* temp_var = NewTemporary(ast_value_factory()->empty_string()); |
3934 Expression* value_assignment = factory()->NewAssignment( | 4115 Expression* value_assignment = factory()->NewAssignment( |
3935 Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos); | 4116 Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos); |
3936 do_block->statements()->Add( | 4117 do_block->statements()->Add( |
3937 factory()->NewExpressionStatement(value_assignment, value->position()), | 4118 factory()->NewExpressionStatement(value_assignment, value->position()), |
(...skipping 15 matching lines...) Expand all Loading... |
3953 async_function_await_args, nopos); | 4134 async_function_await_args, nopos); |
3954 do_block->statements()->Add( | 4135 do_block->statements()->Add( |
3955 factory()->NewExpressionStatement(async_function_await, await_pos), | 4136 factory()->NewExpressionStatement(async_function_await, await_pos), |
3956 zone()); | 4137 zone()); |
3957 | 4138 |
3958 // Wrap await to provide a break location between value evaluation and yield. | 4139 // Wrap await to provide a break location between value evaluation and yield. |
3959 Expression* do_expr = factory()->NewDoExpression(do_block, promise, nopos); | 4140 Expression* do_expr = factory()->NewDoExpression(do_block, promise, nopos); |
3960 | 4141 |
3961 generator_object = factory()->NewVariableProxy(generator_object_variable); | 4142 generator_object = factory()->NewVariableProxy(generator_object_variable); |
3962 return factory()->NewYield(generator_object, do_expr, nopos, | 4143 return factory()->NewYield(generator_object, do_expr, nopos, |
3963 Yield::kOnExceptionRethrow); | 4144 Yield::kOnExceptionRethrow, Yield::kAwait); |
3964 } | 4145 } |
3965 | 4146 |
3966 class NonPatternRewriter : public AstExpressionRewriter { | 4147 class NonPatternRewriter : public AstExpressionRewriter { |
3967 public: | 4148 public: |
3968 NonPatternRewriter(uintptr_t stack_limit, Parser* parser) | 4149 NonPatternRewriter(uintptr_t stack_limit, Parser* parser) |
3969 : AstExpressionRewriter(stack_limit), parser_(parser) {} | 4150 : AstExpressionRewriter(stack_limit), parser_(parser) {} |
3970 ~NonPatternRewriter() override {} | 4151 ~NonPatternRewriter() override {} |
3971 | 4152 |
3972 private: | 4153 private: |
3973 bool RewriteExpression(Expression* expr) override { | 4154 bool RewriteExpression(Expression* expr) override { |
(...skipping 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5134 | 5315 |
5135 return final_loop; | 5316 return final_loop; |
5136 } | 5317 } |
5137 | 5318 |
5138 #undef CHECK_OK | 5319 #undef CHECK_OK |
5139 #undef CHECK_OK_VOID | 5320 #undef CHECK_OK_VOID |
5140 #undef CHECK_FAILED | 5321 #undef CHECK_FAILED |
5141 | 5322 |
5142 } // namespace internal | 5323 } // namespace internal |
5143 } // namespace v8 | 5324 } // namespace v8 |
OLD | NEW |