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

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

Issue 2622833002: WIP [esnext] implement async iteration proposal (Closed)
Patch Set: 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 1518 matching lines...) Expand 10 before | Expand all | Expand 10 after
2085 block->statements()->Add(body, zone()); 2086 block->statements()->Add(body, zone());
2086 block->statements()->Add(set_completion_normal, zone()); 2087 block->statements()->Add(set_completion_normal, zone());
2087 body = block; 2088 body = block;
2088 } 2089 }
2089 2090
2090 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, 2091 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done,
2091 assign_each); 2092 assign_each);
2092 return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of; 2093 return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of;
2093 } 2094 }
2094 2095
2096 Statement* Parser::InitializeForAwaitOfStatement(ForEachStatement* stmt,
2097 Expression* each,
2098 Expression* iterable,
2099 Statement* body, bool finalize,
2100 int next_result_pos) {
2101 DCHECK(stmt->IsForOfStatement());
2102 ForOfStatement* for_of = stmt->AsForOfStatement();
2103
2104 // Create the auxiliary expressions needed for iterating over the iterable,
2105 // and initialize the given ForOfStatement with them.
2106 // If finalize is true, also instrument the loop with code that performs the
2107 // proper ES6 iterator finalization. In that case, the result is not
2108 // immediately a ForOfStatement.
2109
2110 const int nopos = kNoSourcePosition;
2111 auto avfactory = ast_value_factory();
2112
2113 Variable* iterator = NewTemporary(ast_value_factory()->dot_iterator_string());
2114 Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
2115 Variable* completion = NewTemporary(avfactory->empty_string());
2116
2117 // iterator = iterable[Symbol.iterator]()
2118 Expression* assign_iterator;
2119 {
2120 assign_iterator = factory()->NewAssignment(
2121 Token::ASSIGN, factory()->NewVariableProxy(iterator),
2122 factory()->NewGetIterator(iterable, GetIterator::kAsync,
2123 iterable->position()),
2124 iterable->position());
2125 }
2126
2127 // !%_IsJSReceiver(result = iterator.next()) &&
2128 // %ThrowIteratorResultNotAnObject(result)
2129 Expression* next_result;
2130 {
2131 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
2132 next_result =
2133 BuildIteratorNextResult(iterator_proxy, result, 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, nopos) : for_of;
2222 }
2223
2095 Statement* Parser::DesugarLexicalBindingsInForStatement( 2224 Statement* Parser::DesugarLexicalBindingsInForStatement(
2096 ForStatement* loop, Statement* init, Expression* cond, Statement* next, 2225 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
2097 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) { 2226 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 2227 // 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 2228 // copied into a new environment. Moreover, the "next" statement must be
2100 // evaluated not in the environment of the just completed iteration but in 2229 // 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. 2230 // 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. 2231 // Extra care is needed to preserve the completion value of the original loop.
2103 // 2232 //
2104 // We are given a for statement of the form 2233 // We are given a for statement of the form
(...skipping 1813 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 4047 // 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 4048 // a break location, and the .promise needs to be read earlier so that it
3920 // doesn't insert a false location. 4049 // doesn't insert a false location.
3921 // TODO(littledan): investigate why this ordering is needed in more detail. 4050 // TODO(littledan): investigate why this ordering is needed in more detail.
3922 Variable* generator_object_variable = 4051 Variable* generator_object_variable =
3923 function_state_->generator_object_variable(); 4052 function_state_->generator_object_variable();
3924 DCHECK_NOT_NULL(generator_object_variable); 4053 DCHECK_NOT_NULL(generator_object_variable);
3925 4054
3926 const int nopos = kNoSourcePosition; 4055 const int nopos = kNoSourcePosition;
3927 4056
4057 if (is_async_generator()) {
4058 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
4059 Expression* generator_object =
4060 factory()->NewVariableProxy(generator_object_variable);
4061 args->Add(generator_object, zone());
4062 args->Add(value, zone());
4063
4064 Expression* await = factory()->NewCallRuntime(
4065 Context::ASYNC_GENERATOR_AWAIT_CAUGHT, args, nopos);
4066
4067 return factory()->NewYield(generator_object, await, nopos,
4068 Yield::kOnExceptionRethrow, Yield::kAwait);
4069 }
4070
3928 Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos); 4071 Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos);
3929 4072
3930 Variable* promise = PromiseVariable(); 4073 Variable* promise = PromiseVariable();
3931 4074
3932 // Wrap value evaluation to provide a break location. 4075 // Wrap value evaluation to provide a break location.
3933 Variable* temp_var = NewTemporary(ast_value_factory()->empty_string()); 4076 Variable* temp_var = NewTemporary(ast_value_factory()->empty_string());
3934 Expression* value_assignment = factory()->NewAssignment( 4077 Expression* value_assignment = factory()->NewAssignment(
3935 Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos); 4078 Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos);
3936 do_block->statements()->Add( 4079 do_block->statements()->Add(
3937 factory()->NewExpressionStatement(value_assignment, value->position()), 4080 factory()->NewExpressionStatement(value_assignment, value->position()),
(...skipping 15 matching lines...) Expand all
3953 async_function_await_args, nopos); 4096 async_function_await_args, nopos);
3954 do_block->statements()->Add( 4097 do_block->statements()->Add(
3955 factory()->NewExpressionStatement(async_function_await, await_pos), 4098 factory()->NewExpressionStatement(async_function_await, await_pos),
3956 zone()); 4099 zone());
3957 4100
3958 // Wrap await to provide a break location between value evaluation and yield. 4101 // Wrap await to provide a break location between value evaluation and yield.
3959 Expression* do_expr = factory()->NewDoExpression(do_block, promise, nopos); 4102 Expression* do_expr = factory()->NewDoExpression(do_block, promise, nopos);
3960 4103
3961 generator_object = factory()->NewVariableProxy(generator_object_variable); 4104 generator_object = factory()->NewVariableProxy(generator_object_variable);
3962 return factory()->NewYield(generator_object, do_expr, nopos, 4105 return factory()->NewYield(generator_object, do_expr, nopos,
3963 Yield::kOnExceptionRethrow); 4106 Yield::kOnExceptionRethrow, Yield::kAwait);
3964 } 4107 }
3965 4108
3966 class NonPatternRewriter : public AstExpressionRewriter { 4109 class NonPatternRewriter : public AstExpressionRewriter {
3967 public: 4110 public:
3968 NonPatternRewriter(uintptr_t stack_limit, Parser* parser) 4111 NonPatternRewriter(uintptr_t stack_limit, Parser* parser)
3969 : AstExpressionRewriter(stack_limit), parser_(parser) {} 4112 : AstExpressionRewriter(stack_limit), parser_(parser) {}
3970 ~NonPatternRewriter() override {} 4113 ~NonPatternRewriter() override {}
3971 4114
3972 private: 4115 private:
3973 bool RewriteExpression(Expression* expr) override { 4116 bool RewriteExpression(Expression* expr) override {
(...skipping 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after
5134 5277
5135 return final_loop; 5278 return final_loop;
5136 } 5279 }
5137 5280
5138 #undef CHECK_OK 5281 #undef CHECK_OK
5139 #undef CHECK_OK_VOID 5282 #undef CHECK_OK_VOID
5140 #undef CHECK_FAILED 5283 #undef CHECK_FAILED
5141 5284
5142 } // namespace internal 5285 } // namespace internal
5143 } // namespace v8 5286 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698