OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 void CheckFunctionParameterNames(LanguageMode language_mode, | 520 void CheckFunctionParameterNames(LanguageMode language_mode, |
521 bool strict_params, | 521 bool strict_params, |
522 const FormalParameterErrorLocations& locs, | 522 const FormalParameterErrorLocations& locs, |
523 bool* ok) { | 523 bool* ok) { |
524 if (is_sloppy(language_mode) && !strict_params) return; | 524 if (is_sloppy(language_mode) && !strict_params) return; |
525 if (is_strict(language_mode) && locs.eval_or_arguments_.IsValid()) { | 525 if (is_strict(language_mode) && locs.eval_or_arguments_.IsValid()) { |
526 Traits::ReportMessageAt(locs.eval_or_arguments_, "strict_eval_arguments"); | 526 Traits::ReportMessageAt(locs.eval_or_arguments_, "strict_eval_arguments"); |
527 *ok = false; | 527 *ok = false; |
528 return; | 528 return; |
529 } | 529 } |
| 530 if (is_strict(language_mode) && locs.reserved_.IsValid()) { |
| 531 Traits::ReportMessageAt(locs.reserved_, "unexpected_strict_reserved"); |
| 532 *ok = false; |
| 533 return; |
| 534 } |
530 if (is_strong(language_mode) && locs.undefined_.IsValid()) { | 535 if (is_strong(language_mode) && locs.undefined_.IsValid()) { |
531 Traits::ReportMessageAt(locs.undefined_, "strong_undefined"); | 536 Traits::ReportMessageAt(locs.undefined_, "strong_undefined"); |
532 *ok = false; | 537 *ok = false; |
533 return; | 538 return; |
534 } | 539 } |
535 // TODO(arv): When we add support for destructuring in setters we also need | 540 // TODO(arv): When we add support for destructuring in setters we also need |
536 // to check for duplicate names. | 541 // to check for duplicate names. |
537 if (locs.duplicate_.IsValid()) { | 542 if (locs.duplicate_.IsValid()) { |
538 Traits::ReportMessageAt(locs.duplicate_, "strict_param_dupe"); | 543 Traits::ReportMessageAt(locs.duplicate_, "strict_param_dupe"); |
539 *ok = false; | 544 *ok = false; |
540 return; | 545 return; |
541 } | 546 } |
542 if (locs.reserved_.IsValid()) { | |
543 Traits::ReportMessageAt(locs.reserved_, "unexpected_strict_reserved"); | |
544 *ok = false; | |
545 return; | |
546 } | |
547 } | 547 } |
548 | 548 |
549 // Determine precedence of given token. | 549 // Determine precedence of given token. |
550 static int Precedence(Token::Value token, bool accept_IN) { | 550 static int Precedence(Token::Value token, bool accept_IN) { |
551 if (token == Token::IN && !accept_IN) | 551 if (token == Token::IN && !accept_IN) |
552 return 0; // 0 precedence will terminate binary expression parsing | 552 return 0; // 0 precedence will terminate binary expression parsing |
553 return Token::Precedence(token); | 553 return Token::Precedence(token); |
554 } | 554 } |
555 | 555 |
556 typename Traits::Type::Factory* factory() { | 556 typename Traits::Type::Factory* factory() { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 ExpressionT ParseYieldExpression(bool* ok); | 614 ExpressionT ParseYieldExpression(bool* ok); |
615 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 615 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
616 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 616 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
617 ExpressionT ParseUnaryExpression(bool* ok); | 617 ExpressionT ParseUnaryExpression(bool* ok); |
618 ExpressionT ParsePostfixExpression(bool* ok); | 618 ExpressionT ParsePostfixExpression(bool* ok); |
619 ExpressionT ParseLeftHandSideExpression(bool* ok); | 619 ExpressionT ParseLeftHandSideExpression(bool* ok); |
620 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 620 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
621 ExpressionT ParseMemberExpression(bool* ok); | 621 ExpressionT ParseMemberExpression(bool* ok); |
622 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 622 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
623 bool* ok); | 623 bool* ok); |
624 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, | 624 ExpressionT ParseArrowFunctionLiteral( |
625 bool* ok); | 625 int start_pos, FormalParameterListT params, |
| 626 const FormalParameterErrorLocations& error_locs, bool has_rest, bool* ok); |
626 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 627 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
627 void AddTemplateExpression(ExpressionT); | 628 void AddTemplateExpression(ExpressionT); |
628 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 629 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
629 | 630 |
630 FormalParameterT ParseFormalParameter(DuplicateFinder* duplicate_finder, | 631 FormalParameterT ParseFormalParameter(DuplicateFinder* duplicate_finder, |
631 FormalParameterErrorLocations* locs, | 632 FormalParameterErrorLocations* locs, |
632 bool* ok); | 633 bool* ok); |
633 FormalParameterListT ParseFormalParameterList( | 634 FormalParameterListT ParseFormalParameterList( |
634 FormalParameterErrorLocations* locs, bool* is_rest, bool* ok); | 635 FormalParameterErrorLocations* locs, bool* is_rest, bool* ok); |
635 void CheckArityRestrictions( | 636 void CheckArityRestrictions( |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
838 ValidArrowParam valid_arrow_param_list = | 839 ValidArrowParam valid_arrow_param_list = |
839 (op == Token::COMMA && !left.is_parenthesized() && | 840 (op == Token::COMMA && !left.is_parenthesized() && |
840 !right.is_parenthesized()) ? | 841 !right.is_parenthesized()) ? |
841 std::min(left.ValidateArrowParams(), right.ValidateArrowParams()) | 842 std::min(left.ValidateArrowParams(), right.ValidateArrowParams()) |
842 : kInvalidArrowParam; | 843 : kInvalidArrowParam; |
843 return PreParserExpression( | 844 return PreParserExpression( |
844 TypeField::encode(kBinaryOperationExpression) | | 845 TypeField::encode(kBinaryOperationExpression) | |
845 IsValidArrowParamListField::encode(valid_arrow_param_list)); | 846 IsValidArrowParamListField::encode(valid_arrow_param_list)); |
846 } | 847 } |
847 | 848 |
848 static PreParserExpression EmptyArrowParamList() { | |
849 // Any expression for which IsValidArrowParamList() returns true | |
850 // will work here. | |
851 return FromIdentifier(PreParserIdentifier::Default()); | |
852 } | |
853 | |
854 static PreParserExpression StringLiteral() { | 849 static PreParserExpression StringLiteral() { |
855 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); | 850 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); |
856 } | 851 } |
857 | 852 |
858 static PreParserExpression UseStrictStringLiteral() { | 853 static PreParserExpression UseStrictStringLiteral() { |
859 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | | 854 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | |
860 IsUseStrictField::encode(true)); | 855 IsUseStrictField::encode(true)); |
861 } | 856 } |
862 | 857 |
863 static PreParserExpression UseStrongStringLiteral() { | 858 static PreParserExpression UseStrongStringLiteral() { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
934 | 929 |
935 bool IsCall() const { | 930 bool IsCall() const { |
936 return TypeField::decode(code_) == kExpression && | 931 return TypeField::decode(code_) == kExpression && |
937 ExpressionTypeField::decode(code_) == kCallExpression; | 932 ExpressionTypeField::decode(code_) == kCallExpression; |
938 } | 933 } |
939 | 934 |
940 bool IsValidReferenceExpression() const { | 935 bool IsValidReferenceExpression() const { |
941 return IsIdentifier() || IsProperty(); | 936 return IsIdentifier() || IsProperty(); |
942 } | 937 } |
943 | 938 |
944 bool IsValidArrowParamList(FormalParameterErrorLocations* locs) const { | 939 bool IsValidArrowParamList(FormalParameterErrorLocations* locs, |
| 940 const Scanner::Location& params_loc) const { |
945 ValidArrowParam valid = ValidateArrowParams(); | 941 ValidArrowParam valid = ValidateArrowParams(); |
946 if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) { | 942 if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) { |
947 return false; | 943 return false; |
948 } | 944 } |
949 if (valid == kValidArrowParam) { | 945 switch (valid) { |
950 return true; | 946 case kInvalidArrowParam: |
951 } else if (valid == kInvalidStrongArrowParam) { | 947 return false; |
952 // Return true for now regardless of strong mode for compatibility with | 948 case kInvalidStrongArrowParam: |
953 // parser. | 949 locs->undefined_ = params_loc; |
954 locs->undefined_ = Scanner::Location(); | 950 return true; |
955 return true; | 951 case kInvalidStrictReservedArrowParam: |
956 } else { | 952 locs->reserved_ = params_loc; |
957 return false; | 953 return true; |
| 954 case kInvalidStrictEvalArgumentsArrowParam: |
| 955 locs->eval_or_arguments_ = params_loc; |
| 956 return true; |
| 957 default: |
| 958 DCHECK_EQ(valid, kValidArrowParam); |
| 959 return true; |
958 } | 960 } |
959 } | 961 } |
960 | 962 |
961 // At the moment PreParser doesn't track these expression types. | 963 // At the moment PreParser doesn't track these expression types. |
962 bool IsFunctionLiteral() const { return false; } | 964 bool IsFunctionLiteral() const { return false; } |
963 bool IsCallNew() const { return false; } | 965 bool IsCallNew() const { return false; } |
964 | 966 |
965 bool IsNoTemplateTag() const { | 967 bool IsNoTemplateTag() const { |
966 return TypeField::decode(code_) == kExpression && | 968 return TypeField::decode(code_) == kExpression && |
967 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; | 969 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1014 }; | 1016 }; |
1015 | 1017 |
1016 enum ExpressionType { | 1018 enum ExpressionType { |
1017 kThisExpression, | 1019 kThisExpression, |
1018 kThisPropertyExpression, | 1020 kThisPropertyExpression, |
1019 kPropertyExpression, | 1021 kPropertyExpression, |
1020 kCallExpression, | 1022 kCallExpression, |
1021 kNoTemplateTagExpression | 1023 kNoTemplateTagExpression |
1022 }; | 1024 }; |
1023 | 1025 |
| 1026 // These validity constraints are ordered such that a value of N implies lack |
| 1027 // of errors M < N. |
1024 enum ValidArrowParam { | 1028 enum ValidArrowParam { |
1025 kInvalidArrowParam, | 1029 kInvalidArrowParam, |
| 1030 kInvalidStrictEvalArgumentsArrowParam, |
| 1031 kInvalidStrictReservedArrowParam, |
1026 kInvalidStrongArrowParam, | 1032 kInvalidStrongArrowParam, |
1027 kValidArrowParam | 1033 kValidArrowParam |
1028 }; | 1034 }; |
1029 | 1035 |
1030 explicit PreParserExpression(uint32_t expression_code) | 1036 explicit PreParserExpression(uint32_t expression_code) |
1031 : code_(expression_code) {} | 1037 : code_(expression_code) {} |
1032 | 1038 |
1033 V8_INLINE ValidArrowParam ValidateArrowParams() const { | 1039 V8_INLINE ValidArrowParam ValidateArrowParams() const { |
1034 if (IsBinaryOperation()) { | 1040 if (IsBinaryOperation()) { |
1035 return IsValidArrowParamListField::decode(code_); | 1041 return IsValidArrowParamListField::decode(code_); |
1036 } | 1042 } |
1037 if (!IsIdentifier()) { | 1043 if (!IsIdentifier()) { |
1038 return kInvalidArrowParam; | 1044 return kInvalidArrowParam; |
1039 } | 1045 } |
1040 PreParserIdentifier ident = AsIdentifier(); | 1046 PreParserIdentifier ident = AsIdentifier(); |
1041 // A valid identifier can be an arrow function parameter | 1047 // In strict mode, eval and arguments are not valid formal parameter names. |
1042 // except for eval, arguments, yield, and reserved keywords. | 1048 if (ident.IsEval() || ident.IsArguments()) { |
1043 if (ident.IsEval() || ident.IsArguments() || | 1049 return kInvalidStrictEvalArgumentsArrowParam; |
1044 ident.IsFutureStrictReserved()) { | |
1045 return kInvalidArrowParam; | |
1046 } | 1050 } |
1047 // In strong mode, 'undefined' is similarly restricted. | 1051 // In strict mode, future reserved words are not valid either, and as they |
| 1052 // produce different errors we allot them their own error code. |
| 1053 if (ident.IsFutureStrictReserved()) { |
| 1054 return kInvalidStrictReservedArrowParam; |
| 1055 } |
| 1056 // In strong mode, 'undefined' isn't a valid formal parameter name either. |
1048 if (ident.IsUndefined()) { | 1057 if (ident.IsUndefined()) { |
1049 return kInvalidStrongArrowParam; | 1058 return kInvalidStrongArrowParam; |
1050 } | 1059 } |
1051 return kValidArrowParam; | 1060 return kValidArrowParam; |
1052 } | 1061 } |
1053 | 1062 |
1054 // The first five bits are for the Type and Parenthesization. | 1063 // The first five bits are for the Type and Parenthesization. |
1055 typedef BitField<Type, 0, 3> TypeField; | 1064 typedef BitField<Type, 0, 3> TypeField; |
1056 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; | 1065 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; |
1057 | 1066 |
1058 // The rest of the bits are interpreted depending on the value | 1067 // The rest of the bits are interpreted depending on the value |
1059 // of the Type field, so they can share the storage. | 1068 // of the Type field, so they can share the storage. |
1060 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> | 1069 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> |
1061 ExpressionTypeField; | 1070 ExpressionTypeField; |
1062 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; | 1071 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; |
1063 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 1072 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
1064 typedef BitField<ValidArrowParam, ParenthesizationField::kNext, 2> | 1073 typedef BitField<ValidArrowParam, ParenthesizationField::kNext, 3> |
1065 IsValidArrowParamListField; | 1074 IsValidArrowParamListField; |
1066 typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10> | 1075 typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10> |
1067 IdentifierTypeField; | 1076 IdentifierTypeField; |
1068 | 1077 |
1069 uint32_t code_; | 1078 uint32_t code_; |
1070 }; | 1079 }; |
1071 | 1080 |
1072 | 1081 |
1073 // The pre-parser doesn't need to build lists of expressions, identifiers, or | 1082 // The pre-parser doesn't need to build lists of expressions, identifiers, or |
1074 // the like. | 1083 // the like. |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1447 // "null" return type creators. | 1456 // "null" return type creators. |
1448 static PreParserIdentifier EmptyIdentifier() { | 1457 static PreParserIdentifier EmptyIdentifier() { |
1449 return PreParserIdentifier::Default(); | 1458 return PreParserIdentifier::Default(); |
1450 } | 1459 } |
1451 static PreParserIdentifier EmptyIdentifierString() { | 1460 static PreParserIdentifier EmptyIdentifierString() { |
1452 return PreParserIdentifier::Default(); | 1461 return PreParserIdentifier::Default(); |
1453 } | 1462 } |
1454 static PreParserExpression EmptyExpression() { | 1463 static PreParserExpression EmptyExpression() { |
1455 return PreParserExpression::Default(); | 1464 return PreParserExpression::Default(); |
1456 } | 1465 } |
1457 static PreParserExpression EmptyArrowParamList() { | |
1458 return PreParserExpression::EmptyArrowParamList(); | |
1459 } | |
1460 static PreParserExpression EmptyLiteral() { | 1466 static PreParserExpression EmptyLiteral() { |
1461 return PreParserExpression::Default(); | 1467 return PreParserExpression::Default(); |
1462 } | 1468 } |
1463 static PreParserExpression EmptyObjectLiteralProperty() { | 1469 static PreParserExpression EmptyObjectLiteralProperty() { |
1464 return PreParserExpression::Default(); | 1470 return PreParserExpression::Default(); |
1465 } | 1471 } |
1466 static PreParserExpression EmptyFunctionLiteral() { | 1472 static PreParserExpression EmptyFunctionLiteral() { |
1467 return PreParserExpression::Default(); | 1473 return PreParserExpression::Default(); |
1468 } | 1474 } |
1469 static PreParserExpressionList NullExpressionList() { | 1475 static PreParserExpressionList NullExpressionList() { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1548 int* materialized_literal_count, | 1554 int* materialized_literal_count, |
1549 int* expected_property_count, bool* ok) { | 1555 int* expected_property_count, bool* ok) { |
1550 UNREACHABLE(); | 1556 UNREACHABLE(); |
1551 } | 1557 } |
1552 | 1558 |
1553 V8_INLINE PreParserStatementList | 1559 V8_INLINE PreParserStatementList |
1554 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, | 1560 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
1555 Variable* fvar, Token::Value fvar_init_op, | 1561 Variable* fvar, Token::Value fvar_init_op, |
1556 FunctionKind kind, bool* ok); | 1562 FunctionKind kind, bool* ok); |
1557 | 1563 |
1558 // Utility functions | 1564 V8_INLINE PreParserFormalParameterList ParseArrowFunctionFormalParameterList( |
1559 V8_INLINE int DeclareArrowParametersFromExpression( | 1565 PreParserExpression expression, const Scanner::Location& params_loc, |
1560 PreParserExpression expression, Scope* scope, | 1566 FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok); |
1561 FormalParameterErrorLocations* locs, bool* ok) { | |
1562 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect eval or | |
1563 // arguments. Detect reserved words. | |
1564 *ok = expression.IsValidArrowParamList(locs); | |
1565 return 0; | |
1566 } | |
1567 | 1567 |
1568 struct TemplateLiteralState {}; | 1568 struct TemplateLiteralState {}; |
1569 | 1569 |
1570 TemplateLiteralState OpenTemplateLiteral(int pos) { | 1570 TemplateLiteralState OpenTemplateLiteral(int pos) { |
1571 return TemplateLiteralState(); | 1571 return TemplateLiteralState(); |
1572 } | 1572 } |
1573 void AddTemplateSpan(TemplateLiteralState*, bool) {} | 1573 void AddTemplateSpan(TemplateLiteralState*, bool) {} |
1574 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} | 1574 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} |
1575 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int, | 1575 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int, |
1576 PreParserExpression tag) { | 1576 PreParserExpression tag) { |
1577 if (IsTaggedTemplate(tag)) { | 1577 if (IsTaggedTemplate(tag)) { |
1578 // Emulate generation of array literals for tag callsite | 1578 // Emulate generation of array literals for tag callsite |
1579 // 1st is array of cooked strings, second is array of raw strings | 1579 // 1st is array of cooked strings, second is array of raw strings |
1580 MaterializeTemplateCallsiteLiterals(); | 1580 MaterializeTemplateCallsiteLiterals(); |
1581 } | 1581 } |
1582 return EmptyExpression(); | 1582 return EmptyExpression(); |
1583 } | 1583 } |
1584 inline void MaterializeTemplateCallsiteLiterals(); | 1584 inline void MaterializeTemplateCallsiteLiterals(); |
1585 PreParserExpression NoTemplateTag() { | 1585 PreParserExpression NoTemplateTag() { |
1586 return PreParserExpression::NoTemplateTag(); | 1586 return PreParserExpression::NoTemplateTag(); |
1587 } | 1587 } |
1588 static bool IsTaggedTemplate(const PreParserExpression tag) { | 1588 static bool IsTaggedTemplate(const PreParserExpression tag) { |
1589 return !tag.IsNoTemplateTag(); | 1589 return !tag.IsNoTemplateTag(); |
1590 } | 1590 } |
1591 | 1591 |
| 1592 int DeclareFormalParameters(PreParserFormalParameterList params, Scope* scope, |
| 1593 bool has_rest) { |
| 1594 return params->length(); |
| 1595 } |
| 1596 |
1592 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} | 1597 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} |
1593 | 1598 |
1594 // Temporary glue; these functions will move to ParserBase. | 1599 // Temporary glue; these functions will move to ParserBase. |
1595 PreParserExpression ParseV8Intrinsic(bool* ok); | 1600 PreParserExpression ParseV8Intrinsic(bool* ok); |
1596 PreParserExpression ParseFunctionLiteral( | 1601 PreParserExpression ParseFunctionLiteral( |
1597 PreParserIdentifier name, Scanner::Location function_name_location, | 1602 PreParserIdentifier name, Scanner::Location function_name_location, |
1598 bool name_is_strict_reserved, FunctionKind kind, | 1603 bool name_is_strict_reserved, FunctionKind kind, |
1599 int function_token_position, FunctionLiteral::FunctionType type, | 1604 int function_token_position, FunctionLiteral::FunctionType type, |
1600 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); | 1605 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); |
1601 | 1606 |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1770 return pre_parser_->factory()->NewCall(function, args, pos); | 1775 return pre_parser_->factory()->NewCall(function, args, pos); |
1771 } | 1776 } |
1772 | 1777 |
1773 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, | 1778 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, |
1774 PreParserExpressionList args, | 1779 PreParserExpressionList args, |
1775 int pos) { | 1780 int pos) { |
1776 return pre_parser_->factory()->NewCallNew(function, args, pos); | 1781 return pre_parser_->factory()->NewCallNew(function, args, pos); |
1777 } | 1782 } |
1778 | 1783 |
1779 | 1784 |
| 1785 PreParserFormalParameterList |
| 1786 PreParserTraits::ParseArrowFunctionFormalParameterList( |
| 1787 PreParserExpression params, const Scanner::Location& params_loc, |
| 1788 FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok) { |
| 1789 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter |
| 1790 // lists that are too long. |
| 1791 if (!params.IsValidArrowParamList(error_locs, params_loc)) { |
| 1792 *ok = false; |
| 1793 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); |
| 1794 return this->NullFormalParameterList(); |
| 1795 } |
| 1796 |
| 1797 return PreParserFormalParameterList(); |
| 1798 } |
| 1799 |
| 1800 |
1780 PreParserStatementList PreParser::ParseEagerFunctionBody( | 1801 PreParserStatementList PreParser::ParseEagerFunctionBody( |
1781 PreParserIdentifier function_name, int pos, Variable* fvar, | 1802 PreParserIdentifier function_name, int pos, Variable* fvar, |
1782 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { | 1803 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { |
1783 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1804 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
1784 | 1805 |
1785 ParseStatementList(Token::RBRACE, ok); | 1806 ParseStatementList(Token::RBRACE, ok); |
1786 if (!*ok) return PreParserStatementList(); | 1807 if (!*ok) return PreParserStatementList(); |
1787 | 1808 |
1788 Expect(Token::RBRACE, ok); | 1809 Expect(Token::RBRACE, ok); |
1789 return PreParserStatementList(); | 1810 return PreParserStatementList(); |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2065 case Token::LBRACK: | 2086 case Token::LBRACK: |
2066 result = this->ParseArrayLiteral(CHECK_OK); | 2087 result = this->ParseArrayLiteral(CHECK_OK); |
2067 break; | 2088 break; |
2068 | 2089 |
2069 case Token::LBRACE: | 2090 case Token::LBRACE: |
2070 result = this->ParseObjectLiteral(CHECK_OK); | 2091 result = this->ParseObjectLiteral(CHECK_OK); |
2071 break; | 2092 break; |
2072 | 2093 |
2073 case Token::LPAREN: | 2094 case Token::LPAREN: |
2074 Consume(Token::LPAREN); | 2095 Consume(Token::LPAREN); |
2075 if (allow_harmony_arrow_functions() && peek() == Token::RPAREN) { | 2096 if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) { |
2076 // Arrow functions are the only expression type constructions | 2097 // As a primary expression, the only thing that can follow "()" is "=>". |
2077 // for which an empty parameter list "()" is valid input. | 2098 FormalParameterListT params = this->NewFormalParameterList(0, zone()); |
2078 Consume(Token::RPAREN); | 2099 FormalParameterErrorLocations error_locs; |
2079 result = this->ParseArrowFunctionLiteral( | 2100 bool has_rest = false; |
2080 beg_pos, this->EmptyArrowParamList(), CHECK_OK); | 2101 result = this->ParseArrowFunctionLiteral(beg_pos, params, error_locs, |
| 2102 has_rest, CHECK_OK); |
2081 } else { | 2103 } else { |
2082 // Heuristically try to detect immediately called functions before | 2104 // Heuristically try to detect immediately called functions before |
2083 // seeing the call parentheses. | 2105 // seeing the call parentheses. |
2084 parenthesized_function_ = (peek() == Token::FUNCTION); | 2106 parenthesized_function_ = (peek() == Token::FUNCTION); |
2085 result = this->ParseExpression(true, CHECK_OK); | 2107 result = this->ParseExpression(true, CHECK_OK); |
2086 result->increase_parenthesization_level(); | 2108 result->increase_parenthesization_level(); |
2087 Expect(Token::RPAREN, CHECK_OK); | 2109 Expect(Token::RPAREN, CHECK_OK); |
2088 } | 2110 } |
2089 break; | 2111 break; |
2090 | 2112 |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2528 return this->ParseYieldExpression(ok); | 2550 return this->ParseYieldExpression(ok); |
2529 } | 2551 } |
2530 | 2552 |
2531 if (fni_ != NULL) fni_->Enter(); | 2553 if (fni_ != NULL) fni_->Enter(); |
2532 ParserBase<Traits>::Checkpoint checkpoint(this); | 2554 ParserBase<Traits>::Checkpoint checkpoint(this); |
2533 ExpressionT expression = | 2555 ExpressionT expression = |
2534 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 2556 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
2535 | 2557 |
2536 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { | 2558 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { |
2537 checkpoint.Restore(); | 2559 checkpoint.Restore(); |
2538 expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos, | 2560 FormalParameterErrorLocations error_locs; |
2539 expression, CHECK_OK); | 2561 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); |
| 2562 bool has_rest = false; |
| 2563 FormalParameterListT params = this->ParseArrowFunctionFormalParameterList( |
| 2564 expression, loc, &error_locs, &has_rest, CHECK_OK); |
| 2565 expression = this->ParseArrowFunctionLiteral( |
| 2566 lhs_location.beg_pos, params, error_locs, has_rest, CHECK_OK); |
2540 return expression; | 2567 return expression; |
2541 } | 2568 } |
2542 | 2569 |
2543 if (!Token::IsAssignmentOp(peek())) { | 2570 if (!Token::IsAssignmentOp(peek())) { |
2544 if (fni_ != NULL) fni_->Leave(); | 2571 if (fni_ != NULL) fni_->Leave(); |
2545 // Parsed conditional expression only (no assignment). | 2572 // Parsed conditional expression only (no assignment). |
2546 return expression; | 2573 return expression; |
2547 } | 2574 } |
2548 | 2575 |
2549 expression = this->CheckAndRewriteReferenceExpression( | 2576 expression = this->CheckAndRewriteReferenceExpression( |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3078 // Store locations for possible future error reports. | 3105 // Store locations for possible future error reports. |
3079 if (!locs->eval_or_arguments_.IsValid() && this->IsEvalOrArguments(name)) { | 3106 if (!locs->eval_or_arguments_.IsValid() && this->IsEvalOrArguments(name)) { |
3080 locs->eval_or_arguments_ = scanner()->location(); | 3107 locs->eval_or_arguments_ = scanner()->location(); |
3081 } | 3108 } |
3082 if (!locs->undefined_.IsValid() && this->IsUndefined(name)) { | 3109 if (!locs->undefined_.IsValid() && this->IsUndefined(name)) { |
3083 locs->undefined_ = scanner()->location(); | 3110 locs->undefined_ = scanner()->location(); |
3084 } | 3111 } |
3085 if (!locs->reserved_.IsValid() && is_strict_reserved) { | 3112 if (!locs->reserved_.IsValid() && is_strict_reserved) { |
3086 locs->reserved_ = scanner()->location(); | 3113 locs->reserved_ = scanner()->location(); |
3087 } | 3114 } |
3088 if (!locs->duplicate_.IsValid()) { | 3115 if (!locs->duplicate_.IsValid() && duplicate_finder != nullptr) { |
3089 int prev_value = scanner()->FindSymbol(duplicate_finder, 1); | 3116 int prev_value = scanner()->FindSymbol(duplicate_finder, 1); |
3090 if (prev_value != 0) locs->duplicate_ = scanner()->location(); | 3117 if (prev_value != 0) locs->duplicate_ = scanner()->location(); |
3091 } | 3118 } |
3092 | 3119 |
3093 return name; | 3120 return name; |
3094 } | 3121 } |
3095 | 3122 |
3096 | 3123 |
3097 template <class Traits> | 3124 template <class Traits> |
3098 typename ParserBase<Traits>::FormalParameterListT | 3125 typename ParserBase<Traits>::FormalParameterListT |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3157 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), | 3184 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), |
3158 "bad_setter_arity"); | 3185 "bad_setter_arity"); |
3159 *ok = false; | 3186 *ok = false; |
3160 } | 3187 } |
3161 break; | 3188 break; |
3162 default: | 3189 default: |
3163 break; | 3190 break; |
3164 } | 3191 } |
3165 } | 3192 } |
3166 | 3193 |
| 3194 |
3167 template <class Traits> | 3195 template <class Traits> |
3168 typename ParserBase<Traits>::ExpressionT | 3196 typename ParserBase<Traits>::ExpressionT |
3169 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, | 3197 ParserBase<Traits>::ParseArrowFunctionLiteral( |
3170 ExpressionT params_ast, | 3198 int start_pos, FormalParameterListT params, |
3171 bool* ok) { | 3199 const FormalParameterErrorLocations& error_locs, bool has_rest, bool* ok) { |
3172 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3200 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
3173 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3201 // ASI inserts `;` after arrow parameters if a line terminator is found. |
3174 // `=> ...` is never a valid expression, so report as syntax error. | 3202 // `=> ...` is never a valid expression, so report as syntax error. |
3175 // If next token is not `=>`, it's a syntax error anyways. | 3203 // If next token is not `=>`, it's a syntax error anyways. |
3176 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3204 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
3177 *ok = false; | 3205 *ok = false; |
3178 return this->EmptyExpression(); | 3206 return this->EmptyExpression(); |
3179 } | 3207 } |
3180 | 3208 |
3181 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); | 3209 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); |
3182 typename Traits::Type::StatementList body; | 3210 typename Traits::Type::StatementList body; |
3183 int num_parameters = -1; | 3211 int num_parameters = -1; |
3184 int materialized_literal_count = -1; | 3212 int materialized_literal_count = -1; |
3185 int expected_property_count = -1; | 3213 int expected_property_count = -1; |
3186 int handler_count = 0; | 3214 int handler_count = 0; |
3187 Scanner::Location super_loc; | 3215 Scanner::Location super_loc; |
3188 | 3216 |
3189 { | 3217 { |
3190 typename Traits::Type::Factory function_factory(ast_value_factory()); | 3218 typename Traits::Type::Factory function_factory(ast_value_factory()); |
3191 FunctionState function_state(&function_state_, &scope_, scope, | 3219 FunctionState function_state(&function_state_, &scope_, scope, |
3192 kArrowFunction, &function_factory); | 3220 kArrowFunction, &function_factory); |
3193 FormalParameterErrorLocations error_locs; | 3221 num_parameters = this->DeclareFormalParameters(params, scope_, has_rest); |
3194 num_parameters = Traits::DeclareArrowParametersFromExpression( | |
3195 params_ast, scope_, &error_locs, ok); | |
3196 if (!*ok) { | |
3197 ReportMessageAt( | |
3198 Scanner::Location(start_pos, scanner()->location().beg_pos), | |
3199 "malformed_arrow_function_parameter_list"); | |
3200 return this->EmptyExpression(); | |
3201 } | |
3202 | |
3203 if (error_locs.undefined_.IsValid()) { | |
3204 // Workaround for preparser not keeping track of positions. | |
3205 error_locs.undefined_ = | |
3206 Scanner::Location(start_pos, scanner()->location().end_pos); | |
3207 } | |
3208 if (num_parameters > Code::kMaxArguments) { | |
3209 ReportMessageAt(Scanner::Location(params_ast->position(), position()), | |
3210 "too_many_parameters"); | |
3211 *ok = false; | |
3212 return this->EmptyExpression(); | |
3213 } | |
3214 | 3222 |
3215 Expect(Token::ARROW, CHECK_OK); | 3223 Expect(Token::ARROW, CHECK_OK); |
3216 | 3224 |
3217 if (peek() == Token::LBRACE) { | 3225 if (peek() == Token::LBRACE) { |
3218 // Multiple statement body | 3226 // Multiple statement body |
3219 Consume(Token::LBRACE); | 3227 Consume(Token::LBRACE); |
3220 bool is_lazily_parsed = | 3228 bool is_lazily_parsed = |
3221 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); | 3229 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); |
3222 if (is_lazily_parsed) { | 3230 if (is_lazily_parsed) { |
3223 body = this->NewStatementList(0, zone()); | 3231 body = this->NewStatementList(0, zone()); |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3461 *ok = false; | 3469 *ok = false; |
3462 return; | 3470 return; |
3463 } | 3471 } |
3464 has_seen_constructor_ = true; | 3472 has_seen_constructor_ = true; |
3465 return; | 3473 return; |
3466 } | 3474 } |
3467 } | 3475 } |
3468 } } // v8::internal | 3476 } } // v8::internal |
3469 | 3477 |
3470 #endif // V8_PREPARSER_H | 3478 #endif // V8_PREPARSER_H |
OLD | NEW |