Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(124)

Side by Side Diff: src/parsing/parser.cc

Issue 2622833002: WIP [esnext] implement async iteration proposal (Closed)
Patch Set: Make (most of) for-await-of work (no IteratorClose yet..) Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698