[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:
parent
fe0323d4a4
commit
28f25699ab
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user