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

Unified Diff: src/parsing/parser-base.h

Issue 2654423004: [async-functions] support await expressions in finally statements (Closed)
Patch Set: I'd like to build with -Wunused-variables locally, but how!? 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
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/pattern-rewriter.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parsing/parser-base.h
diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
index 18366443b70c1955069e97ec1026fb9d2ce493d7..7b7d356454af04942dec6d0e350639960e38f45f 100644
--- a/src/parsing/parser-base.h
+++ b/src/parsing/parser-base.h
@@ -425,25 +425,6 @@ class ParserBase {
FunctionKind kind() const { return scope()->function_kind(); }
FunctionState* outer() const { return outer_function_state_; }
- void set_generator_object_variable(typename Types::Variable* variable) {
- DCHECK_NOT_NULL(variable);
- DCHECK(IsResumableFunction(kind()));
- DCHECK(scope()->has_forced_context_allocation());
- generator_object_variable_ = variable;
- }
- typename Types::Variable* generator_object_variable() const {
- return generator_object_variable_;
- }
-
- void set_promise_variable(typename Types::Variable* variable) {
- DCHECK(variable != NULL);
- DCHECK(IsAsyncFunction(kind()));
- promise_variable_ = variable;
- }
- typename Types::Variable* promise_variable() const {
- return promise_variable_;
- }
-
const ZoneList<DestructuringAssignment>&
destructuring_assignments_to_rewrite() const {
return destructuring_assignments_to_rewrite_;
@@ -506,14 +487,6 @@ class ParserBase {
// Properties count estimation.
int expected_property_count_;
- // For generators, this variable may hold the generator object. It variable
- // is used by yield expressions and return statements. It is not necessary
- // for generator functions to have this variable set.
- Variable* generator_object_variable_;
- // For async functions, this variable holds a temporary for the Promise
- // being created as output of the async function.
- Variable* promise_variable_;
-
FunctionState** function_state_stack_;
FunctionState* outer_function_state_;
@@ -739,6 +712,7 @@ class ParserBase {
if (!IsArrowFunction(kind)) {
result->DeclareDefaultFunctionVariables(ast_value_factory());
}
+
return result;
}
@@ -1196,9 +1170,6 @@ class ParserBase {
ExpressionT ParseArrowFunctionLiteral(bool accept_IN,
const FormalParametersT& parameters,
bool* ok);
- void ParseAsyncFunctionBody(Scope* scope, StatementListT body,
- FunctionKind kind, FunctionBodyType type,
- bool accept_IN, int pos, bool* ok);
ExpressionT ParseAsyncFunctionLiteral(bool* ok);
ExpressionT ParseClassLiteral(IdentifierT name,
Scanner::Location class_name_location,
@@ -1231,9 +1202,9 @@ class ParserBase {
StatementT ParseNativeDeclaration(bool* ok);
// Consumes the ending }.
- void ParseFunctionBody(StatementListT result, IdentifierT function_name,
- int pos, const FormalParametersT& parameters,
- FunctionKind kind,
+ void ParseFunctionBody(StatementListT result, BlockT* init_block,
+ IdentifierT function_name, int pos,
+ const FormalParametersT& parameters, FunctionKind kind,
FunctionLiteral::FunctionType function_type, bool* ok);
// Under some circumstances, we allow preparsing to abort if the preparsed
@@ -1495,8 +1466,6 @@ ParserBase<Impl>::FunctionState::FunctionState(
: ScopeState(scope_stack, scope),
next_materialized_literal_index_(0),
expected_property_count_(0),
- generator_object_variable_(nullptr),
- promise_variable_(nullptr),
function_state_stack_(function_state_stack),
outer_function_state_(*function_state_stack),
destructuring_assignments_to_rewrite_(16, scope->zone()),
@@ -2915,8 +2884,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression(
classifier()->RecordFormalParameterInitializerError(
scanner()->peek_location(), MessageTemplate::kYieldInParameter);
Expect(Token::YIELD, CHECK_OK);
- ExpressionT generator_object =
- factory()->NewVariableProxy(function_state_->generator_object_variable());
+
// The following initialization is necessary.
ExpressionT expression = impl()->EmptyExpression();
bool delegating = false; // yield*
@@ -2944,14 +2912,14 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression(
}
if (delegating) {
- return impl()->RewriteYieldStar(generator_object, expression, pos);
+ return impl()->RewriteYieldStar(expression, pos);
}
expression = impl()->BuildIteratorResult(expression, false);
// Hackily disambiguate o from o.next and o [Symbol.iterator]().
// TODO(verwaest): Come up with a better solution.
- ExpressionT yield = factory()->NewYield(generator_object, expression, pos,
- Yield::kOnExceptionThrow);
+ ExpressionT yield = factory()->NewYield(
+ expression, pos, Yield::kOnExceptionThrow, Yield::kNormal);
return yield;
}
@@ -3111,7 +3079,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression(
ExpressionT value = ParseUnaryExpression(CHECK_OK);
- return impl()->RewriteAwaitExpression(value, await_pos);
+ return factory()->NewYield(value, await_pos, Yield::kOnExceptionRethrow,
+ Yield::kAwait);
} else {
return ParsePostfixExpression(ok);
}
@@ -3945,21 +3914,10 @@ ParserBase<Impl>::ParseAsyncFunctionDeclaration(
template <typename Impl>
void ParserBase<Impl>::ParseFunctionBody(
- typename ParserBase<Impl>::StatementListT result, IdentifierT function_name,
+ typename ParserBase<Impl>::StatementListT result,
+ typename ParserBase<Impl>::BlockT* init_block, IdentifierT function_name,
int pos, const FormalParametersT& parameters, FunctionKind kind,
FunctionLiteral::FunctionType function_type, bool* ok) {
- static const int kFunctionNameAssignmentIndex = 0;
- if (function_type == FunctionLiteral::kNamedExpression) {
- DCHECK(!impl()->IsEmptyIdentifier(function_name));
- // If we have a named function expression, we add a local variable
- // declaration to the body of the function with the name of the
- // function and let it refer to the function itself (closure).
- // Not having parsed the function body, the language mode may still change,
- // so we reserve a spot and create the actual const assignment later.
- DCHECK_EQ(kFunctionNameAssignmentIndex, result->length());
- result->Add(impl()->NullStatement(), zone());
- }
-
DeclarationScope* function_scope = scope()->AsDeclarationScope();
DeclarationScope* inner_scope = function_scope;
BlockT inner_block = impl()->NullBlock();
@@ -3976,15 +3934,7 @@ void ParserBase<Impl>::ParseFunctionBody(
{
BlockState block_state(&scope_state_, inner_scope);
- if (IsGeneratorFunction(kind)) {
- impl()->ParseAndRewriteGeneratorFunctionBody(pos, kind, body, ok);
- } else if (IsAsyncFunction(kind)) {
- const bool accept_IN = true;
- ParseAsyncFunctionBody(inner_scope, body, kind, FunctionBodyType::kNormal,
- accept_IN, pos, CHECK_OK_VOID);
- } else {
- ParseStatementList(body, Token::RBRACE, CHECK_OK_VOID);
- }
+ ParseStatementList(body, Token::RBRACE, CHECK_OK_VOID);
if (IsDerivedConstructor(kind)) {
body->Add(factory()->NewReturnStatement(impl()->ThisExpression(),
@@ -4001,18 +3951,13 @@ void ParserBase<Impl>::ParseFunctionBody(
DCHECK_EQ(function_scope, scope());
DCHECK_EQ(function_scope, inner_scope->outer_scope());
impl()->SetLanguageMode(function_scope, inner_scope->language_mode());
- BlockT init_block =
+ *init_block =
impl()->BuildParameterInitializationBlock(parameters, CHECK_OK_VOID);
if (is_sloppy(inner_scope->language_mode())) {
impl()->InsertSloppyBlockFunctionVarBindings(inner_scope);
}
- // TODO(littledan): Merge the two rejection blocks into one
- if (IsAsyncFunction(kind)) {
- init_block = impl()->BuildRejectPromiseOnException(init_block);
- }
-
inner_scope->set_end_position(scanner()->location().end_pos);
if (inner_scope->FinalizeBlockScope() != nullptr) {
impl()->CheckConflictingVarDeclarations(inner_scope, CHECK_OK_VOID);
@@ -4020,7 +3965,6 @@ void ParserBase<Impl>::ParseFunctionBody(
}
inner_scope = nullptr;
- result->Add(init_block, zone());
result->Add(inner_block, zone());
} else {
DCHECK_EQ(inner_scope, function_scope);
@@ -4036,9 +3980,8 @@ void ParserBase<Impl>::ParseFunctionBody(
function_scope->DeclareArguments(ast_value_factory());
}
- impl()->CreateFunctionNameAssignment(function_name, pos, function_type,
- function_scope, result,
- kFunctionNameAssignmentIndex);
+ impl()->CreateFunctionNameVariable(function_name, pos, function_type,
+ function_scope);
impl()->MarkCollectedTailCallExpressions();
}
@@ -4136,6 +4079,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
return impl()->EmptyExpression();
}
+ BlockT parameter_init_block = impl()->NullBlock();
StatementListT body = impl()->NullStatementList();
int materialized_literal_count = -1;
int expected_property_count = -1;
@@ -4155,7 +4099,9 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
{
FunctionState function_state(&function_state_, &scope_state_,
formal_parameters.scope);
-
+ if (kind == kAsyncArrowFunction) {
+ function_state.scope()->ForceContextAllocation();
+ }
function_state.SkipMaterializedLiterals(
formal_parameters.materialized_literals_count);
@@ -4204,10 +4150,10 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
if (!is_lazy_top_level_function) {
Consume(Token::LBRACE);
body = impl()->NewStatementList(8);
- impl()->ParseFunctionBody(body, impl()->EmptyIdentifier(),
- kNoSourcePosition, formal_parameters, kind,
- FunctionLiteral::kAnonymousExpression,
- CHECK_OK);
+ impl()->ParseFunctionBody(
+ body, &parameter_init_block, impl()->EmptyIdentifier(),
+ kNoSourcePosition, formal_parameters, kind,
+ FunctionLiteral::kAnonymousExpression, CHECK_OK);
materialized_literal_count =
function_state.materialized_literal_count();
expected_property_count = function_state.expected_property_count();
@@ -4215,31 +4161,27 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
} else {
// Single-expression body
has_braces = false;
- int pos = position();
DCHECK(ReturnExprContext::kInsideValidBlock ==
function_state_->return_expr_context());
ReturnExprScope allow_tail_calls(
function_state_, ReturnExprContext::kInsideValidReturnStatement);
body = impl()->NewStatementList(1);
- impl()->AddParameterInitializationBlock(
- formal_parameters, body, kind == kAsyncArrowFunction, CHECK_OK);
+ if (!formal_parameters.is_simple) {
+ parameter_init_block = impl()->BuildParameterInitializationBlock(
+ formal_parameters, CHECK_OK);
+ }
ExpressionClassifier classifier(this);
- if (kind == kAsyncArrowFunction) {
- ParseAsyncFunctionBody(scope(), body, kAsyncArrowFunction,
- FunctionBodyType::kSingleExpression, accept_IN,
- pos, CHECK_OK);
- impl()->RewriteNonPattern(CHECK_OK);
- } else {
- ExpressionT expression = ParseAssignmentExpression(accept_IN, CHECK_OK);
- impl()->RewriteNonPattern(CHECK_OK);
- body->Add(
- factory()->NewReturnStatement(expression, expression->position()),
- zone());
- if (allow_tailcalls() && !is_sloppy(language_mode())) {
- // ES6 14.6.1 Static Semantics: IsInTailPosition
- impl()->MarkTailPosition(expression);
- }
+ ExpressionT expression = ParseAssignmentExpression(accept_IN, CHECK_OK);
+ impl()->RewriteNonPattern(CHECK_OK);
+ body->Add(
+ factory()->NewReturnStatement(expression, expression->position()),
+ zone());
+ if (allow_tailcalls() && !is_sloppy(language_mode()) &&
+ kind != kAsyncArrowFunction) {
+ // ES6 14.6.1 Static Semantics: IsInTailPosition
+ impl()->MarkTailPosition(expression);
}
+
materialized_literal_count = function_state.materialized_literal_count();
expected_property_count = function_state.expected_property_count();
impl()->MarkCollectedTailCallExpressions();
@@ -4279,6 +4221,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
FunctionLiteral::kAnonymousExpression, eager_compile_hint,
formal_parameters.scope->start_position(), has_braces,
function_literal_id);
+ function_literal->set_parameter_init_block(parameter_init_block);
function_literal->set_function_token_position(
formal_parameters.scope->start_position());
@@ -4364,31 +4307,6 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
}
template <typename Impl>
-void ParserBase<Impl>::ParseAsyncFunctionBody(Scope* scope, StatementListT body,
- FunctionKind kind,
- FunctionBodyType body_type,
- bool accept_IN, int pos,
- bool* ok) {
- impl()->PrepareAsyncFunctionBody(body, kind, pos);
-
- BlockT block = factory()->NewBlock(nullptr, 8, true, kNoSourcePosition);
-
- ExpressionT return_value = impl()->EmptyExpression();
- if (body_type == FunctionBodyType::kNormal) {
- ParseStatementList(block->statements(), Token::RBRACE,
- CHECK_OK_CUSTOM(Void));
- return_value = factory()->NewUndefinedLiteral(kNoSourcePosition);
- } else {
- return_value = ParseAssignmentExpression(accept_IN, CHECK_OK_CUSTOM(Void));
- impl()->RewriteNonPattern(CHECK_OK_CUSTOM(Void));
- }
-
- impl()->RewriteAsyncFunctionBody(body, block, return_value,
- CHECK_OK_CUSTOM(Void));
- scope->set_end_position(scanner()->location().end_pos);
-}
-
-template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) {
// AsyncFunctionLiteral ::
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/pattern-rewriter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698