[parser] Various cleanup for async function parsing

This patch removes a few unnecessary bits of async function
parsing (the PrepareAsyncFunctionBody() helper method, the
FunctionBodyType enum) by doing separate handling of
block and single-expression async arrow functions.

Change-Id: I64f837635a23eaf06d42887ca7f9ac59c768f0f2
Reviewed-on: https://chromium-review.googlesource.com/601247
Commit-Queue: Adam Klein <adamk@chromium.org>
Reviewed-by: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47169}
This commit is contained in:
Adam Klein 2017-08-04 10:15:17 -07:00 committed by Commit Bot
parent fe0323d4a4
commit 28f25699ab
4 changed files with 38 additions and 62 deletions

View File

@ -337,8 +337,6 @@ class ParserBase {
kForStatement kForStatement
}; };
enum class FunctionBodyType { kNormal, kSingleExpression };
class ClassLiteralChecker; class ClassLiteralChecker;
class ObjectLiteralChecker; class ObjectLiteralChecker;
@ -1116,9 +1114,9 @@ class ParserBase {
ExpressionT ParseArrowFunctionLiteral(bool accept_IN, ExpressionT ParseArrowFunctionLiteral(bool accept_IN,
const FormalParametersT& parameters, const FormalParametersT& parameters,
int rewritable_length, bool* ok); int rewritable_length, bool* ok);
void ParseAsyncFunctionBody(Scope* scope, StatementListT body, void ParseSingleExpressionFunctionBody(StatementListT body, bool is_async,
FunctionKind kind, FunctionBodyType type, bool accept_IN, bool* ok);
bool accept_IN, int pos, bool* ok); void ParseAsyncFunctionBody(Scope* scope, StatementListT body, bool* ok);
ExpressionT ParseAsyncFunctionLiteral(bool* ok); ExpressionT ParseAsyncFunctionLiteral(bool* ok);
ExpressionT ParseClassLiteral(IdentifierT name, ExpressionT ParseClassLiteral(IdentifierT name,
Scanner::Location class_name_location, Scanner::Location class_name_location,
@ -4053,14 +4051,14 @@ void ParserBase<Impl>::ParseFunctionBody(
{ {
BlockState block_state(&scope_, inner_scope); BlockState block_state(&scope_, inner_scope);
if (IsResumableFunction(kind)) impl()->PrepareGeneratorVariables();
if (IsAsyncGeneratorFunction(kind)) { if (IsAsyncGeneratorFunction(kind)) {
impl()->ParseAndRewriteAsyncGeneratorFunctionBody(pos, kind, body, ok); impl()->ParseAndRewriteAsyncGeneratorFunctionBody(pos, kind, body, ok);
} else if (IsGeneratorFunction(kind)) { } else if (IsGeneratorFunction(kind)) {
impl()->ParseAndRewriteGeneratorFunctionBody(pos, kind, body, ok); impl()->ParseAndRewriteGeneratorFunctionBody(pos, kind, body, ok);
} else if (IsAsyncFunction(kind)) { } else if (IsAsyncFunction(kind)) {
const bool accept_IN = true; ParseAsyncFunctionBody(inner_scope, body, CHECK_OK_VOID);
ParseAsyncFunctionBody(inner_scope, body, kind, FunctionBodyType::kNormal,
accept_IN, pos, CHECK_OK_VOID);
} else { } else {
ParseStatementList(body, Token::RBRACE, CHECK_OK_VOID); ParseStatementList(body, Token::RBRACE, CHECK_OK_VOID);
} }
@ -4264,31 +4262,19 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
} else { } else {
Consume(Token::LBRACE); Consume(Token::LBRACE);
body = impl()->NewStatementList(8); body = impl()->NewStatementList(8);
impl()->ParseFunctionBody(body, impl()->EmptyIdentifier(), ParseFunctionBody(body, impl()->EmptyIdentifier(), kNoSourcePosition,
kNoSourcePosition, formal_parameters, kind, formal_parameters, kind,
FunctionLiteral::kAnonymousExpression, FunctionLiteral::kAnonymousExpression, CHECK_OK);
CHECK_OK);
expected_property_count = function_state.expected_property_count(); expected_property_count = function_state.expected_property_count();
} }
} else { } else {
// Single-expression body // Single-expression body
has_braces = false; has_braces = false;
int pos = position(); const bool is_async = IsAsyncFunction(kind);
body = impl()->NewStatementList(1); body = impl()->NewStatementList(1);
impl()->AddParameterInitializationBlock( impl()->AddParameterInitializationBlock(formal_parameters, body, is_async,
formal_parameters, body, kind == kAsyncArrowFunction, CHECK_OK); CHECK_OK);
ExpressionClassifier classifier(this); ParseSingleExpressionFunctionBody(body, is_async, accept_IN, CHECK_OK);
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(BuildReturnStatement(expression, expression->position()),
zone());
}
expected_property_count = function_state.expected_property_count(); expected_property_count = function_state.expected_property_count();
} }
@ -4425,27 +4411,33 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
} }
template <typename Impl> template <typename Impl>
void ParserBase<Impl>::ParseAsyncFunctionBody(Scope* scope, StatementListT body, void ParserBase<Impl>::ParseSingleExpressionFunctionBody(StatementListT body,
FunctionKind kind, bool is_async,
FunctionBodyType body_type, bool accept_IN,
bool accept_IN, int pos, bool* ok) {
bool* ok) { if (is_async) impl()->PrepareGeneratorVariables();
impl()->PrepareAsyncFunctionBody(body, kind, pos);
ExpressionClassifier classifier(this);
ExpressionT expression = ParseAssignmentExpression(accept_IN, CHECK_OK_VOID);
impl()->RewriteNonPattern(CHECK_OK_VOID);
if (is_async) {
BlockT block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
impl()->RewriteAsyncFunctionBody(body, block, expression, CHECK_OK_VOID);
} else {
body->Add(BuildReturnStatement(expression, expression->position()), zone());
}
}
template <typename Impl>
void ParserBase<Impl>::ParseAsyncFunctionBody(Scope* scope, StatementListT body,
bool* ok) {
BlockT block = factory()->NewBlock(nullptr, 8, true, kNoSourcePosition); BlockT block = factory()->NewBlock(nullptr, 8, true, kNoSourcePosition);
ExpressionT return_value = impl()->EmptyExpression(); ParseStatementList(block->statements(), Token::RBRACE, CHECK_OK_VOID);
if (body_type == FunctionBodyType::kNormal) { impl()->RewriteAsyncFunctionBody(
ParseStatementList(block->statements(), Token::RBRACE, body, block, factory()->NewUndefinedLiteral(kNoSourcePosition),
CHECK_OK_CUSTOM(Void)); CHECK_OK_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); scope->set_end_position(scanner()->location().end_pos);
} }

View File

@ -3194,8 +3194,6 @@ ZoneList<Statement*>* Parser::ParseFunction(
DuplicateFinder duplicate_finder; DuplicateFinder duplicate_finder;
ExpressionClassifier formals_classifier(this, &duplicate_finder); ExpressionClassifier formals_classifier(this, &duplicate_finder);
if (IsResumableFunction(kind)) PrepareGeneratorVariables();
int expected_parameters_end_pos = parameters_end_pos_; int expected_parameters_end_pos = parameters_end_pos_;
if (expected_parameters_end_pos != kNoSourcePosition) { if (expected_parameters_end_pos != kNoSourcePosition) {
// This is the first function encountered in a CreateDynamicFunction eval. // This is the first function encountered in a CreateDynamicFunction eval.
@ -3820,17 +3818,6 @@ Expression* Parser::ExpressionListToExpression(ZoneList<Expression*>* args) {
return expr; return expr;
} }
// This method intoduces the line initializing the generator object
// when desugaring the body of async_function.
void Parser::PrepareAsyncFunctionBody(ZoneList<Statement*>* body,
FunctionKind kind, int pos) {
// When parsing an async arrow function, we get here without having called
// PrepareGeneratorVariables yet, so do it now.
if (function_state_->scope()->generator_object_var() == nullptr) {
PrepareGeneratorVariables();
}
}
// This method completes the desugaring of the body of async_function. // This method completes the desugaring of the body of async_function.
void Parser::RewriteAsyncFunctionBody(ZoneList<Statement*>* body, Block* block, void Parser::RewriteAsyncFunctionBody(ZoneList<Statement*>* body, Block* block,
Expression* return_value, bool* ok) { Expression* return_value, bool* ok) {

View File

@ -685,8 +685,6 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
IteratorType type); IteratorType type);
Statement* CheckCallable(Variable* var, Expression* error, int pos); Statement* CheckCallable(Variable* var, Expression* error, int pos);
V8_INLINE void PrepareAsyncFunctionBody(ZoneList<Statement*>* body,
FunctionKind kind, int pos);
V8_INLINE void RewriteAsyncFunctionBody(ZoneList<Statement*>* body, V8_INLINE void RewriteAsyncFunctionBody(ZoneList<Statement*>* body,
Block* block, Block* block,
Expression* return_value, bool* ok); Expression* return_value, bool* ok);

View File

@ -1026,8 +1026,7 @@ class PreParser : public ParserBase<PreParser> {
return left; return left;
} }
V8_INLINE void PrepareAsyncFunctionBody(PreParserStatementList body, V8_INLINE void PrepareGeneratorVariables() {}
FunctionKind kind, int pos) {}
V8_INLINE void RewriteAsyncFunctionBody(PreParserStatementList body, V8_INLINE void RewriteAsyncFunctionBody(PreParserStatementList body,
PreParserStatement block, PreParserStatement block,
PreParserExpression return_value, PreParserExpression return_value,