| Index: src/parsing/parser-base.h
|
| diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
|
| index cde95076a598852d1853db5714eda550ed173b8c..3a0dbc8cf65307750c90c91f756474a8a9d56e8a 100644
|
| --- a/src/parsing/parser-base.h
|
| +++ b/src/parsing/parser-base.h
|
| @@ -36,6 +36,10 @@ enum class ParseFunctionFlags {
|
| kIsDefault = 4
|
| };
|
|
|
| +enum class FunctionBody { Normal, SingleExpression };
|
| +
|
| +enum class FunctionParsePhase { Unknown, FormalParameters, FunctionBody };
|
| +
|
| static inline ParseFunctionFlags operator|(ParseFunctionFlags lhs,
|
| ParseFunctionFlags rhs) {
|
| typedef unsigned char T;
|
| @@ -313,14 +317,26 @@ class ParserBase : public Traits {
|
|
|
| bool is_generator() const { return IsGeneratorFunction(kind_); }
|
| bool is_async_function() const { return IsAsyncFunction(kind_); }
|
| + bool is_resumable() const { return is_generator() || is_async_function(); }
|
|
|
| FunctionKind kind() const { return kind_; }
|
| FunctionState* outer() const { return outer_function_state_; }
|
|
|
| + bool is_async_function_body() const {
|
| + return is_async_function() &&
|
| + parse_phase() == FunctionParsePhase::FunctionBody;
|
| + }
|
| +
|
| + FunctionParsePhase parse_phase() const { return parse_phase_; }
|
| +
|
| + void set_parse_phase(FunctionParsePhase parse_phase) {
|
| + parse_phase_ = parse_phase;
|
| + }
|
| +
|
| void set_generator_object_variable(
|
| typename Traits::Type::GeneratorVariable* variable) {
|
| DCHECK(variable != NULL);
|
| - DCHECK(is_generator());
|
| + DCHECK(is_resumable());
|
| generator_object_variable_ = variable;
|
| }
|
| typename Traits::Type::GeneratorVariable* generator_object_variable()
|
| @@ -426,6 +442,8 @@ class ParserBase : public Traits {
|
| // to this function. Filled in by constructor.
|
| bool this_function_is_parenthesized_;
|
|
|
| + FunctionParsePhase parse_phase_ = FunctionParsePhase::Unknown;
|
| +
|
| friend class ParserTraits;
|
| friend class PreParserTraits;
|
| friend class Checkpoint;
|
| @@ -721,6 +739,7 @@ class ParserBase : public Traits {
|
| bool is_async_function() const {
|
| return function_state_->is_async_function();
|
| }
|
| + bool is_resumable() const { return function_state_->is_resumable(); }
|
|
|
| // Report syntax errors.
|
| void ReportMessage(MessageTemplate::Template message, const char* arg = NULL,
|
| @@ -2174,8 +2193,9 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
|
| ValidateFormalParameterInitializer(&arrow_formals_classifier, ok);
|
|
|
| Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
|
| - Scope* scope =
|
| - this->NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction);
|
| + Scope* scope = this->NewScope(scope_, FUNCTION_SCOPE,
|
| + is_async ? FunctionKind::kAsyncArrowFunction
|
| + : FunctionKind::kArrowFunction);
|
| // Because the arrow's parameters were parsed in the outer scope, any
|
| // usage flags that might have been triggered there need to be copied
|
| // to the arrow scope.
|
| @@ -2610,10 +2630,14 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
|
| Consume(Token::AWAIT);
|
|
|
| ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK);
|
| - classifier->RecordFormalParameterInitializerError(
|
| - Scanner::Location(beg_pos, scanner()->location().end_pos),
|
| - MessageTemplate::kAwaitExpressionFormalParameter);
|
| -
|
| + if (!function_state_->is_async_function_body()) {
|
| + // Not currently parsing function body --- must have occurred within
|
| + // formal parameter parsing.
|
| + ReportMessageAt(Scanner::Location(beg_pos, scanner()->location().end_pos),
|
| + MessageTemplate::kAwaitExpressionFormalParameter);
|
| + *ok = false;
|
| + return this->EmptyExpression();
|
| + }
|
| return Traits::RewriteAwaitExpression(value, beg_pos);
|
| } else {
|
| return this->ParsePostfixExpression(classifier, ok);
|
| @@ -3211,11 +3235,12 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
|
| int expected_property_count = -1;
|
| Scanner::Location super_loc;
|
|
|
| + FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction;
|
| {
|
| typename Traits::Type::Factory function_factory(ast_value_factory());
|
| - FunctionState function_state(
|
| - &function_state_, &scope_, formal_parameters.scope,
|
| - is_async ? kAsyncArrowFunction : kArrowFunction, &function_factory);
|
| + FunctionState function_state(&function_state_, &scope_,
|
| + formal_parameters.scope, arrow_kind,
|
| + &function_factory);
|
|
|
| function_state.SkipMaterializedLiterals(
|
| formal_parameters.materialized_literals_count);
|
| @@ -3223,6 +3248,7 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
|
| this->ReindexLiterals(formal_parameters);
|
|
|
| Expect(Token::ARROW, CHECK_OK);
|
| + function_state.set_parse_phase(FunctionParsePhase::FunctionBody);
|
|
|
| if (peek() == Token::LBRACE) {
|
| // Multiple statement body
|
| @@ -3240,7 +3266,7 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
|
| } else {
|
| body = this->ParseEagerFunctionBody(
|
| this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters,
|
| - kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK);
|
| + arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK);
|
| materialized_literal_count =
|
| function_state.materialized_literal_count();
|
| expected_property_count = function_state.expected_property_count();
|
| @@ -3253,18 +3279,25 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
|
| function_state_->return_expr_context());
|
| ReturnExprScope allow_tail_calls(
|
| function_state_, ReturnExprContext::kInsideValidReturnStatement);
|
| - ExpressionT expression =
|
| - ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK);
|
| - Traits::RewriteNonPattern(&classifier, CHECK_OK);
|
| body = this->NewStatementList(1, zone());
|
| - this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK);
|
| - body->Add(factory()->NewReturnStatement(expression, pos), zone());
|
| + this->AddParameterInitializationBlock(formal_parameters, body, is_async,
|
| + CHECK_OK);
|
| + if (is_async) {
|
| + this->ParseAsyncArrowSingleExpressionBody(body, accept_IN, &classifier,
|
| + pos, CHECK_OK);
|
| + Traits::RewriteNonPattern(&classifier, CHECK_OK);
|
| + } else {
|
| + ExpressionT expression =
|
| + ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK);
|
| + Traits::RewriteNonPattern(&classifier, CHECK_OK);
|
| + body->Add(factory()->NewReturnStatement(expression, pos), zone());
|
| + if (allow_tailcalls() && !is_sloppy(language_mode())) {
|
| + // ES6 14.6.1 Static Semantics: IsInTailPosition
|
| + this->MarkTailPosition(expression);
|
| + }
|
| + }
|
| materialized_literal_count = function_state.materialized_literal_count();
|
| expected_property_count = function_state.expected_property_count();
|
| - if (allow_tailcalls() && !is_sloppy(language_mode())) {
|
| - // ES6 14.6.1 Static Semantics: IsInTailPosition
|
| - this->MarkTailPosition(expression);
|
| - }
|
| this->MarkCollectedTailCallExpressions();
|
| }
|
| super_loc = function_state.super_location();
|
| @@ -3294,7 +3327,7 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
|
| materialized_literal_count, expected_property_count, num_parameters,
|
| FunctionLiteral::kNoDuplicateParameters,
|
| FunctionLiteral::kAnonymousExpression,
|
| - FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction,
|
| + FunctionLiteral::kShouldLazyCompile, arrow_kind,
|
| formal_parameters.scope->start_position());
|
|
|
| function_literal->set_function_token_position(
|
|
|