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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: src/parsing/parser.cc
diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc
index ecde4f28831eced822e4e9d7a25b9a0293407fef..1aeccd65c7661126ea8676618a28275e6f1415ea 100644
--- a/src/parsing/parser.cc
+++ b/src/parsing/parser.cc
@@ -554,6 +554,7 @@ Parser::Parser(ParseInfo* info)
set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas);
set_allow_harmony_class_fields(FLAG_harmony_class_fields);
set_allow_harmony_object_spread(FLAG_harmony_object_spread);
+ set_allow_harmony_async_iteration(FLAG_harmony_async_iteration);
for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
++feature) {
use_counts_[feature] = 0;
@@ -2092,6 +2093,134 @@ Statement* Parser::InitializeForOfStatement(ForOfStatement* for_of,
return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of;
}
+Statement* Parser::InitializeForAwaitOfStatement(ForEachStatement* stmt,
+ Expression* each,
+ Expression* iterable,
+ Statement* body, bool finalize,
+ int next_result_pos) {
+ DCHECK(stmt->IsForOfStatement());
+ ForOfStatement* for_of = stmt->AsForOfStatement();
+
+ // Create the auxiliary expressions needed for iterating over the iterable,
+ // and initialize the given ForOfStatement with them.
+ // If finalize is true, also instrument the loop with code that performs the
+ // proper ES6 iterator finalization. In that case, the result is not
+ // immediately a ForOfStatement.
+
+ const int nopos = kNoSourcePosition;
+ auto avfactory = ast_value_factory();
+
+ Variable* iterator = NewTemporary(ast_value_factory()->dot_iterator_string());
+ Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
+ Variable* completion = NewTemporary(avfactory->empty_string());
+
+ // iterator = iterable[Symbol.iterator]()
+ Expression* assign_iterator;
+ {
+ assign_iterator = factory()->NewAssignment(
+ Token::ASSIGN, factory()->NewVariableProxy(iterator),
+ factory()->NewGetIterator(iterable, GetIterator::kAsync,
+ iterable->position()),
+ iterable->position());
+ }
+
+ // !%_IsJSReceiver(result = iterator.next()) &&
+ // %ThrowIteratorResultNotAnObject(result)
+ Expression* next_result;
+ {
+ Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
+ next_result =
+ BuildIteratorNextResult(iterator_proxy, result, next_result_pos);
+ }
+
+ // result.done
+ Expression* result_done;
+ {
+ Expression* done_literal = factory()->NewStringLiteral(
+ ast_value_factory()->done_string(), kNoSourcePosition);
+ Expression* result_proxy = factory()->NewVariableProxy(result);
+ result_done =
+ factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition);
+ }
+
+ // result.value
+ Expression* result_value;
+ {
+ Expression* value_literal =
+ factory()->NewStringLiteral(avfactory->value_string(), nopos);
+ Expression* result_proxy = factory()->NewVariableProxy(result);
+ result_value = factory()->NewProperty(result_proxy, value_literal, nopos);
+ }
+
+ // {{completion = kAbruptCompletion;}}
+ Statement* set_completion_abrupt;
+ if (finalize) {
+ Expression* proxy = factory()->NewVariableProxy(completion);
+ Expression* assignment = factory()->NewAssignment(
+ Token::ASSIGN, proxy,
+ factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
+
+ Block* block = factory()->NewBlock(nullptr, 1, true, nopos);
+ block->statements()->Add(
+ factory()->NewExpressionStatement(assignment, nopos), zone());
+ set_completion_abrupt = block;
+ }
+
+ // do { let tmp = #result_value; #set_completion_abrupt; tmp }
+ // Expression* result_value (gets overwritten)
+ if (finalize) {
+ Variable* var_tmp = NewTemporary(avfactory->empty_string());
+ Expression* tmp = factory()->NewVariableProxy(var_tmp);
+ Expression* assignment =
+ factory()->NewAssignment(Token::ASSIGN, tmp, result_value, nopos);
+
+ Block* block = factory()->NewBlock(nullptr, 2, false, nopos);
+ block->statements()->Add(
+ factory()->NewExpressionStatement(assignment, nopos), zone());
+ block->statements()->Add(set_completion_abrupt, zone());
+
+ result_value = factory()->NewDoExpression(block, var_tmp, nopos);
+ }
+
+ // each = #result_value;
+ Expression* assign_each;
+ {
+ assign_each =
+ factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos);
+ if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
+ assign_each = PatternRewriter::RewriteDestructuringAssignment(
+ this, assign_each->AsAssignment(), scope());
+ }
+ }
+
+ // {{completion = kNormalCompletion;}}
+ Statement* set_completion_normal;
+ if (finalize) {
+ Expression* proxy = factory()->NewVariableProxy(completion);
+ Expression* assignment = factory()->NewAssignment(
+ Token::ASSIGN, proxy,
+ factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
+
+ Block* block = factory()->NewBlock(nullptr, 1, true, nopos);
+ block->statements()->Add(
+ factory()->NewExpressionStatement(assignment, nopos), zone());
+ set_completion_normal = block;
+ }
+
+ // { #loop-body; #set_completion_normal }
+ // Statement* body (gets overwritten)
+ if (finalize) {
+ Block* block = factory()->NewBlock(nullptr, 2, false, nopos);
+ block->statements()->Add(body, zone());
+ block->statements()->Add(set_completion_normal, zone());
+ body = block;
+ }
+
+ for_of->Initialize(body, iterator, assign_iterator, next_result, result_done,
+ assign_each);
+ return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of;
+}
+
Statement* Parser::DesugarLexicalBindingsInForStatement(
ForStatement* loop, Statement* init, Expression* cond, Statement* next,
Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) {
@@ -3925,6 +4054,20 @@ Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) {
const int nopos = kNoSourcePosition;
+ if (is_async_generator()) {
+ ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
+ Expression* generator_object =
+ factory()->NewVariableProxy(generator_object_variable);
+ args->Add(generator_object, zone());
+ args->Add(value, zone());
+
+ Expression* await = factory()->NewCallRuntime(
+ Context::ASYNC_GENERATOR_AWAIT_CAUGHT, args, nopos);
+
+ return factory()->NewYield(generator_object, await, nopos,
+ Yield::kOnExceptionRethrow, Yield::kAwait);
+ }
+
Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos);
Variable* promise = PromiseVariable();
@@ -3960,7 +4103,7 @@ Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) {
generator_object = factory()->NewVariableProxy(generator_object_variable);
return factory()->NewYield(generator_object, do_expr, nopos,
- Yield::kOnExceptionRethrow);
+ Yield::kOnExceptionRethrow, Yield::kAwait);
}
class NonPatternRewriter : public AstExpressionRewriter {

Powered by Google App Engine
This is Rietveld 408576698