diff options
author | Michaël Zasso <targos@protonmail.com> | 2018-03-07 08:54:53 +0100 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2018-03-07 16:48:52 +0100 |
commit | 88786fecff336342a56e6f2e7ff3b286be716e47 (patch) | |
tree | 92e6ba5b8ac8dae1a058988d20c9d27bfa654390 /deps/v8/src/parsing/parser-base.h | |
parent | 4e86f9b5ab83cbabf43839385bf383e6a7ef7d19 (diff) | |
download | android-node-v8-88786fecff336342a56e6f2e7ff3b286be716e47.tar.gz android-node-v8-88786fecff336342a56e6f2e7ff3b286be716e47.tar.bz2 android-node-v8-88786fecff336342a56e6f2e7ff3b286be716e47.zip |
deps: update V8 to 6.5.254.31
PR-URL: https://github.com/nodejs/node/pull/18453
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Diffstat (limited to 'deps/v8/src/parsing/parser-base.h')
-rw-r--r-- | deps/v8/src/parsing/parser-base.h | 387 |
1 files changed, 214 insertions, 173 deletions
diff --git a/deps/v8/src/parsing/parser-base.h b/deps/v8/src/parsing/parser-base.h index c393bc5ec2..faefe44011 100644 --- a/deps/v8/src/parsing/parser-base.h +++ b/deps/v8/src/parsing/parser-base.h @@ -279,9 +279,11 @@ class ParserBase { allow_harmony_do_expressions_(false), allow_harmony_function_sent_(false), allow_harmony_public_fields_(false), + allow_harmony_static_fields_(false), allow_harmony_dynamic_import_(false), allow_harmony_import_meta_(false), - allow_harmony_async_iteration_(false) {} + allow_harmony_optional_catch_binding_(false), + allow_harmony_private_fields_(false) {} #define ALLOW_ACCESSORS(name) \ bool allow_##name() const { return allow_##name##_; } \ @@ -291,9 +293,10 @@ class ParserBase { ALLOW_ACCESSORS(harmony_do_expressions); ALLOW_ACCESSORS(harmony_function_sent); ALLOW_ACCESSORS(harmony_public_fields); + ALLOW_ACCESSORS(harmony_static_fields); ALLOW_ACCESSORS(harmony_dynamic_import); ALLOW_ACCESSORS(harmony_import_meta); - ALLOW_ACCESSORS(harmony_async_iteration); + ALLOW_ACCESSORS(harmony_optional_catch_binding); #undef ALLOW_ACCESSORS @@ -304,6 +307,13 @@ class ParserBase { scanner()->set_allow_harmony_bigint(allow); } + bool allow_harmony_private_fields() const { + return scanner()->allow_harmony_private_fields(); + } + void set_allow_harmony_private_fields(bool allow) { + scanner()->set_allow_harmony_private_fields(allow); + } + uintptr_t stack_limit() const { return stack_limit_; } void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } @@ -383,18 +393,27 @@ class ParserBase { void AddProperty() { expected_property_count_++; } int expected_property_count() { return expected_property_count_; } + void DisableOptimization(BailoutReason reason) { + dont_optimize_reason_ = reason; + } + BailoutReason dont_optimize_reason() { return dont_optimize_reason_; } + FunctionKind kind() const { return scope()->function_kind(); } - FunctionState* outer() const { return outer_function_state_; } void RewindDestructuringAssignments(int pos) { destructuring_assignments_to_rewrite_.Rewind(pos); } - void SetDestructuringAssignmentsScope(int pos, Scope* scope) { - for (int i = pos; i < destructuring_assignments_to_rewrite_.length(); - ++i) { - destructuring_assignments_to_rewrite_[i]->set_scope(scope); + void AdoptDestructuringAssignmentsFromParentState(int pos) { + const auto& outer_assignments = + outer_function_state_->destructuring_assignments_to_rewrite_; + DCHECK_GE(outer_assignments.length(), pos); + for (int i = pos; i < outer_assignments.length(); ++i) { + auto expr = outer_assignments[i]; + expr->set_scope(scope_); + destructuring_assignments_to_rewrite_.Add(expr, scope_->zone()); } + outer_function_state_->RewindDestructuringAssignments(pos); } const ZoneList<RewritableExpressionT>& @@ -451,14 +470,6 @@ class ParserBase { destructuring_assignments_to_rewrite_.Add(expr, scope_->zone()); } - void AddNonPatternForRewriting(RewritableExpressionT expr, bool* ok) { - non_patterns_to_rewrite_.Add(expr, scope_->zone()); - if (non_patterns_to_rewrite_.length() >= - std::numeric_limits<uint16_t>::max()) { - *ok = false; - } - } - // Properties count estimation. int expected_property_count_; @@ -471,6 +482,9 @@ class ParserBase { ZoneList<typename ExpressionClassifier::Error> reported_errors_; + // A reason, if any, why this function should not be optimized. + BailoutReason dont_optimize_reason_; + // Record whether the next (=== immediately following) function literal is // preceded by a parenthesis / exclamation mark. Also record the previous // state. @@ -1078,10 +1092,8 @@ class ParserBase { return ParsePrimaryExpression(&is_async, ok); } - // This method wraps the parsing of the expression inside a new expression - // classifier and calls RewriteNonPattern if parsing is successful. - // It should be used whenever we're parsing an expression that is known - // to not be a pattern or part of a pattern. + // Use when parsing an expression that is known to not be a pattern or part + // of a pattern. V8_INLINE ExpressionT ParseExpression(bool accept_IN, bool* ok); // This method does not wrap the parsing of the expression inside a @@ -1201,14 +1213,15 @@ class ParserBase { // by value. The method is expected to add the parsed statements to the // list. This works because in the case of the parser, StatementListT is // a pointer whereas the preparser does not really modify the body. - V8_INLINE void ParseStatementList(StatementListT body, int end_token, + V8_INLINE void ParseStatementList(StatementListT body, Token::Value end_token, bool* ok) { LazyParsingResult result = ParseStatementList(body, end_token, false, ok); USE(result); DCHECK_EQ(result, kLazyParsingComplete); } - LazyParsingResult ParseStatementList(StatementListT body, int end_token, - bool may_abort, bool* ok); + LazyParsingResult ParseStatementList(StatementListT body, + Token::Value end_token, bool may_abort, + bool* ok); StatementT ParseStatementListItem(bool* ok); StatementT ParseStatement(ZoneList<const AstRawString*>* labels, bool* ok) { return ParseStatement(labels, kDisallowLabelledFunctionStatement, ok); @@ -1463,21 +1476,18 @@ class ParserBase { // Accumulates the classifier that is on top of the stack (inner) to // the one that is right below (outer) and pops the inner. - V8_INLINE void Accumulate(unsigned productions, - bool merge_non_patterns = true) { + V8_INLINE void Accumulate(unsigned productions) { DCHECK_NOT_NULL(classifier_); ExpressionClassifier* previous = classifier_->previous(); DCHECK_NOT_NULL(previous); - previous->Accumulate(classifier_, productions, merge_non_patterns); + previous->Accumulate(classifier_, productions); classifier_ = previous; } V8_INLINE void AccumulateNonBindingPatternErrors() { - static const bool kMergeNonPatterns = true; this->Accumulate(ExpressionClassifier::AllProductions & - ~(ExpressionClassifier::BindingPatternProduction | - ExpressionClassifier::LetPatternProduction), - kMergeNonPatterns); + ~(ExpressionClassifier::BindingPatternProduction | + ExpressionClassifier::LetPatternProduction)); } // Pops and discards the classifier that is on top of the stack @@ -1534,9 +1544,11 @@ class ParserBase { bool allow_harmony_do_expressions_; bool allow_harmony_function_sent_; bool allow_harmony_public_fields_; + bool allow_harmony_static_fields_; bool allow_harmony_dynamic_import_; bool allow_harmony_import_meta_; - bool allow_harmony_async_iteration_; + bool allow_harmony_optional_catch_binding_; + bool allow_harmony_private_fields_; friend class DiscardableZoneScope; }; @@ -1553,6 +1565,7 @@ ParserBase<Impl>::FunctionState::FunctionState( destructuring_assignments_to_rewrite_(16, scope->zone()), non_patterns_to_rewrite_(0, scope->zone()), reported_errors_(16, scope->zone()), + dont_optimize_reason_(BailoutReason::kNoReason), next_function_is_likely_called_(false), previous_function_was_likely_called_(false), contains_function_or_eval_(false) { @@ -1587,6 +1600,7 @@ void ParserBase<Impl>::GetUnexpectedTokenMessage( case Token::STRING: *message = MessageTemplate::kUnexpectedTokenString; break; + case Token::PRIVATE_NAME: case Token::IDENTIFIER: *message = MessageTemplate::kUnexpectedTokenIdentifier; break; @@ -1664,6 +1678,13 @@ ParserBase<Impl>::ParseAndClassifyIdentifier(bool* ok) { if (next == Token::IDENTIFIER || next == Token::ASYNC || (next == Token::AWAIT && !parsing_module_ && !is_async_function())) { IdentifierT name = impl()->GetSymbol(); + + if (impl()->IsArguments(name) && scope()->ShouldBanArguments()) { + ReportMessage(MessageTemplate::kArgumentsDisallowedInInitializer); + *ok = false; + return impl()->NullIdentifier(); + } + // When this function is used to read a formal parameter, we don't always // know whether the function is going to be strict or sloppy. Indeed for // arrow functions we don't always know that the identifier we are reading @@ -1942,7 +1963,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( bool accept_IN, bool* ok) { ExpressionClassifier classifier(this); ExpressionT result = ParseExpressionCoverGrammar(accept_IN, CHECK_OK); - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); return result; } @@ -2068,22 +2089,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral( } Expect(Token::RBRACK, CHECK_OK); - ExpressionT result = - factory()->NewArrayLiteral(values, first_spread_index, pos); - if (first_spread_index >= 0) { - auto rewritable = factory()->NewRewritableExpression(result, scope()); - impl()->QueueNonPatternForRewriting(rewritable, ok); - if (!*ok) { - // If the non-pattern rewriting mechanism is used in the future for - // rewriting other things than spreads, this error message will have - // to change. Also, this error message will never appear while pre- - // parsing (this is OK, as it is an implementation limitation). - ReportMessage(MessageTemplate::kTooManySpreads); - return impl()->NullExpression(); - } - result = rewritable; - } - return result; + return factory()->NewArrayLiteral(values, first_spread_index, pos); } template <class Impl> @@ -2108,6 +2114,9 @@ bool ParserBase<Impl>::SetPropertyKindFromToken(Token::Value token, case Token::SEMICOLON: *kind = PropertyKind::kClassField; return true; + case Token::PRIVATE_NAME: + *kind = PropertyKind::kClassField; + return true; default: break; } @@ -2137,8 +2146,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName( !scanner()->HasAnyLineTerminatorAfterNext()) { Consume(Token::ASYNC); token = peek(); - if (token == Token::MUL && allow_harmony_async_iteration() && - !scanner()->HasAnyLineTerminatorBeforeNext()) { + if (token == Token::MUL && !scanner()->HasAnyLineTerminatorBeforeNext()) { Consume(Token::MUL); token = peek(); *is_generator = true; @@ -2198,7 +2206,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName( Consume(Token::LBRACK); ExpressionClassifier computed_name_classifier(this); expression = ParseAssignmentExpression(true, CHECK_OK); - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); AccumulateFormalParameterContainmentErrors(); Expect(Token::RBRACK, CHECK_OK); break; @@ -2270,6 +2278,8 @@ ParserBase<Impl>::ParseClassPropertyDefinition( PropertyKind kind = PropertyKind::kNotSet; Token::Value name_token = peek(); + DCHECK_IMPLIES(name_token == Token::PRIVATE_NAME, + allow_harmony_private_fields()); int name_token_position = scanner()->peek_location().beg_pos; IdentifierT name = impl()->NullIdentifier(); @@ -2285,12 +2295,22 @@ ParserBase<Impl>::ParseClassPropertyDefinition( peek() == Token::RBRACE) { name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' name_expression = factory()->NewStringLiteral(name, position()); + } else if (peek() == Token::PRIVATE_NAME) { + DCHECK(allow_harmony_private_fields()); + // TODO(gsathya): Make a better error message for this. + ReportUnexpectedToken(Next()); + *ok = false; + return impl()->NullLiteralProperty(); } else { *is_static = true; name_expression = ParsePropertyName(&name, &kind, &is_generator, &is_get, &is_set, &is_async, is_computed_name, CHECK_OK_CUSTOM(NullLiteralProperty)); } + } else if (name_token == Token::PRIVATE_NAME) { + Consume(Token::PRIVATE_NAME); + name = impl()->GetSymbol(); + name_expression = factory()->NewStringLiteral(name, position()); } else { name_expression = ParsePropertyName(&name, &kind, &is_generator, &is_get, &is_set, &is_async, is_computed_name, @@ -2312,9 +2332,14 @@ ParserBase<Impl>::ParseClassPropertyDefinition( // as an uninitialized field. case PropertyKind::kShorthandProperty: case PropertyKind::kValueProperty: - if (allow_harmony_public_fields()) { + if (allow_harmony_public_fields() || allow_harmony_private_fields()) { *property_kind = ClassLiteralProperty::FIELD; - if (!*is_computed_name) { + if (*is_static && !allow_harmony_static_fields()) { + ReportUnexpectedToken(Next()); + *ok = false; + return impl()->NullLiteralProperty(); + } + if (!*is_computed_name && name_token != Token::PRIVATE_NAME) { checker->CheckClassFieldName(*is_static, CHECK_OK_CUSTOM(NullLiteralProperty)); } @@ -2362,7 +2387,7 @@ ParserBase<Impl>::ParseClassPropertyDefinition( name, scanner()->location(), kSkipFunctionNameCheck, kind, FLAG_harmony_function_tostring ? name_token_position : kNoSourcePosition, - FunctionLiteral::kAccessorOrMethod, language_mode(), + FunctionLiteral::kAccessorOrMethod, language_mode(), nullptr, CHECK_OK_CUSTOM(NullLiteralProperty)); *property_kind = ClassLiteralProperty::METHOD; @@ -2394,7 +2419,7 @@ ParserBase<Impl>::ParseClassPropertyDefinition( name, scanner()->location(), kSkipFunctionNameCheck, kind, FLAG_harmony_function_tostring ? name_token_position : kNoSourcePosition, - FunctionLiteral::kAccessorOrMethod, language_mode(), + FunctionLiteral::kAccessorOrMethod, language_mode(), nullptr, CHECK_OK_CUSTOM(NullLiteralProperty)); *property_kind = @@ -2427,7 +2452,8 @@ ParserBase<Impl>::ParseClassFieldInitializer(ClassInfo* class_info, : class_info->instance_fields_scope; if (initializer_scope == nullptr) { - initializer_scope = NewFunctionScope(FunctionKind::kConciseMethod); + initializer_scope = + NewFunctionScope(FunctionKind::kClassFieldsInitializerFunction); // TODO(gsathya): Make scopes be non contiguous. initializer_scope->set_start_position(scanner()->location().end_pos); initializer_scope->SetLanguageMode(LanguageMode::kStrict); @@ -2441,7 +2467,7 @@ ParserBase<Impl>::ParseClassFieldInitializer(ClassInfo* class_info, initializer = ParseAssignmentExpression(true, CHECK_OK_CUSTOM(NullExpression)); - impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpression)); + ValidateExpression(CHECK_OK_CUSTOM(NullExpression)); } else { initializer = factory()->NewUndefinedLiteral(kNoSourcePosition); } @@ -2560,7 +2586,7 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker, ExpressionClassifier rhs_classifier(this); ExpressionT rhs = ParseAssignmentExpression( true, CHECK_OK_CUSTOM(NullLiteralProperty)); - impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullLiteralProperty)); + ValidateExpression(CHECK_OK_CUSTOM(NullLiteralProperty)); AccumulateFormalParameterContainmentErrors(); value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, kNoSourcePosition); @@ -2595,7 +2621,7 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker, ExpressionT value = impl()->ParseFunctionLiteral( name, scanner()->location(), kSkipFunctionNameCheck, kind, FLAG_harmony_function_tostring ? next_beg_pos : kNoSourcePosition, - FunctionLiteral::kAccessorOrMethod, language_mode(), + FunctionLiteral::kAccessorOrMethod, language_mode(), nullptr, CHECK_OK_CUSTOM(NullLiteralProperty)); ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty( @@ -2627,7 +2653,7 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker, FunctionLiteralT value = impl()->ParseFunctionLiteral( name, scanner()->location(), kSkipFunctionNameCheck, kind, FLAG_harmony_function_tostring ? next_beg_pos : kNoSourcePosition, - FunctionLiteral::kAccessorOrMethod, language_mode(), + FunctionLiteral::kAccessorOrMethod, language_mode(), nullptr, CHECK_OK_CUSTOM(NullLiteralProperty)); ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty( @@ -2711,8 +2737,8 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( MessageTemplate::kTooManyArguments); } - return factory()->NewObjectLiteral( - properties, number_of_boilerplate_properties, pos, has_rest_property); + return impl()->InitializeObjectLiteral(factory()->NewObjectLiteral( + properties, number_of_boilerplate_properties, pos, has_rest_property)); } template <typename Impl> @@ -2738,7 +2764,7 @@ typename ParserBase<Impl>::ExpressionListT ParserBase<Impl>::ParseArguments( *is_simple_parameter_list = false; } if (!maybe_arrow) { - impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList)); + ValidateExpression(CHECK_OK_CUSTOM(NullExpressionList)); } if (is_spread) { if (is_simple_parameter_list != nullptr) { @@ -2784,7 +2810,7 @@ typename ParserBase<Impl>::ExpressionListT ParserBase<Impl>::ParseArguments( if (!maybe_arrow || peek() != Token::ARROW) { if (maybe_arrow) { - impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList)); + ValidateExpression(CHECK_OK_CUSTOM(NullExpressionList)); } } @@ -2864,7 +2890,6 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) { // Because the arrow's parameters were parsed in the outer scope, // we need to fix up the scope chain appropriately. scope_snapshot.Reparent(scope); - function_state_->SetDestructuringAssignmentsScope(rewritable_length, scope); FormalParametersT parameters(scope); if (!classifier()->is_simple_parameter_list()) { @@ -2914,15 +2939,8 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) { productions &= ~ExpressionClassifier::ExpressionProduction; } - if (!Token::IsAssignmentOp(peek())) { - // Parsed conditional expression only (no assignment). - // Pending non-pattern expressions must be merged. - Accumulate(productions); - return expression; - } else { - // Pending non-pattern expressions must be discarded. - Accumulate(productions, false); - } + Accumulate(productions); + if (!Token::IsAssignmentOp(peek())) return expression; if (is_destructuring_assignment) { ValidateAssignmentPattern(CHECK_OK); @@ -2945,7 +2963,7 @@ ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) { ExpressionClassifier rhs_classifier(this); ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK); - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); AccumulateFormalParameterContainmentErrors(); // We try to estimate the set of properties set by constructors. We define a @@ -3019,7 +3037,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression( // Delegating yields require an RHS; fall through. default: expression = ParseAssignmentExpression(accept_IN, CHECK_OK); - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); break; } } @@ -3052,7 +3070,7 @@ ParserBase<Impl>::ParseConditionalExpression(bool accept_IN, // We start using the binary expression parser for prec >= 4 only! ExpressionT expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); if (peek() != Token::CONDITIONAL) return expression; - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); BindingPatternUnexpectedToken(); ArrowFormalParametersUnexpectedToken(); @@ -3067,7 +3085,7 @@ ParserBase<Impl>::ParseConditionalExpression(bool accept_IN, left = ParseAssignmentExpression(true, CHECK_OK); AccumulateNonBindingPatternErrors(); } - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); ExpressionT right; { SourceRangeScope range_scope(scanner(), &else_range); @@ -3076,7 +3094,7 @@ ParserBase<Impl>::ParseConditionalExpression(bool accept_IN, right = ParseAssignmentExpression(accept_IN, CHECK_OK); AccumulateNonBindingPatternErrors(); } - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); ExpressionT expr = factory()->NewConditional(expression, left, right, pos); impl()->RecordConditionalSourceRange(expr, then_range, else_range); return expr; @@ -3093,7 +3111,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression( for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { // prec1 >= 4 while (Precedence(peek(), accept_IN) == prec1) { - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); BindingPatternUnexpectedToken(); ArrowFormalParametersUnexpectedToken(); @@ -3105,7 +3123,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression( const int next_prec = is_right_associative ? prec1 : prec1 + 1; ExpressionT y = ParseBinaryExpression(next_prec, accept_IN, CHECK_OK); right_range_scope.Finalize(); - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); if (impl()->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos)) { continue; @@ -3171,7 +3189,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression( } ExpressionT expression = ParseUnaryExpression(CHECK_OK); - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); if (op == Token::DELETE && is_strict(language_mode())) { if (impl()->IsIdentifier(expression)) { @@ -3200,7 +3218,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression( expression, beg_pos, scanner()->location().end_pos, MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); impl()->MarkExpressionAsAssigned(expression); - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); return factory()->NewCountOperation(op, true /* prefix */, @@ -3211,12 +3229,15 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression( classifier()->RecordFormalParameterInitializerError( scanner()->peek_location(), MessageTemplate::kAwaitExpressionFormalParameter); - int await_pos = peek_position(); Consume(Token::AWAIT); ExpressionT value = ParseUnaryExpression(CHECK_OK); + classifier()->RecordBindingPatternError( + Scanner::Location(await_pos, scanner()->location().end_pos), + MessageTemplate::kInvalidDestructuringTarget); + ExpressionT expr = factory()->NewAwait(value, await_pos); impl()->RecordSuspendSourceRange(expr, PositionAfterSemicolon()); return expr; @@ -3242,7 +3263,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePostfixExpression( expression, lhs_beg_pos, scanner()->location().end_pos, MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); impl()->MarkExpressionAsAssigned(expression); - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); Token::Value next = Next(); expression = @@ -3267,13 +3288,13 @@ ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) { while (true) { switch (peek()) { case Token::LBRACK: { - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); BindingPatternUnexpectedToken(); ArrowFormalParametersUnexpectedToken(); Consume(Token::LBRACK); int pos = position(); ExpressionT index = ParseExpressionCoverGrammar(true, CHECK_OK); - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); result = factory()->NewProperty(result, index, pos); Expect(Token::RBRACK, CHECK_OK); break; @@ -3281,7 +3302,7 @@ ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) { case Token::LPAREN: { int pos; - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); BindingPatternUnexpectedToken(); if (scanner()->current_token() == Token::IDENTIFIER || scanner()->current_token() == Token::SUPER || @@ -3373,7 +3394,7 @@ ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) { } case Token::PERIOD: { - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); BindingPatternUnexpectedToken(); ArrowFormalParametersUnexpectedToken(); Consume(Token::PERIOD); @@ -3387,7 +3408,7 @@ ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) { case Token::TEMPLATE_SPAN: case Token::TEMPLATE_TAIL: { - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); BindingPatternUnexpectedToken(); ArrowFormalParametersUnexpectedToken(); result = ParseTemplateLiteral(result, position(), true, CHECK_OK); @@ -3446,7 +3467,7 @@ ParserBase<Impl>::ParseMemberWithNewPrefixesExpression(bool* is_async, } else { result = ParseMemberWithNewPrefixesExpression(is_async, CHECK_OK); } - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); if (peek() == Token::LPAREN) { // NewExpression with arguments. Scanner::Location spread_pos; @@ -3537,7 +3558,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberExpression( is_strict_reserved_name ? kFunctionNameIsStrictReserved : kFunctionNameValidityUnknown, function_kind, function_token_position, function_type, language_mode(), - CHECK_OK); + nullptr, CHECK_OK); } else if (peek() == Token::SUPER) { const bool is_new = false; result = ParseSuperExpression(is_new, CHECK_OK); @@ -3657,14 +3678,14 @@ ParserBase<Impl>::ParseMemberExpressionContinuation(ExpressionT expression, switch (peek()) { case Token::LBRACK: { *is_async = false; - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); BindingPatternUnexpectedToken(); ArrowFormalParametersUnexpectedToken(); Consume(Token::LBRACK); int pos = position(); ExpressionT index = ParseExpressionCoverGrammar(true, CHECK_OK); - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); expression = factory()->NewProperty(expression, index, pos); impl()->PushPropertyName(index); Expect(Token::RBRACK, CHECK_OK); @@ -3672,13 +3693,19 @@ ParserBase<Impl>::ParseMemberExpressionContinuation(ExpressionT expression, } case Token::PERIOD: { *is_async = false; - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); BindingPatternUnexpectedToken(); ArrowFormalParametersUnexpectedToken(); Consume(Token::PERIOD); int pos = peek_position(); - IdentifierT name = ParseIdentifierName(CHECK_OK); + IdentifierT name; + if (allow_harmony_private_fields() && peek() == Token::PRIVATE_NAME) { + Consume(Token::PRIVATE_NAME); + name = impl()->GetSymbol(); + } else { + name = ParseIdentifierName(CHECK_OK); + } expression = factory()->NewProperty( expression, factory()->NewStringLiteral(name, pos), pos); impl()->PushLiteralName(name); @@ -3687,7 +3714,7 @@ ParserBase<Impl>::ParseMemberExpressionContinuation(ExpressionT expression, case Token::TEMPLATE_SPAN: case Token::TEMPLATE_TAIL: { *is_async = false; - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); BindingPatternUnexpectedToken(); ArrowFormalParametersUnexpectedToken(); int pos; @@ -3743,7 +3770,7 @@ void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters, } ExpressionClassifier init_classifier(this); initializer = ParseAssignmentExpression(true, CHECK_OK_CUSTOM(Void)); - impl()->RewriteNonPattern(CHECK_OK_CUSTOM(Void)); + ValidateExpression(CHECK_OK_CUSTOM(Void)); ValidateFormalParameterInitializer(CHECK_OK_CUSTOM(Void)); parameters->is_simple = false; DiscardExpressionClassifier(); @@ -3882,7 +3909,7 @@ typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseVariableDeclarations( ExpressionClassifier classifier(this); value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK_CUSTOM(NullStatement)); - impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullStatement)); + ValidateExpression(CHECK_OK_CUSTOM(NullStatement)); variable_loc.end_pos = scanner()->location().end_pos; if (!parsing_result->first_initializer_loc.IsValid()) { @@ -3997,7 +4024,7 @@ ParserBase<Impl>::ParseHoistableDeclaration( const bool is_async = flags & ParseFunctionFlags::kIsAsync; DCHECK(!is_generator || !is_async); - if (allow_harmony_async_iteration() && is_async && Check(Token::MUL)) { + if (is_async && Check(Token::MUL)) { // Async generator is_generator = true; } @@ -4025,7 +4052,7 @@ ParserBase<Impl>::ParseHoistableDeclaration( FunctionLiteralT function = impl()->ParseFunctionLiteral( name, scanner()->location(), name_validity, kind, pos, - FunctionLiteral::kDeclaration, language_mode(), + FunctionLiteral::kDeclaration, language_mode(), nullptr, CHECK_OK_CUSTOM(NullStatement)); // In ES6, a function behaves as a lexical binding, except in @@ -4096,6 +4123,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseClassDeclaration( template <typename Impl> typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseNativeDeclaration( bool* ok) { + function_state_->DisableOptimization(BailoutReason::kNativeFunctionLiteral); + int pos = peek_position(); Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement)); // Allow "eval" or "arguments" for backward compatibility. @@ -4150,6 +4179,11 @@ void ParserBase<Impl>::ParseFunctionBody( body = inner_block->statements(); } + // If we are parsing the source as if it is wrapped in a function, the source + // ends without a closing brace. + Token::Value closing_token = + function_type == FunctionLiteral::kWrapped ? Token::EOS : Token::RBRACE; + { BlockState block_state(&scope_, inner_scope); @@ -4162,7 +4196,7 @@ void ParserBase<Impl>::ParseFunctionBody( } else if (IsAsyncFunction(kind)) { ParseAsyncFunctionBody(inner_scope, body, CHECK_OK_VOID); } else { - ParseStatementList(body, Token::RBRACE, CHECK_OK_VOID); + ParseStatementList(body, closing_token, CHECK_OK_VOID); } if (IsDerivedConstructor(kind)) { @@ -4172,7 +4206,7 @@ void ParserBase<Impl>::ParseFunctionBody( } } - Expect(Token::RBRACE, CHECK_OK_VOID); + Expect(closing_token, CHECK_OK_VOID); scope()->set_end_position(scanner()->location().end_pos); if (!parameters.is_simple) { @@ -4298,11 +4332,11 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrowFunctionLiteral( bool accept_IN, const FormalParametersT& formal_parameters, int rewritable_length, bool* ok) { - const RuntimeCallStats::CounterId counters[2][2] = { - {&RuntimeCallStats::ParseBackgroundArrowFunctionLiteral, - &RuntimeCallStats::ParseArrowFunctionLiteral}, - {&RuntimeCallStats::PreParseBackgroundArrowFunctionLiteral, - &RuntimeCallStats::PreParseArrowFunctionLiteral}}; + const RuntimeCallCounterId counters[2][2] = { + {RuntimeCallCounterId::kParseBackgroundArrowFunctionLiteral, + RuntimeCallCounterId::kParseArrowFunctionLiteral}, + {RuntimeCallCounterId::kPreParseBackgroundArrowFunctionLiteral, + RuntimeCallCounterId::kPreParseArrowFunctionLiteral}}; RuntimeCallTimerScope runtime_timer( runtime_call_stats_, counters[Impl::IsPreParser()][parsing_on_main_thread_]); @@ -4337,6 +4371,11 @@ ParserBase<Impl>::ParseArrowFunctionLiteral( FunctionState function_state(&function_state_, &scope_, formal_parameters.scope); + // Move any queued destructuring assignments which appeared + // in this function's parameter list into its own function_state. + function_state.AdoptDestructuringAssignmentsFromParentState( + rewritable_length); + Expect(Token::ARROW, CHECK_OK); if (peek() == Token::LBRACE) { @@ -4360,14 +4399,10 @@ ParserBase<Impl>::ParseArrowFunctionLiteral( USE(result); formal_parameters.scope->ResetAfterPreparsing(ast_value_factory_, false); - // Discard any queued destructuring assignments which appeared - // in this function's parameter list. - FunctionState* parent_state = function_state.outer(); - DCHECK_NOT_NULL(parent_state); - DCHECK_GE(parent_state->destructuring_assignments_to_rewrite().length(), - rewritable_length); - parent_state->RewindDestructuringAssignments(rewritable_length); + // in this function's parameter list, and which were adopted + // into this function state, above. + function_state.RewindDestructuringAssignments(0); } else { Consume(Token::LBRACE); body = impl()->NewStatementList(8); @@ -4467,9 +4502,10 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral( scope()->set_start_position(scanner()->location().end_pos); if (Check(Token::EXTENDS)) { + FuncNameInferrer::State fni_state(fni_); ExpressionClassifier extends_classifier(this); class_info.extends = ParseLeftHandSideExpression(CHECK_OK); - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); AccumulateFormalParameterContainmentErrors(); } @@ -4501,7 +4537,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral( class_info.computed_field_count++; } is_constructor &= class_info.has_seen_constructor; - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); AccumulateFormalParameterContainmentErrors(); impl()->DeclareClassProperty(name, property, property_kind, is_static, @@ -4526,7 +4562,7 @@ void ParserBase<Impl>::ParseSingleExpressionFunctionBody(StatementListT body, ExpressionClassifier classifier(this); ExpressionT expression = ParseAssignmentExpression(accept_IN, CHECK_OK_VOID); - impl()->RewriteNonPattern(CHECK_OK_VOID); + ValidateExpression(CHECK_OK_VOID); if (is_async) { BlockT block = factory()->NewBlock(1, true); @@ -4564,7 +4600,7 @@ ParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) { IdentifierT name = impl()->NullIdentifier(); FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; - bool is_generator = allow_harmony_async_iteration() && Check(Token::MUL); + bool is_generator = Check(Token::MUL); const bool kIsAsync = true; const FunctionKind kind = FunctionKindFor(is_generator, kIsAsync); @@ -4590,7 +4626,7 @@ ParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) { name, scanner()->location(), is_strict_reserved ? kFunctionNameIsStrictReserved : kFunctionNameValidityUnknown, - kind, pos, type, language_mode(), CHECK_OK); + kind, pos, type, language_mode(), nullptr, CHECK_OK); } template <typename Impl> @@ -4650,7 +4686,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral( int expr_pos = peek_position(); ExpressionT expression = ParseExpressionCoverGrammar(true, CHECK_OK); - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); impl()->AddTemplateExpression(&ts, expression); if (peek() != Token::RBRACE) { @@ -4781,8 +4817,9 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseDoExpression( template <typename Impl> typename ParserBase<Impl>::LazyParsingResult -ParserBase<Impl>::ParseStatementList(StatementListT body, int end_token, - bool may_abort, bool* ok) { +ParserBase<Impl>::ParseStatementList(StatementListT body, + Token::Value end_token, bool may_abort, + bool* ok) { // StatementList :: // (StatementListItem)* <end_token> @@ -4953,8 +4990,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatement( case Token::WHILE: return ParseWhileStatement(labels, ok); case Token::FOR: - if (V8_UNLIKELY(allow_harmony_async_iteration() && is_async_function() && - PeekAhead() == Token::AWAIT)) { + if (V8_UNLIKELY(is_async_function() && PeekAhead() == Token::AWAIT)) { return ParseForAwaitStatement(labels, ok); } return ParseForStatement(labels, ok); @@ -5175,11 +5211,6 @@ ParserBase<Impl>::ParseExpressionOrLabelledStatement( // Parsed expression statement, followed by semicolon. ExpectSemicolon(CHECK_OK); - if (labels != nullptr) { - // TODO(adamk): Also measure in the PreParser by passing something - // non-null as |labels|. - impl()->CountUsage(v8::Isolate::kLabeledExpressionStatement); - } return factory()->NewExpressionStatement(expr, pos); } @@ -5204,8 +5235,9 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseIfStatement( StatementT else_statement = impl()->NullStatement(); if (Check(Token::ELSE)) { - SourceRangeScope range_scope(scanner(), &else_range); + else_range = SourceRange::ContinuationOf(then_range); else_statement = ParseScopedStatement(labels, CHECK_OK); + else_range.end = scanner_->location().end_pos; } else { else_statement = factory()->NewEmptyStatement(kNoSourcePosition); } @@ -5547,50 +5579,60 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseTryStatement( { SourceRangeScope catch_range_scope(scanner(), &catch_range); if (Check(Token::CATCH)) { - Expect(Token::LPAREN, CHECK_OK); - catch_info.scope = NewScope(CATCH_SCOPE); - catch_info.scope->set_start_position(scanner()->location().beg_pos); - - { - BlockState catch_block_state(&scope_, catch_info.scope); + bool has_binding; + if (allow_harmony_optional_catch_binding()) { + has_binding = Check(Token::LPAREN); + } else { + has_binding = true; + Expect(Token::LPAREN, CHECK_OK); + } - catch_block = factory()->NewBlock(16, false); + if (has_binding) { + catch_info.scope = NewScope(CATCH_SCOPE); + catch_info.scope->set_start_position(scanner()->location().beg_pos); - // Create a block scope to hold any lexical declarations created - // as part of destructuring the catch parameter. { - BlockState catch_variable_block_state(zone(), &scope_); - scope()->set_start_position(scanner()->location().beg_pos); - typename Types::Target target(this, catch_block); - - // This does not simply call ParsePrimaryExpression to avoid - // ExpressionFromIdentifier from being called in the first - // branch, which would introduce an unresolved symbol and mess - // with arrow function names. - if (peek_any_identifier()) { - catch_info.name = - ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); - } else { - ExpressionClassifier pattern_classifier(this); - catch_info.pattern = ParsePrimaryExpression(CHECK_OK); - ValidateBindingPattern(CHECK_OK); - } + BlockState catch_block_state(&scope_, catch_info.scope); + + catch_block = factory()->NewBlock(16, false); + + // Create a block scope to hold any lexical declarations created + // as part of destructuring the catch parameter. + { + BlockState catch_variable_block_state(zone(), &scope_); + scope()->set_start_position(scanner()->location().beg_pos); + + // This does not simply call ParsePrimaryExpression to avoid + // ExpressionFromIdentifier from being called in the first + // branch, which would introduce an unresolved symbol and mess + // with arrow function names. + if (peek_any_identifier()) { + catch_info.name = + ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); + } else { + ExpressionClassifier pattern_classifier(this); + catch_info.pattern = ParsePrimaryExpression(CHECK_OK); + ValidateBindingPattern(CHECK_OK); + } - Expect(Token::RPAREN, CHECK_OK); - impl()->RewriteCatchPattern(&catch_info, CHECK_OK); - if (!impl()->IsNull(catch_info.init_block)) { - catch_block->statements()->Add(catch_info.init_block, zone()); - } + Expect(Token::RPAREN, CHECK_OK); + impl()->RewriteCatchPattern(&catch_info, CHECK_OK); + if (!impl()->IsNull(catch_info.init_block)) { + catch_block->statements()->Add(catch_info.init_block, zone()); + } - catch_info.inner_block = ParseBlock(nullptr, CHECK_OK); - catch_block->statements()->Add(catch_info.inner_block, zone()); - impl()->ValidateCatchBlock(catch_info, CHECK_OK); - scope()->set_end_position(scanner()->location().end_pos); - catch_block->set_scope(scope()->FinalizeBlockScope()); + catch_info.inner_block = ParseBlock(nullptr, CHECK_OK); + catch_block->statements()->Add(catch_info.inner_block, zone()); + impl()->ValidateCatchBlock(catch_info, CHECK_OK); + scope()->set_end_position(scanner()->location().end_pos); + catch_block->set_scope(scope()->FinalizeBlockScope()); + } } - } - catch_info.scope->set_end_position(scanner()->location().end_pos); + catch_info.scope->set_end_position(scanner()->location().end_pos); + } else { + catch_block = ParseBlock(nullptr, CHECK_OK); + } } } @@ -5687,7 +5729,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement( if (is_destructuring) { ValidateAssignmentPattern(CHECK_OK); } else { - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); } if (is_for_each) { @@ -5750,7 +5792,7 @@ ParserBase<Impl>::ParseForEachStatementWithDeclarations( if (for_info->mode == ForEachStatement::ITERATE) { ExpressionClassifier classifier(this); enumerable = ParseAssignmentExpression(true, CHECK_OK); - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); } else { enumerable = ParseExpression(true, CHECK_OK); } @@ -5826,7 +5868,7 @@ ParserBase<Impl>::ParseForEachStatementWithoutDeclarations( if (for_info->mode == ForEachStatement::ITERATE) { ExpressionClassifier classifier(this); enumerable = ParseAssignmentExpression(true, CHECK_OK); - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); } else { enumerable = ParseExpression(true, CHECK_OK); } @@ -5945,7 +5987,6 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement( ZoneList<const AstRawString*>* labels, bool* ok) { // for await '(' ForDeclaration of AssignmentExpression ')' DCHECK(is_async_function()); - DCHECK(allow_harmony_async_iteration()); int stmt_pos = peek_position(); @@ -6014,7 +6055,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement( if (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()) { ValidateAssignmentPattern(CHECK_OK); } else { - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); each_variable = CheckAndRewriteReferenceExpression( lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK); @@ -6030,7 +6071,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement( { ExpressionClassifier classifier(this); iterable = ParseAssignmentExpression(kAllowIn, CHECK_OK); - impl()->RewriteNonPattern(CHECK_OK); + ValidateExpression(CHECK_OK); } Expect(Token::RPAREN, CHECK_OK); |