diff options
Diffstat (limited to 'deps/v8/src/preparser.h')
-rw-r--r-- | deps/v8/src/preparser.h | 220 |
1 files changed, 120 insertions, 100 deletions
diff --git a/deps/v8/src/preparser.h b/deps/v8/src/preparser.h index 85844a0875..c4d7ed45b3 100644 --- a/deps/v8/src/preparser.h +++ b/deps/v8/src/preparser.h @@ -88,6 +88,7 @@ class ParserBase : public Traits { typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; typedef typename Traits::Type::Literal LiteralT; typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; + typedef typename Traits::Type::StatementList StatementListT; ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, v8::Extension* extension, AstValueFactory* ast_value_factory, @@ -107,18 +108,15 @@ class ParserBase : public Traits { stack_overflow_(false), allow_lazy_(false), allow_natives_(false), - allow_harmony_arrow_functions_(false), allow_harmony_sloppy_(false), allow_harmony_sloppy_function_(false), allow_harmony_sloppy_let_(false), allow_harmony_rest_parameters_(false), allow_harmony_default_parameters_(false), - allow_harmony_spread_calls_(false), allow_harmony_destructuring_(false), - allow_harmony_spread_arrays_(false), - allow_harmony_new_target_(false), allow_strong_mode_(false), - allow_legacy_const_(true) {} + allow_legacy_const_(true), + allow_harmony_do_expressions_(false) {} #define ALLOW_ACCESSORS(name) \ bool allow_##name() const { return allow_##name##_; } \ @@ -126,20 +124,19 @@ class ParserBase : public Traits { ALLOW_ACCESSORS(lazy); ALLOW_ACCESSORS(natives); - ALLOW_ACCESSORS(harmony_arrow_functions); ALLOW_ACCESSORS(harmony_sloppy); ALLOW_ACCESSORS(harmony_sloppy_function); ALLOW_ACCESSORS(harmony_sloppy_let); ALLOW_ACCESSORS(harmony_rest_parameters); ALLOW_ACCESSORS(harmony_default_parameters); - ALLOW_ACCESSORS(harmony_spread_calls); ALLOW_ACCESSORS(harmony_destructuring); - ALLOW_ACCESSORS(harmony_spread_arrays); - ALLOW_ACCESSORS(harmony_new_target); ALLOW_ACCESSORS(strong_mode); ALLOW_ACCESSORS(legacy_const); + ALLOW_ACCESSORS(harmony_do_expressions); #undef ALLOW_ACCESSORS + uintptr_t stack_limit() const { return stack_limit_; } + protected: enum AllowRestrictedIdentifiers { kAllowRestrictedIdentifiers, @@ -309,16 +306,14 @@ class ParserBase : public Traits { }; Scope* NewScope(Scope* parent, ScopeType scope_type) { - // Must always pass the function kind for FUNCTION_SCOPE and ARROW_SCOPE. + // Must always pass the function kind for FUNCTION_SCOPE. DCHECK(scope_type != FUNCTION_SCOPE); - DCHECK(scope_type != ARROW_SCOPE); return NewScope(parent, scope_type, kNormalFunction); } Scope* NewScope(Scope* parent, ScopeType scope_type, FunctionKind kind) { DCHECK(ast_value_factory()); DCHECK(scope_type != MODULE_SCOPE || FLAG_harmony_modules); - DCHECK(!IsArrowFunction(kind) || scope_type == ARROW_SCOPE); Scope* result = new (zone()) Scope(zone(), parent, scope_type, ast_value_factory(), kind); result->Initialize(); @@ -426,8 +421,7 @@ class ParserBase : public Traits { } } - bool CheckInOrOf( - bool accept_OF, ForEachStatement::VisitMode* visit_mode, bool* ok) { + bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode, bool* ok) { if (Check(Token::IN)) { if (is_strong(language_mode())) { ReportMessageAt(scanner()->location(), MessageTemplate::kStrongForIn); @@ -436,7 +430,7 @@ class ParserBase : public Traits { *visit_mode = ForEachStatement::ENUMERATE; } return true; - } else if (accept_OF && CheckContextualKeyword(CStrVector("of"))) { + } else if (CheckContextualKeyword(CStrVector("of"))) { *visit_mode = ForEachStatement::ITERATE; return true; } @@ -620,6 +614,13 @@ class ParserBase : public Traits { } } + void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) { + if (!classifier->is_valid_let_pattern()) { + ReportClassifierError(classifier->let_pattern_error()); + *ok = false; + } + } + void ExpressionUnexpectedToken(ExpressionClassifier* classifier) { MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; const char* arg; @@ -711,9 +712,10 @@ class ParserBase : public Traits { ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok); ExpressionT ParseMemberExpressionContinuation( ExpressionT expression, ExpressionClassifier* classifier, bool* ok); - ExpressionT ParseArrowFunctionLiteral( - const FormalParametersT& parameters, - const ExpressionClassifier& classifier, bool* ok); + ExpressionT ParseArrowFunctionLiteral(bool accept_IN, + const FormalParametersT& parameters, + const ExpressionClassifier& classifier, + bool* ok); ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, ExpressionClassifier* classifier, bool* ok); void AddTemplateExpression(ExpressionT); @@ -827,18 +829,15 @@ class ParserBase : public Traits { bool allow_lazy_; bool allow_natives_; - bool allow_harmony_arrow_functions_; bool allow_harmony_sloppy_; bool allow_harmony_sloppy_function_; bool allow_harmony_sloppy_let_; bool allow_harmony_rest_parameters_; bool allow_harmony_default_parameters_; - bool allow_harmony_spread_calls_; bool allow_harmony_destructuring_; - bool allow_harmony_spread_arrays_; - bool allow_harmony_new_target_; bool allow_strong_mode_; bool allow_legacy_const_; + bool allow_harmony_do_expressions_; }; @@ -948,6 +947,14 @@ class PreParserExpression { right->IsSpreadExpression())); } + static PreParserExpression ObjectLiteral() { + return PreParserExpression(TypeField::encode(kObjectLiteralExpression)); + } + + static PreParserExpression ArrayLiteral() { + return PreParserExpression(TypeField::encode(kArrayLiteralExpression)); + } + static PreParserExpression StringLiteral() { return PreParserExpression(TypeField::encode(kStringLiteralExpression)); } @@ -1005,6 +1012,14 @@ class PreParserExpression { return PreParserIdentifier(IdentifierTypeField::decode(code_)); } + bool IsObjectLiteral() const { + return TypeField::decode(code_) == kObjectLiteralExpression; + } + + bool IsArrayLiteral() const { + return TypeField::decode(code_) == kArrayLiteralExpression; + } + bool IsStringLiteral() const { return TypeField::decode(code_) == kStringLiteralExpression; } @@ -1093,7 +1108,9 @@ class PreParserExpression { kIdentifierExpression, kStringLiteralExpression, kBinaryOperationExpression, - kSpreadExpression + kSpreadExpression, + kObjectLiteralExpression, + kArrayLiteralExpression }; enum ExpressionType { @@ -1231,12 +1248,12 @@ class PreParserFactory { int literal_index, bool is_strong, int pos) { - return PreParserExpression::Default(); + return PreParserExpression::ArrayLiteral(); } PreParserExpression NewArrayLiteral(PreParserExpressionList values, int first_spread_index, int literal_index, bool is_strong, int pos) { - return PreParserExpression::Default(); + return PreParserExpression::ArrayLiteral(); } PreParserExpression NewObjectLiteralProperty(PreParserExpression key, PreParserExpression value, @@ -1257,7 +1274,7 @@ class PreParserFactory { bool has_function, bool is_strong, int pos) { - return PreParserExpression::Default(); + return PreParserExpression::ObjectLiteral(); } PreParserExpression NewVariableProxy(void* variable) { return PreParserExpression::Default(); @@ -1695,6 +1712,7 @@ class PreParserTraits { // Temporary glue; these functions will move to ParserBase. PreParserExpression ParseV8Intrinsic(bool* ok); + V8_INLINE PreParserExpression ParseDoExpression(bool* ok); PreParserExpression ParseFunctionLiteral( PreParserIdentifier name, Scanner::Location function_name_location, FunctionNameValidity function_name_validity, FunctionKind kind, @@ -1835,6 +1853,7 @@ class PreParser : public ParserBase<PreParserTraits> { Expression ParseConditionalExpression(bool accept_IN, bool* ok); Expression ParseObjectLiteral(bool* ok); Expression ParseV8Intrinsic(bool* ok); + Expression ParseDoExpression(bool* ok); V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count, int* expected_property_count, bool* ok); @@ -1900,6 +1919,11 @@ void PreParserTraits::ParseArrowFunctionFormalParameterList( } +PreParserExpression PreParserTraits::ParseDoExpression(bool* ok) { + return pre_parser_->ParseDoExpression(ok); +} + + PreParserStatementList PreParser::ParseEagerFunctionBody( PreParserIdentifier function_name, int pos, const PreParserFormalParameters& parameters, FunctionKind kind, @@ -2095,6 +2119,10 @@ ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, (next == Token::YIELD && !is_generator()))) { classifier->RecordStrictModeFormalParameterError( scanner()->location(), MessageTemplate::kUnexpectedStrictReserved); + if (next == Token::LET) { + classifier->RecordLetPatternError(scanner()->location(), + MessageTemplate::kLetInLexicalBinding); + } return this->GetSymbol(scanner()); } else { this->ReportUnexpectedToken(next); @@ -2216,12 +2244,10 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, // ClassLiteral // '(' Expression ')' // TemplateLiteral + // do Block - int beg_pos = scanner()->peek_location().beg_pos; - int end_pos = scanner()->peek_location().end_pos; - ExpressionT result = this->EmptyExpression(); - Token::Value token = peek(); - switch (token) { + int beg_pos = peek_position(); + switch (peek()) { case Token::THIS: { BindingPatternUnexpectedToken(classifier); Consume(Token::THIS); @@ -2231,29 +2257,22 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, if (IsClassConstructor(function_state_->kind())) { ReportMessage(MessageTemplate::kStrongConstructorThis); *ok = false; - break; + return this->EmptyExpression(); } } - result = this->ThisExpression(scope_, factory(), beg_pos); - break; + return this->ThisExpression(scope_, factory(), beg_pos); } case Token::NULL_LITERAL: case Token::TRUE_LITERAL: case Token::FALSE_LITERAL: BindingPatternUnexpectedToken(classifier); - Next(); - result = - this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); - break; + return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); case Token::SMI: case Token::NUMBER: classifier->RecordBindingPatternError( scanner()->peek_location(), MessageTemplate::kUnexpectedTokenNumber); - Next(); - result = - this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); - break; + return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); case Token::IDENTIFIER: case Token::LET: @@ -2262,46 +2281,40 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, case Token::FUTURE_STRICT_RESERVED_WORD: { // Using eval or arguments in this context is OK even in strict mode. IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); - result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, - factory()); - break; + return this->ExpressionFromIdentifier( + name, beg_pos, scanner()->location().end_pos, scope_, factory()); } case Token::STRING: { classifier->RecordBindingPatternError( scanner()->peek_location(), MessageTemplate::kUnexpectedTokenString); Consume(Token::STRING); - result = this->ExpressionFromString(beg_pos, scanner(), factory()); - break; + return this->ExpressionFromString(beg_pos, scanner(), factory()); } case Token::ASSIGN_DIV: classifier->RecordBindingPatternError( scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp); - result = this->ParseRegExpLiteral(true, classifier, CHECK_OK); - break; + return this->ParseRegExpLiteral(true, classifier, ok); case Token::DIV: classifier->RecordBindingPatternError( scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp); - result = this->ParseRegExpLiteral(false, classifier, CHECK_OK); - break; + return this->ParseRegExpLiteral(false, classifier, ok); case Token::LBRACK: if (!allow_harmony_destructuring()) { BindingPatternUnexpectedToken(classifier); } - result = this->ParseArrayLiteral(classifier, CHECK_OK); - break; + return this->ParseArrayLiteral(classifier, ok); case Token::LBRACE: if (!allow_harmony_destructuring()) { BindingPatternUnexpectedToken(classifier); } - result = this->ParseObjectLiteral(classifier, CHECK_OK); - break; + return this->ParseObjectLiteral(classifier, ok); - case Token::LPAREN: + case Token::LPAREN: { // Arrow function formal parameters are either a single identifier or a // list of BindingPattern productions enclosed in parentheses. // Parentheses are not valid on the LHS of a BindingPattern, so we use the @@ -2321,28 +2334,27 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, classifier->RecordBindingPatternError(scanner()->location(), MessageTemplate::kUnexpectedToken, Token::String(Token::RPAREN)); - result = factory()->NewEmptyParentheses(beg_pos); + return factory()->NewEmptyParentheses(beg_pos); } else if (allow_harmony_rest_parameters() && Check(Token::ELLIPSIS)) { // (...x)=>x. The continuation that looks for the => is in // ParseAssignmentExpression. - int ellipsis_pos = scanner()->location().beg_pos; + int ellipsis_pos = position(); classifier->RecordExpressionError(scanner()->location(), MessageTemplate::kUnexpectedToken, Token::String(Token::ELLIPSIS)); classifier->RecordNonSimpleParameter(); Scanner::Location expr_loc = scanner()->peek_location(); Token::Value tok = peek(); - result = this->ParseAssignmentExpression(true, classifier, CHECK_OK); + ExpressionT expr = + this->ParseAssignmentExpression(true, classifier, CHECK_OK); // Patterns are not allowed as rest parameters. There is no way we can // succeed so go ahead and use the convenient ReportUnexpectedToken // interface. - if (!Traits::IsIdentifier(result)) { + if (!Traits::IsIdentifier(expr)) { ReportUnexpectedTokenAt(expr_loc, tok); *ok = false; return this->EmptyExpression(); } - result = factory()->NewSpread(result, ellipsis_pos); - if (peek() == Token::COMMA) { ReportMessageAt(scanner()->peek_location(), MessageTemplate::kParamAfterRest); @@ -2350,14 +2362,15 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, return this->EmptyExpression(); } Expect(Token::RPAREN, CHECK_OK); - } else { - // Heuristically try to detect immediately called functions before - // seeing the call parentheses. - parenthesized_function_ = (peek() == Token::FUNCTION); - result = this->ParseExpression(true, classifier, CHECK_OK); - Expect(Token::RPAREN, CHECK_OK); + return factory()->NewSpread(expr, ellipsis_pos); } - break; + // Heuristically try to detect immediately called functions before + // seeing the call parentheses. + parenthesized_function_ = (peek() == Token::FUNCTION); + ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK); + Expect(Token::RPAREN, CHECK_OK); + return expr; + } case Token::CLASS: { BindingPatternUnexpectedToken(classifier); @@ -2365,7 +2378,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { ReportMessage(MessageTemplate::kSloppyLexical); *ok = false; - break; + return this->EmptyExpression(); } int class_token_position = position(); IdentifierT name = this->EmptyIdentifier(); @@ -2376,10 +2389,9 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, CHECK_OK); class_name_location = scanner()->location(); } - result = this->ParseClassLiteral(name, class_name_location, - is_strict_reserved_name, - class_token_position, CHECK_OK); - break; + return this->ParseClassLiteral(name, class_name_location, + is_strict_reserved_name, + class_token_position, ok); } case Token::TEMPLATE_SPAN: @@ -2387,26 +2399,30 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, classifier->RecordBindingPatternError( scanner()->peek_location(), MessageTemplate::kUnexpectedTemplateString); - result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, - classifier, CHECK_OK); - break; + return this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, + classifier, ok); case Token::MOD: if (allow_natives() || extension_ != NULL) { - result = this->ParseV8Intrinsic(CHECK_OK); - break; + BindingPatternUnexpectedToken(classifier); + return this->ParseV8Intrinsic(ok); } - // If we're not allowing special syntax we fall-through to the - // default case. + break; - default: { - Next(); - ReportUnexpectedToken(token); - *ok = false; - } + case Token::DO: + if (allow_harmony_do_expressions()) { + BindingPatternUnexpectedToken(classifier); + return Traits::ParseDoExpression(ok); + } + break; + + default: + break; } - return result; + ReportUnexpectedToken(Next()); + *ok = false; + return this->EmptyExpression(); } @@ -2493,9 +2509,6 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( } elem = this->GetLiteralTheHole(peek_position(), factory()); } else if (peek() == Token::ELLIPSIS) { - if (!allow_harmony_spread_arrays()) { - ExpressionUnexpectedToken(classifier); - } int start_pos = peek_position(); Consume(Token::ELLIPSIS); ExpressionT argument = @@ -2642,6 +2655,10 @@ ParserBase<Traits>::ParsePropertyDefinition( scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { classifier->RecordDuplicateFormalParameterError(scanner()->location()); } + if (name_token == Token::LET) { + classifier->RecordLetPatternError( + scanner()->location(), MessageTemplate::kLetInLexicalBinding); + } ExpressionT lhs = this->ExpressionFromIdentifier( name, next_beg_pos, next_end_pos, scope_, factory()); @@ -2832,10 +2849,8 @@ typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( bool was_unspread = false; int unspread_sequences_count = 0; while (!done) { - bool is_spread = - allow_harmony_spread_calls() && (peek() == Token::ELLIPSIS); int start_pos = peek_position(); - if (is_spread) Consume(Token::ELLIPSIS); + bool is_spread = Check(Token::ELLIPSIS); ExpressionT argument = this->ParseAssignmentExpression( true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); @@ -2912,13 +2927,17 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, } ExpressionT expression = this->ParseConditionalExpression( accept_IN, &arrow_formals_classifier, CHECK_OK); - if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { + if (peek() == Token::ARROW) { BindingPatternUnexpectedToken(classifier); ValidateArrowFormalParameters(&arrow_formals_classifier, expression, parenthesized_formals, CHECK_OK); Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); Scope* scope = - this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); + this->NewScope(scope_, FUNCTION_SCOPE, 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. + scope_->PropagateUsageFlagsToScope(scope); FormalParametersT parameters(scope); if (!arrow_formals_classifier.is_simple_parameter_list()) { scope->SetHasNonSimpleParameters(); @@ -2937,7 +2956,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, duplicate_loc); } expression = this->ParseArrowFunctionLiteral( - parameters, arrow_formals_classifier, CHECK_OK); + accept_IN, parameters, arrow_formals_classifier, CHECK_OK); if (fni_ != nullptr) fni_->Infer(); @@ -3376,7 +3395,7 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression( if (peek() == Token::SUPER) { const bool is_new = true; result = ParseSuperExpression(is_new, classifier, CHECK_OK); - } else if (allow_harmony_new_target() && peek() == Token::PERIOD) { + } else if (peek() == Token::PERIOD) { return ParseNewTargetExpression(CHECK_OK); } else { result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); @@ -3873,7 +3892,7 @@ bool ParserBase<Traits>::IsNextLetKeyword() { template <class Traits> typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrowFunctionLiteral( - const FormalParametersT& formal_parameters, + bool accept_IN, const FormalParametersT& formal_parameters, const ExpressionClassifier& formals_classifier, bool* ok) { if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { // ASI inserts `;` after arrow parameters if a line terminator is found. @@ -3931,7 +3950,7 @@ ParserBase<Traits>::ParseArrowFunctionLiteral( parenthesized_function_ = false; ExpressionClassifier classifier; ExpressionT expression = - ParseAssignmentExpression(true, &classifier, CHECK_OK); + ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); ValidateExpression(&classifier, CHECK_OK); body = this->NewStatementList(1, zone()); this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); @@ -4180,6 +4199,7 @@ void ParserBase<Traits>::ClassLiteralChecker::CheckProperty( return; } } -} } // v8::internal +} // namespace internal +} // namespace v8 #endif // V8_PREPARSER_H |