| 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" |
| 11 #include "src/func-name-inferrer.h" | 11 #include "src/func-name-inferrer.h" |
| 12 #include "src/hashmap.h" | 12 #include "src/hashmap.h" |
| 13 #include "src/scanner.h" | 13 #include "src/scanner.h" |
| 14 #include "src/scopes.h" | 14 #include "src/scopes.h" |
| 15 #include "src/token.h" | 15 #include "src/token.h" |
| 16 | 16 |
| 17 namespace v8 { | 17 namespace v8 { |
| 18 namespace internal { | 18 namespace internal { |
| 19 | 19 |
| 20 | |
| 21 // When parsing the formal parameters of a function, we usually don't yet know | |
| 22 // if the function will be strict, so we cannot yet produce errors for | |
| 23 // parameter names or duplicates. Instead, we remember the locations of these | |
| 24 // errors if they occur and produce the errors later. | |
| 25 class FormalParameterErrorLocations BASE_EMBEDDED { | |
| 26 public: | |
| 27 FormalParameterErrorLocations() | |
| 28 : eval_or_arguments(Scanner::Location::invalid()), | |
| 29 undefined(Scanner::Location::invalid()), | |
| 30 duplicate(Scanner::Location::invalid()), | |
| 31 reserved(Scanner::Location::invalid()) {} | |
| 32 | |
| 33 Scanner::Location eval_or_arguments; | |
| 34 Scanner::Location undefined; | |
| 35 Scanner::Location duplicate; | |
| 36 Scanner::Location reserved; | |
| 37 }; | |
| 38 | |
| 39 | |
| 40 // Common base class shared between parser and pre-parser. Traits encapsulate | 20 // Common base class shared between parser and pre-parser. Traits encapsulate |
| 41 // the differences between Parser and PreParser: | 21 // the differences between Parser and PreParser: |
| 42 | 22 |
| 43 // - Return types: For example, Parser functions return Expression* and | 23 // - Return types: For example, Parser functions return Expression* and |
| 44 // PreParser functions return PreParserExpression. | 24 // PreParser functions return PreParserExpression. |
| 45 | 25 |
| 46 // - Creating parse tree nodes: Parser generates an AST during the recursive | 26 // - Creating parse tree nodes: Parser generates an AST during the recursive |
| 47 // descent. PreParser doesn't create a tree. Instead, it passes around minimal | 27 // descent. PreParser doesn't create a tree. Instead, it passes around minimal |
| 48 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain | 28 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain |
| 49 // just enough data for the upper layer functions. PreParserFactory is | 29 // just enough data for the upper layer functions. PreParserFactory is |
| (...skipping 14 matching lines...) Expand all Loading... |
| 64 // typedef GeneratorVariable; | 44 // typedef GeneratorVariable; |
| 65 // // Return types for traversing functions. | 45 // // Return types for traversing functions. |
| 66 // typedef Identifier; | 46 // typedef Identifier; |
| 67 // typedef Expression; | 47 // typedef Expression; |
| 68 // typedef FunctionLiteral; | 48 // typedef FunctionLiteral; |
| 69 // typedef ClassLiteral; | 49 // typedef ClassLiteral; |
| 70 // typedef ObjectLiteralProperty; | 50 // typedef ObjectLiteralProperty; |
| 71 // typedef Literal; | 51 // typedef Literal; |
| 72 // typedef ExpressionList; | 52 // typedef ExpressionList; |
| 73 // typedef PropertyList; | 53 // typedef PropertyList; |
| 74 // typedef FormalParameter; | |
| 75 // typedef FormalParameterList; | |
| 76 // // For constructing objects returned by the traversing functions. | 54 // // For constructing objects returned by the traversing functions. |
| 77 // typedef Factory; | 55 // typedef Factory; |
| 78 // }; | 56 // }; |
| 79 // // ... | 57 // // ... |
| 80 // }; | 58 // }; |
| 81 | 59 |
| 82 template <typename Traits> | 60 template <typename Traits> |
| 83 class ParserBase : public Traits { | 61 class ParserBase : public Traits { |
| 84 public: | 62 public: |
| 85 // Shorten type names defined by Traits. | 63 // Shorten type names defined by Traits. |
| 86 typedef typename Traits::Type::Expression ExpressionT; | 64 typedef typename Traits::Type::Expression ExpressionT; |
| 87 typedef typename Traits::Type::Identifier IdentifierT; | 65 typedef typename Traits::Type::Identifier IdentifierT; |
| 88 typedef typename Traits::Type::FormalParameter FormalParameterT; | |
| 89 typedef typename Traits::Type::FormalParameterList FormalParameterListT; | |
| 90 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; | 66 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; |
| 91 typedef typename Traits::Type::Literal LiteralT; | 67 typedef typename Traits::Type::Literal LiteralT; |
| 92 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; | 68 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; |
| 93 | 69 |
| 94 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, | 70 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, |
| 95 v8::Extension* extension, AstValueFactory* ast_value_factory, | 71 v8::Extension* extension, AstValueFactory* ast_value_factory, |
| 96 ParserRecorder* log, typename Traits::Type::Parser this_object) | 72 ParserRecorder* log, typename Traits::Type::Parser this_object) |
| 97 : Traits(this_object), | 73 : Traits(this_object), |
| 98 parenthesized_function_(false), | 74 parenthesized_function_(false), |
| 99 scope_(NULL), | 75 scope_(NULL), |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 Traits::ReportMessageAt(function_name_loc, "strong_undefined"); | 488 Traits::ReportMessageAt(function_name_loc, "strong_undefined"); |
| 513 *ok = false; | 489 *ok = false; |
| 514 return; | 490 return; |
| 515 } | 491 } |
| 516 } | 492 } |
| 517 | 493 |
| 518 // Checking the parameter names of a function literal. This has to be done | 494 // Checking the parameter names of a function literal. This has to be done |
| 519 // after parsing the function, since the function can declare itself strict. | 495 // after parsing the function, since the function can declare itself strict. |
| 520 void CheckFunctionParameterNames(LanguageMode language_mode, | 496 void CheckFunctionParameterNames(LanguageMode language_mode, |
| 521 bool strict_params, | 497 bool strict_params, |
| 522 const FormalParameterErrorLocations& locs, | 498 const Scanner::Location& eval_args_loc, |
| 499 const Scanner::Location& undefined_loc, |
| 500 const Scanner::Location& dupe_loc, |
| 501 const Scanner::Location& reserved_loc, |
| 523 bool* ok) { | 502 bool* ok) { |
| 524 if (is_sloppy(language_mode) && !strict_params) return; | 503 if (is_sloppy(language_mode) && !strict_params) return; |
| 525 if (is_strict(language_mode) && locs.eval_or_arguments.IsValid()) { | 504 if (is_strict(language_mode) && eval_args_loc.IsValid()) { |
| 526 Traits::ReportMessageAt(locs.eval_or_arguments, "strict_eval_arguments"); | 505 Traits::ReportMessageAt(eval_args_loc, "strict_eval_arguments"); |
| 527 *ok = false; | 506 *ok = false; |
| 528 return; | 507 return; |
| 529 } | 508 } |
| 530 if (is_strict(language_mode) && locs.reserved.IsValid()) { | 509 if (is_strong(language_mode) && undefined_loc.IsValid()) { |
| 531 Traits::ReportMessageAt(locs.reserved, "unexpected_strict_reserved"); | 510 Traits::ReportMessageAt(undefined_loc, "strong_undefined"); |
| 532 *ok = false; | |
| 533 return; | |
| 534 } | |
| 535 if (is_strong(language_mode) && locs.undefined.IsValid()) { | |
| 536 Traits::ReportMessageAt(locs.undefined, "strong_undefined"); | |
| 537 *ok = false; | 511 *ok = false; |
| 538 return; | 512 return; |
| 539 } | 513 } |
| 540 // TODO(arv): When we add support for destructuring in setters we also need | 514 // TODO(arv): When we add support for destructuring in setters we also need |
| 541 // to check for duplicate names. | 515 // to check for duplicate names. |
| 542 if (locs.duplicate.IsValid()) { | 516 if (dupe_loc.IsValid()) { |
| 543 Traits::ReportMessageAt(locs.duplicate, "strict_param_dupe"); | 517 Traits::ReportMessageAt(dupe_loc, "strict_param_dupe"); |
| 544 *ok = false; | 518 *ok = false; |
| 545 return; | 519 return; |
| 546 } | 520 } |
| 521 if (reserved_loc.IsValid()) { |
| 522 Traits::ReportMessageAt(reserved_loc, "unexpected_strict_reserved"); |
| 523 *ok = false; |
| 524 return; |
| 525 } |
| 547 } | 526 } |
| 548 | 527 |
| 549 // Determine precedence of given token. | 528 // Determine precedence of given token. |
| 550 static int Precedence(Token::Value token, bool accept_IN) { | 529 static int Precedence(Token::Value token, bool accept_IN) { |
| 551 if (token == Token::IN && !accept_IN) | 530 if (token == Token::IN && !accept_IN) |
| 552 return 0; // 0 precedence will terminate binary expression parsing | 531 return 0; // 0 precedence will terminate binary expression parsing |
| 553 return Token::Precedence(token); | 532 return Token::Precedence(token); |
| 554 } | 533 } |
| 555 | 534 |
| 556 typename Traits::Type::Factory* factory() { | 535 typename Traits::Type::Factory* factory() { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 ExpressionT ParseYieldExpression(bool* ok); | 593 ExpressionT ParseYieldExpression(bool* ok); |
| 615 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 594 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
| 616 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 595 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
| 617 ExpressionT ParseUnaryExpression(bool* ok); | 596 ExpressionT ParseUnaryExpression(bool* ok); |
| 618 ExpressionT ParsePostfixExpression(bool* ok); | 597 ExpressionT ParsePostfixExpression(bool* ok); |
| 619 ExpressionT ParseLeftHandSideExpression(bool* ok); | 598 ExpressionT ParseLeftHandSideExpression(bool* ok); |
| 620 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 599 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
| 621 ExpressionT ParseMemberExpression(bool* ok); | 600 ExpressionT ParseMemberExpression(bool* ok); |
| 622 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 601 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
| 623 bool* ok); | 602 bool* ok); |
| 624 ExpressionT ParseArrowFunctionLiteral( | 603 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, |
| 625 int start_pos, FormalParameterListT params, | 604 bool* ok); |
| 626 const FormalParameterErrorLocations& error_locs, bool has_rest, bool* ok); | |
| 627 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 605 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
| 628 void AddTemplateExpression(ExpressionT); | 606 void AddTemplateExpression(ExpressionT); |
| 629 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 607 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
| 630 | 608 |
| 631 FormalParameterT ParseFormalParameter(DuplicateFinder* duplicate_finder, | |
| 632 FormalParameterErrorLocations* locs, | |
| 633 bool* ok); | |
| 634 FormalParameterListT ParseFormalParameterList( | |
| 635 FormalParameterErrorLocations* locs, bool* is_rest, bool* ok); | |
| 636 void CheckArityRestrictions( | |
| 637 int param_count, FunctionLiteral::ArityRestriction arity_restriction, | |
| 638 int formals_start_pos, int formals_end_pos, bool* ok); | |
| 639 | |
| 640 // Checks if the expression is a valid reference expression (e.g., on the | 609 // Checks if the expression is a valid reference expression (e.g., on the |
| 641 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 610 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
| 642 // we allow calls for web compatibility and rewrite them to a runtime throw. | 611 // we allow calls for web compatibility and rewrite them to a runtime throw. |
| 643 ExpressionT CheckAndRewriteReferenceExpression( | 612 ExpressionT CheckAndRewriteReferenceExpression( |
| 644 ExpressionT expression, | 613 ExpressionT expression, |
| 645 Scanner::Location location, const char* message, bool* ok); | 614 Scanner::Location location, const char* message, bool* ok); |
| 646 | 615 |
| 647 // Used to validate property names in object literals and class literals | 616 // Used to validate property names in object literals and class literals |
| 648 enum PropertyKind { | 617 enum PropertyKind { |
| 649 kAccessorProperty, | 618 kAccessorProperty, |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 839 ValidArrowParam valid_arrow_param_list = | 808 ValidArrowParam valid_arrow_param_list = |
| 840 (op == Token::COMMA && !left.is_parenthesized() && | 809 (op == Token::COMMA && !left.is_parenthesized() && |
| 841 !right.is_parenthesized()) ? | 810 !right.is_parenthesized()) ? |
| 842 std::min(left.ValidateArrowParams(), right.ValidateArrowParams()) | 811 std::min(left.ValidateArrowParams(), right.ValidateArrowParams()) |
| 843 : kInvalidArrowParam; | 812 : kInvalidArrowParam; |
| 844 return PreParserExpression( | 813 return PreParserExpression( |
| 845 TypeField::encode(kBinaryOperationExpression) | | 814 TypeField::encode(kBinaryOperationExpression) | |
| 846 IsValidArrowParamListField::encode(valid_arrow_param_list)); | 815 IsValidArrowParamListField::encode(valid_arrow_param_list)); |
| 847 } | 816 } |
| 848 | 817 |
| 818 static PreParserExpression EmptyArrowParamList() { |
| 819 // Any expression for which IsValidArrowParamList() returns true |
| 820 // will work here. |
| 821 return FromIdentifier(PreParserIdentifier::Default()); |
| 822 } |
| 823 |
| 849 static PreParserExpression StringLiteral() { | 824 static PreParserExpression StringLiteral() { |
| 850 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); | 825 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); |
| 851 } | 826 } |
| 852 | 827 |
| 853 static PreParserExpression UseStrictStringLiteral() { | 828 static PreParserExpression UseStrictStringLiteral() { |
| 854 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | | 829 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | |
| 855 IsUseStrictField::encode(true)); | 830 IsUseStrictField::encode(true)); |
| 856 } | 831 } |
| 857 | 832 |
| 858 static PreParserExpression UseStrongStringLiteral() { | 833 static PreParserExpression UseStrongStringLiteral() { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 929 | 904 |
| 930 bool IsCall() const { | 905 bool IsCall() const { |
| 931 return TypeField::decode(code_) == kExpression && | 906 return TypeField::decode(code_) == kExpression && |
| 932 ExpressionTypeField::decode(code_) == kCallExpression; | 907 ExpressionTypeField::decode(code_) == kCallExpression; |
| 933 } | 908 } |
| 934 | 909 |
| 935 bool IsValidReferenceExpression() const { | 910 bool IsValidReferenceExpression() const { |
| 936 return IsIdentifier() || IsProperty(); | 911 return IsIdentifier() || IsProperty(); |
| 937 } | 912 } |
| 938 | 913 |
| 939 bool IsValidArrowParamList(FormalParameterErrorLocations* locs, | 914 bool IsValidArrowParamList(Scanner::Location* undefined_loc) const { |
| 940 const Scanner::Location& params_loc) const { | |
| 941 ValidArrowParam valid = ValidateArrowParams(); | 915 ValidArrowParam valid = ValidateArrowParams(); |
| 942 if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) { | 916 if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) { |
| 943 return false; | 917 return false; |
| 944 } | 918 } |
| 945 switch (valid) { | 919 if (valid == kValidArrowParam) { |
| 946 case kInvalidArrowParam: | 920 return true; |
| 947 return false; | 921 } else if (valid == kInvalidStrongArrowParam) { |
| 948 case kInvalidStrongArrowParam: | 922 // Return true for now regardless of strong mode for compatibility with |
| 949 locs->undefined = params_loc; | 923 // parser. |
| 950 return true; | 924 *undefined_loc = Scanner::Location(); |
| 951 case kInvalidStrictReservedArrowParam: | 925 return true; |
| 952 locs->reserved = params_loc; | 926 } else { |
| 953 return true; | 927 return false; |
| 954 case kInvalidStrictEvalArgumentsArrowParam: | |
| 955 locs->eval_or_arguments = params_loc; | |
| 956 return true; | |
| 957 default: | |
| 958 DCHECK_EQ(valid, kValidArrowParam); | |
| 959 return true; | |
| 960 } | 928 } |
| 961 } | 929 } |
| 962 | 930 |
| 963 // At the moment PreParser doesn't track these expression types. | 931 // At the moment PreParser doesn't track these expression types. |
| 964 bool IsFunctionLiteral() const { return false; } | 932 bool IsFunctionLiteral() const { return false; } |
| 965 bool IsCallNew() const { return false; } | 933 bool IsCallNew() const { return false; } |
| 966 | 934 |
| 967 bool IsNoTemplateTag() const { | 935 bool IsNoTemplateTag() const { |
| 968 return TypeField::decode(code_) == kExpression && | 936 return TypeField::decode(code_) == kExpression && |
| 969 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; | 937 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1016 }; | 984 }; |
| 1017 | 985 |
| 1018 enum ExpressionType { | 986 enum ExpressionType { |
| 1019 kThisExpression, | 987 kThisExpression, |
| 1020 kThisPropertyExpression, | 988 kThisPropertyExpression, |
| 1021 kPropertyExpression, | 989 kPropertyExpression, |
| 1022 kCallExpression, | 990 kCallExpression, |
| 1023 kNoTemplateTagExpression | 991 kNoTemplateTagExpression |
| 1024 }; | 992 }; |
| 1025 | 993 |
| 1026 // These validity constraints are ordered such that a value of N implies lack | |
| 1027 // of errors M < N. | |
| 1028 enum ValidArrowParam { | 994 enum ValidArrowParam { |
| 1029 kInvalidArrowParam, | 995 kInvalidArrowParam, |
| 1030 kInvalidStrictEvalArgumentsArrowParam, | |
| 1031 kInvalidStrictReservedArrowParam, | |
| 1032 kInvalidStrongArrowParam, | 996 kInvalidStrongArrowParam, |
| 1033 kValidArrowParam | 997 kValidArrowParam |
| 1034 }; | 998 }; |
| 1035 | 999 |
| 1036 explicit PreParserExpression(uint32_t expression_code) | 1000 explicit PreParserExpression(uint32_t expression_code) |
| 1037 : code_(expression_code) {} | 1001 : code_(expression_code) {} |
| 1038 | 1002 |
| 1039 V8_INLINE ValidArrowParam ValidateArrowParams() const { | 1003 V8_INLINE ValidArrowParam ValidateArrowParams() const { |
| 1040 if (IsBinaryOperation()) { | 1004 if (IsBinaryOperation()) { |
| 1041 return IsValidArrowParamListField::decode(code_); | 1005 return IsValidArrowParamListField::decode(code_); |
| 1042 } | 1006 } |
| 1043 if (!IsIdentifier()) { | 1007 if (!IsIdentifier()) { |
| 1044 return kInvalidArrowParam; | 1008 return kInvalidArrowParam; |
| 1045 } | 1009 } |
| 1046 PreParserIdentifier ident = AsIdentifier(); | 1010 PreParserIdentifier ident = AsIdentifier(); |
| 1047 // In strict mode, eval and arguments are not valid formal parameter names. | 1011 // A valid identifier can be an arrow function parameter |
| 1048 if (ident.IsEval() || ident.IsArguments()) { | 1012 // except for eval, arguments, yield, and reserved keywords. |
| 1049 return kInvalidStrictEvalArgumentsArrowParam; | 1013 if (ident.IsEval() || ident.IsArguments() || |
| 1014 ident.IsFutureStrictReserved()) { |
| 1015 return kInvalidArrowParam; |
| 1050 } | 1016 } |
| 1051 // In strict mode, future reserved words are not valid either, and as they | 1017 // In strong mode, 'undefined' is similarly restricted. |
| 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. | |
| 1057 if (ident.IsUndefined()) { | 1018 if (ident.IsUndefined()) { |
| 1058 return kInvalidStrongArrowParam; | 1019 return kInvalidStrongArrowParam; |
| 1059 } | 1020 } |
| 1060 return kValidArrowParam; | 1021 return kValidArrowParam; |
| 1061 } | 1022 } |
| 1062 | 1023 |
| 1063 // The first five bits are for the Type and Parenthesization. | 1024 // The first five bits are for the Type and Parenthesization. |
| 1064 typedef BitField<Type, 0, 3> TypeField; | 1025 typedef BitField<Type, 0, 3> TypeField; |
| 1065 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; | 1026 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; |
| 1066 | 1027 |
| 1067 // The rest of the bits are interpreted depending on the value | 1028 // The rest of the bits are interpreted depending on the value |
| 1068 // of the Type field, so they can share the storage. | 1029 // of the Type field, so they can share the storage. |
| 1069 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> | 1030 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> |
| 1070 ExpressionTypeField; | 1031 ExpressionTypeField; |
| 1071 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; | 1032 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; |
| 1072 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 1033 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
| 1073 typedef BitField<ValidArrowParam, ParenthesizationField::kNext, 3> | 1034 typedef BitField<ValidArrowParam, ParenthesizationField::kNext, 2> |
| 1074 IsValidArrowParamListField; | 1035 IsValidArrowParamListField; |
| 1075 typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10> | 1036 typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10> |
| 1076 IdentifierTypeField; | 1037 IdentifierTypeField; |
| 1077 | 1038 |
| 1078 uint32_t code_; | 1039 uint32_t code_; |
| 1079 }; | 1040 }; |
| 1080 | 1041 |
| 1081 | 1042 |
| 1082 // The pre-parser doesn't need to build lists of expressions, identifiers, or | 1043 // PreParserExpressionList doesn't actually store the expressions because |
| 1083 // the like. | 1044 // PreParser doesn't need to. |
| 1084 template <typename T> | 1045 class PreParserExpressionList { |
| 1085 class PreParserList { | |
| 1086 public: | 1046 public: |
| 1087 // These functions make list->Add(some_expression) work (and do nothing). | 1047 // These functions make list->Add(some_expression) work (and do nothing). |
| 1088 PreParserList() : length_(0) {} | 1048 PreParserExpressionList() : length_(0) {} |
| 1089 PreParserList* operator->() { return this; } | 1049 PreParserExpressionList* operator->() { return this; } |
| 1090 void Add(T, void*) { ++length_; } | 1050 void Add(PreParserExpression, void*) { ++length_; } |
| 1091 int length() const { return length_; } | 1051 int length() const { return length_; } |
| 1092 private: | 1052 private: |
| 1093 int length_; | 1053 int length_; |
| 1094 }; | 1054 }; |
| 1095 | 1055 |
| 1096 | 1056 |
| 1097 typedef PreParserList<PreParserExpression> PreParserExpressionList; | |
| 1098 typedef PreParserList<PreParserIdentifier> PreParserFormalParameterList; | |
| 1099 | |
| 1100 | |
| 1101 class PreParserStatement { | 1057 class PreParserStatement { |
| 1102 public: | 1058 public: |
| 1103 static PreParserStatement Default() { | 1059 static PreParserStatement Default() { |
| 1104 return PreParserStatement(kUnknownStatement); | 1060 return PreParserStatement(kUnknownStatement); |
| 1105 } | 1061 } |
| 1106 | 1062 |
| 1107 static PreParserStatement Jump() { | 1063 static PreParserStatement Jump() { |
| 1108 return PreParserStatement(kJumpStatement); | 1064 return PreParserStatement(kJumpStatement); |
| 1109 } | 1065 } |
| 1110 | 1066 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1155 kUseStrictExpressionStatement, | 1111 kUseStrictExpressionStatement, |
| 1156 kUseStrongExpressionStatement, | 1112 kUseStrongExpressionStatement, |
| 1157 kFunctionDeclaration | 1113 kFunctionDeclaration |
| 1158 }; | 1114 }; |
| 1159 | 1115 |
| 1160 explicit PreParserStatement(Type code) : code_(code) {} | 1116 explicit PreParserStatement(Type code) : code_(code) {} |
| 1161 Type code_; | 1117 Type code_; |
| 1162 }; | 1118 }; |
| 1163 | 1119 |
| 1164 | 1120 |
| 1165 typedef PreParserList<PreParserStatement> PreParserStatementList; | 1121 |
| 1122 // PreParserStatementList doesn't actually store the statements because |
| 1123 // the PreParser does not need them. |
| 1124 class PreParserStatementList { |
| 1125 public: |
| 1126 // These functions make list->Add(some_expression) work as no-ops. |
| 1127 PreParserStatementList() {} |
| 1128 PreParserStatementList* operator->() { return this; } |
| 1129 void Add(PreParserStatement, void*) {} |
| 1130 }; |
| 1166 | 1131 |
| 1167 | 1132 |
| 1168 class PreParserFactory { | 1133 class PreParserFactory { |
| 1169 public: | 1134 public: |
| 1170 explicit PreParserFactory(void* unused_value_factory) {} | 1135 explicit PreParserFactory(void* unused_value_factory) {} |
| 1171 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, | 1136 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, |
| 1172 int pos) { | 1137 int pos) { |
| 1173 return PreParserExpression::Default(); | 1138 return PreParserExpression::Default(); |
| 1174 } | 1139 } |
| 1175 PreParserExpression NewNumberLiteral(double number, | 1140 PreParserExpression NewNumberLiteral(double number, |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1320 // Return types for traversing functions. | 1285 // Return types for traversing functions. |
| 1321 typedef PreParserIdentifier Identifier; | 1286 typedef PreParserIdentifier Identifier; |
| 1322 typedef PreParserExpression Expression; | 1287 typedef PreParserExpression Expression; |
| 1323 typedef PreParserExpression YieldExpression; | 1288 typedef PreParserExpression YieldExpression; |
| 1324 typedef PreParserExpression FunctionLiteral; | 1289 typedef PreParserExpression FunctionLiteral; |
| 1325 typedef PreParserExpression ClassLiteral; | 1290 typedef PreParserExpression ClassLiteral; |
| 1326 typedef PreParserExpression ObjectLiteralProperty; | 1291 typedef PreParserExpression ObjectLiteralProperty; |
| 1327 typedef PreParserExpression Literal; | 1292 typedef PreParserExpression Literal; |
| 1328 typedef PreParserExpressionList ExpressionList; | 1293 typedef PreParserExpressionList ExpressionList; |
| 1329 typedef PreParserExpressionList PropertyList; | 1294 typedef PreParserExpressionList PropertyList; |
| 1330 typedef PreParserIdentifier FormalParameter; | |
| 1331 typedef PreParserFormalParameterList FormalParameterList; | |
| 1332 typedef PreParserStatementList StatementList; | 1295 typedef PreParserStatementList StatementList; |
| 1333 | 1296 |
| 1334 // For constructing objects returned by the traversing functions. | 1297 // For constructing objects returned by the traversing functions. |
| 1335 typedef PreParserFactory Factory; | 1298 typedef PreParserFactory Factory; |
| 1336 }; | 1299 }; |
| 1337 | 1300 |
| 1338 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} | 1301 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} |
| 1339 | 1302 |
| 1340 // Helper functions for recursive descent. | 1303 // Helper functions for recursive descent. |
| 1341 static bool IsEval(PreParserIdentifier identifier) { | 1304 static bool IsEval(PreParserIdentifier identifier) { |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1465 // "null" return type creators. | 1428 // "null" return type creators. |
| 1466 static PreParserIdentifier EmptyIdentifier() { | 1429 static PreParserIdentifier EmptyIdentifier() { |
| 1467 return PreParserIdentifier::Default(); | 1430 return PreParserIdentifier::Default(); |
| 1468 } | 1431 } |
| 1469 static PreParserIdentifier EmptyIdentifierString() { | 1432 static PreParserIdentifier EmptyIdentifierString() { |
| 1470 return PreParserIdentifier::Default(); | 1433 return PreParserIdentifier::Default(); |
| 1471 } | 1434 } |
| 1472 static PreParserExpression EmptyExpression() { | 1435 static PreParserExpression EmptyExpression() { |
| 1473 return PreParserExpression::Default(); | 1436 return PreParserExpression::Default(); |
| 1474 } | 1437 } |
| 1438 static PreParserExpression EmptyArrowParamList() { |
| 1439 return PreParserExpression::EmptyArrowParamList(); |
| 1440 } |
| 1475 static PreParserExpression EmptyLiteral() { | 1441 static PreParserExpression EmptyLiteral() { |
| 1476 return PreParserExpression::Default(); | 1442 return PreParserExpression::Default(); |
| 1477 } | 1443 } |
| 1478 static PreParserExpression EmptyObjectLiteralProperty() { | 1444 static PreParserExpression EmptyObjectLiteralProperty() { |
| 1479 return PreParserExpression::Default(); | 1445 return PreParserExpression::Default(); |
| 1480 } | 1446 } |
| 1481 static PreParserExpression EmptyFunctionLiteral() { | 1447 static PreParserExpression EmptyFunctionLiteral() { |
| 1482 return PreParserExpression::Default(); | 1448 return PreParserExpression::Default(); |
| 1483 } | 1449 } |
| 1484 static PreParserExpressionList NullExpressionList() { | 1450 static PreParserExpressionList NullExpressionList() { |
| 1485 return PreParserExpressionList(); | 1451 return PreParserExpressionList(); |
| 1486 } | 1452 } |
| 1487 static PreParserIdentifier EmptyFormalParameter() { | |
| 1488 return PreParserIdentifier::Default(); | |
| 1489 } | |
| 1490 static PreParserFormalParameterList NullFormalParameterList() { | |
| 1491 return PreParserFormalParameterList(); | |
| 1492 } | |
| 1493 | 1453 |
| 1494 // Odd-ball literal creators. | 1454 // Odd-ball literal creators. |
| 1495 static PreParserExpression GetLiteralTheHole(int position, | 1455 static PreParserExpression GetLiteralTheHole(int position, |
| 1496 PreParserFactory* factory) { | 1456 PreParserFactory* factory) { |
| 1497 return PreParserExpression::Default(); | 1457 return PreParserExpression::Default(); |
| 1498 } | 1458 } |
| 1499 | 1459 |
| 1500 // Producing data during the recursive descent. | 1460 // Producing data during the recursive descent. |
| 1501 PreParserIdentifier GetSymbol(Scanner* scanner); | 1461 PreParserIdentifier GetSymbol(Scanner* scanner); |
| 1502 PreParserIdentifier GetNumberAsSymbol(Scanner* scanner); | 1462 PreParserIdentifier GetNumberAsSymbol(Scanner* scanner); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1547 } | 1507 } |
| 1548 | 1508 |
| 1549 static PreParserStatementList NewStatementList(int size, Zone* zone) { | 1509 static PreParserStatementList NewStatementList(int size, Zone* zone) { |
| 1550 return PreParserStatementList(); | 1510 return PreParserStatementList(); |
| 1551 } | 1511 } |
| 1552 | 1512 |
| 1553 static PreParserExpressionList NewPropertyList(int size, Zone* zone) { | 1513 static PreParserExpressionList NewPropertyList(int size, Zone* zone) { |
| 1554 return PreParserExpressionList(); | 1514 return PreParserExpressionList(); |
| 1555 } | 1515 } |
| 1556 | 1516 |
| 1557 static PreParserFormalParameterList NewFormalParameterList(int size, | |
| 1558 Zone* zone) { | |
| 1559 return PreParserFormalParameterList(); | |
| 1560 } | |
| 1561 | |
| 1562 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name, | 1517 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name, |
| 1563 int* materialized_literal_count, | 1518 int* materialized_literal_count, |
| 1564 int* expected_property_count, bool* ok) { | 1519 int* expected_property_count, bool* ok) { |
| 1565 UNREACHABLE(); | 1520 UNREACHABLE(); |
| 1566 } | 1521 } |
| 1567 | 1522 |
| 1568 V8_INLINE PreParserStatementList | 1523 V8_INLINE PreParserStatementList |
| 1569 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, | 1524 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
| 1570 Variable* fvar, Token::Value fvar_init_op, | 1525 Variable* fvar, Token::Value fvar_init_op, |
| 1571 FunctionKind kind, bool* ok); | 1526 FunctionKind kind, bool* ok); |
| 1572 | 1527 |
| 1573 V8_INLINE PreParserFormalParameterList ParseArrowFunctionFormalParameterList( | 1528 // Utility functions |
| 1574 PreParserExpression expression, const Scanner::Location& params_loc, | 1529 int DeclareArrowParametersFromExpression(PreParserExpression expression, |
| 1575 FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok); | 1530 Scope* scope, |
| 1531 Scanner::Location* undefined_loc, |
| 1532 Scanner::Location* dupe_loc, |
| 1533 bool* ok) { |
| 1534 // TODO(aperez): Detect duplicated identifiers in paramlists. |
| 1535 *ok = expression.IsValidArrowParamList(undefined_loc); |
| 1536 return 0; |
| 1537 } |
| 1576 | 1538 |
| 1577 struct TemplateLiteralState {}; | 1539 struct TemplateLiteralState {}; |
| 1578 | 1540 |
| 1579 TemplateLiteralState OpenTemplateLiteral(int pos) { | 1541 TemplateLiteralState OpenTemplateLiteral(int pos) { |
| 1580 return TemplateLiteralState(); | 1542 return TemplateLiteralState(); |
| 1581 } | 1543 } |
| 1582 void AddTemplateSpan(TemplateLiteralState*, bool) {} | 1544 void AddTemplateSpan(TemplateLiteralState*, bool) {} |
| 1583 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} | 1545 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} |
| 1584 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int, | 1546 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int, |
| 1585 PreParserExpression tag) { | 1547 PreParserExpression tag) { |
| 1586 if (IsTaggedTemplate(tag)) { | 1548 if (IsTaggedTemplate(tag)) { |
| 1587 // Emulate generation of array literals for tag callsite | 1549 // Emulate generation of array literals for tag callsite |
| 1588 // 1st is array of cooked strings, second is array of raw strings | 1550 // 1st is array of cooked strings, second is array of raw strings |
| 1589 MaterializeTemplateCallsiteLiterals(); | 1551 MaterializeTemplateCallsiteLiterals(); |
| 1590 } | 1552 } |
| 1591 return EmptyExpression(); | 1553 return EmptyExpression(); |
| 1592 } | 1554 } |
| 1593 inline void MaterializeTemplateCallsiteLiterals(); | 1555 inline void MaterializeTemplateCallsiteLiterals(); |
| 1594 PreParserExpression NoTemplateTag() { | 1556 PreParserExpression NoTemplateTag() { |
| 1595 return PreParserExpression::NoTemplateTag(); | 1557 return PreParserExpression::NoTemplateTag(); |
| 1596 } | 1558 } |
| 1597 static bool IsTaggedTemplate(const PreParserExpression tag) { | 1559 static bool IsTaggedTemplate(const PreParserExpression tag) { |
| 1598 return !tag.IsNoTemplateTag(); | 1560 return !tag.IsNoTemplateTag(); |
| 1599 } | 1561 } |
| 1600 | 1562 |
| 1601 int DeclareFormalParameters(PreParserFormalParameterList params, Scope* scope, | |
| 1602 bool has_rest) { | |
| 1603 return params->length(); | |
| 1604 } | |
| 1605 | |
| 1606 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} | 1563 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} |
| 1607 | 1564 |
| 1608 // Temporary glue; these functions will move to ParserBase. | 1565 // Temporary glue; these functions will move to ParserBase. |
| 1609 PreParserExpression ParseV8Intrinsic(bool* ok); | 1566 PreParserExpression ParseV8Intrinsic(bool* ok); |
| 1610 PreParserExpression ParseFunctionLiteral( | 1567 PreParserExpression ParseFunctionLiteral( |
| 1611 PreParserIdentifier name, Scanner::Location function_name_location, | 1568 PreParserIdentifier name, Scanner::Location function_name_location, |
| 1612 bool name_is_strict_reserved, FunctionKind kind, | 1569 bool name_is_strict_reserved, FunctionKind kind, |
| 1613 int function_token_position, FunctionLiteral::FunctionType type, | 1570 int function_token_position, FunctionLiteral::FunctionType type, |
| 1614 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); | 1571 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); |
| 1615 | 1572 |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1784 return pre_parser_->factory()->NewCall(function, args, pos); | 1741 return pre_parser_->factory()->NewCall(function, args, pos); |
| 1785 } | 1742 } |
| 1786 | 1743 |
| 1787 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, | 1744 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, |
| 1788 PreParserExpressionList args, | 1745 PreParserExpressionList args, |
| 1789 int pos) { | 1746 int pos) { |
| 1790 return pre_parser_->factory()->NewCallNew(function, args, pos); | 1747 return pre_parser_->factory()->NewCallNew(function, args, pos); |
| 1791 } | 1748 } |
| 1792 | 1749 |
| 1793 | 1750 |
| 1794 PreParserFormalParameterList | |
| 1795 PreParserTraits::ParseArrowFunctionFormalParameterList( | |
| 1796 PreParserExpression params, const Scanner::Location& params_loc, | |
| 1797 FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok) { | |
| 1798 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter | |
| 1799 // lists that are too long. | |
| 1800 if (!params.IsValidArrowParamList(error_locs, params_loc)) { | |
| 1801 *ok = false; | |
| 1802 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); | |
| 1803 return this->NullFormalParameterList(); | |
| 1804 } | |
| 1805 | |
| 1806 return PreParserFormalParameterList(); | |
| 1807 } | |
| 1808 | |
| 1809 | |
| 1810 PreParserStatementList PreParser::ParseEagerFunctionBody( | 1751 PreParserStatementList PreParser::ParseEagerFunctionBody( |
| 1811 PreParserIdentifier function_name, int pos, Variable* fvar, | 1752 PreParserIdentifier function_name, int pos, Variable* fvar, |
| 1812 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { | 1753 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { |
| 1813 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1754 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 1814 | 1755 |
| 1815 ParseStatementList(Token::RBRACE, ok); | 1756 ParseStatementList(Token::RBRACE, ok); |
| 1816 if (!*ok) return PreParserStatementList(); | 1757 if (!*ok) return PreParserStatementList(); |
| 1817 | 1758 |
| 1818 Expect(Token::RBRACE, ok); | 1759 Expect(Token::RBRACE, ok); |
| 1819 return PreParserStatementList(); | 1760 return PreParserStatementList(); |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2095 case Token::LBRACK: | 2036 case Token::LBRACK: |
| 2096 result = this->ParseArrayLiteral(CHECK_OK); | 2037 result = this->ParseArrayLiteral(CHECK_OK); |
| 2097 break; | 2038 break; |
| 2098 | 2039 |
| 2099 case Token::LBRACE: | 2040 case Token::LBRACE: |
| 2100 result = this->ParseObjectLiteral(CHECK_OK); | 2041 result = this->ParseObjectLiteral(CHECK_OK); |
| 2101 break; | 2042 break; |
| 2102 | 2043 |
| 2103 case Token::LPAREN: | 2044 case Token::LPAREN: |
| 2104 Consume(Token::LPAREN); | 2045 Consume(Token::LPAREN); |
| 2105 if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) { | 2046 if (allow_harmony_arrow_functions() && peek() == Token::RPAREN) { |
| 2106 // As a primary expression, the only thing that can follow "()" is "=>". | 2047 // Arrow functions are the only expression type constructions |
| 2107 FormalParameterListT params = this->NewFormalParameterList(0, zone()); | 2048 // for which an empty parameter list "()" is valid input. |
| 2108 FormalParameterErrorLocations error_locs; | 2049 Consume(Token::RPAREN); |
| 2109 bool has_rest = false; | 2050 result = this->ParseArrowFunctionLiteral( |
| 2110 result = this->ParseArrowFunctionLiteral(beg_pos, params, error_locs, | 2051 beg_pos, this->EmptyArrowParamList(), CHECK_OK); |
| 2111 has_rest, CHECK_OK); | |
| 2112 } else { | 2052 } else { |
| 2113 // Heuristically try to detect immediately called functions before | 2053 // Heuristically try to detect immediately called functions before |
| 2114 // seeing the call parentheses. | 2054 // seeing the call parentheses. |
| 2115 parenthesized_function_ = (peek() == Token::FUNCTION); | 2055 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 2116 result = this->ParseExpression(true, CHECK_OK); | 2056 result = this->ParseExpression(true, CHECK_OK); |
| 2117 result->increase_parenthesization_level(); | 2057 result->increase_parenthesization_level(); |
| 2118 Expect(Token::RPAREN, CHECK_OK); | 2058 Expect(Token::RPAREN, CHECK_OK); |
| 2119 } | 2059 } |
| 2120 break; | 2060 break; |
| 2121 | 2061 |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2559 return this->ParseYieldExpression(ok); | 2499 return this->ParseYieldExpression(ok); |
| 2560 } | 2500 } |
| 2561 | 2501 |
| 2562 if (fni_ != NULL) fni_->Enter(); | 2502 if (fni_ != NULL) fni_->Enter(); |
| 2563 ParserBase<Traits>::Checkpoint checkpoint(this); | 2503 ParserBase<Traits>::Checkpoint checkpoint(this); |
| 2564 ExpressionT expression = | 2504 ExpressionT expression = |
| 2565 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 2505 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
| 2566 | 2506 |
| 2567 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { | 2507 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { |
| 2568 checkpoint.Restore(); | 2508 checkpoint.Restore(); |
| 2569 FormalParameterErrorLocations error_locs; | 2509 expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos, |
| 2570 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); | 2510 expression, CHECK_OK); |
| 2571 bool has_rest = false; | |
| 2572 FormalParameterListT params = this->ParseArrowFunctionFormalParameterList( | |
| 2573 expression, loc, &error_locs, &has_rest, CHECK_OK); | |
| 2574 expression = this->ParseArrowFunctionLiteral( | |
| 2575 lhs_location.beg_pos, params, error_locs, has_rest, CHECK_OK); | |
| 2576 return expression; | 2511 return expression; |
| 2577 } | 2512 } |
| 2578 | 2513 |
| 2579 if (!Token::IsAssignmentOp(peek())) { | 2514 if (!Token::IsAssignmentOp(peek())) { |
| 2580 if (fni_ != NULL) fni_->Leave(); | 2515 if (fni_ != NULL) fni_->Leave(); |
| 2581 // Parsed conditional expression only (no assignment). | 2516 // Parsed conditional expression only (no assignment). |
| 2582 return expression; | 2517 return expression; |
| 2583 } | 2518 } |
| 2584 | 2519 |
| 2585 expression = this->CheckAndRewriteReferenceExpression( | 2520 expression = this->CheckAndRewriteReferenceExpression( |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3099 default: | 3034 default: |
| 3100 return expression; | 3035 return expression; |
| 3101 } | 3036 } |
| 3102 } | 3037 } |
| 3103 DCHECK(false); | 3038 DCHECK(false); |
| 3104 return this->EmptyExpression(); | 3039 return this->EmptyExpression(); |
| 3105 } | 3040 } |
| 3106 | 3041 |
| 3107 | 3042 |
| 3108 template <class Traits> | 3043 template <class Traits> |
| 3109 typename ParserBase<Traits>::FormalParameterT | |
| 3110 ParserBase<Traits>::ParseFormalParameter(DuplicateFinder* duplicate_finder, | |
| 3111 FormalParameterErrorLocations* locs, | |
| 3112 bool* ok) { | |
| 3113 // FormalParameter[Yield,GeneratorParameter] : | |
| 3114 // BindingElement[?Yield, ?GeneratorParameter] | |
| 3115 bool is_strict_reserved; | |
| 3116 IdentifierT name = | |
| 3117 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, ok); | |
| 3118 if (!*ok) return this->EmptyFormalParameter(); | |
| 3119 | |
| 3120 // Store locations for possible future error reports. | |
| 3121 if (!locs->eval_or_arguments.IsValid() && this->IsEvalOrArguments(name)) { | |
| 3122 locs->eval_or_arguments = scanner()->location(); | |
| 3123 } | |
| 3124 if (!locs->undefined.IsValid() && this->IsUndefined(name)) { | |
| 3125 locs->undefined = scanner()->location(); | |
| 3126 } | |
| 3127 if (!locs->reserved.IsValid() && is_strict_reserved) { | |
| 3128 locs->reserved = scanner()->location(); | |
| 3129 } | |
| 3130 if (!locs->duplicate.IsValid() && duplicate_finder != nullptr) { | |
| 3131 int prev_value = scanner()->FindSymbol(duplicate_finder, 1); | |
| 3132 if (prev_value != 0) locs->duplicate = scanner()->location(); | |
| 3133 } | |
| 3134 | |
| 3135 return name; | |
| 3136 } | |
| 3137 | |
| 3138 | |
| 3139 template <class Traits> | |
| 3140 typename ParserBase<Traits>::FormalParameterListT | |
| 3141 ParserBase<Traits>::ParseFormalParameterList( | |
| 3142 FormalParameterErrorLocations* locs, bool* is_rest, bool* ok) { | |
| 3143 // FormalParameters[Yield,GeneratorParameter] : | |
| 3144 // [empty] | |
| 3145 // FormalParameterList[?Yield, ?GeneratorParameter] | |
| 3146 // | |
| 3147 // FormalParameterList[Yield,GeneratorParameter] : | |
| 3148 // FunctionRestParameter[?Yield] | |
| 3149 // FormalsList[?Yield, ?GeneratorParameter] | |
| 3150 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield] | |
| 3151 // | |
| 3152 // FormalsList[Yield,GeneratorParameter] : | |
| 3153 // FormalParameter[?Yield, ?GeneratorParameter] | |
| 3154 // FormalsList[?Yield, ?GeneratorParameter] , | |
| 3155 // FormalParameter[?Yield,?GeneratorParameter] | |
| 3156 | |
| 3157 FormalParameterListT result = this->NewFormalParameterList(4, zone_); | |
| 3158 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); | |
| 3159 | |
| 3160 if (peek() != Token::RPAREN) { | |
| 3161 do { | |
| 3162 *is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS); | |
| 3163 FormalParameterT param = | |
| 3164 ParseFormalParameter(&duplicate_finder, locs, ok); | |
| 3165 if (!*ok) return this->NullFormalParameterList(); | |
| 3166 result->Add(param, zone()); | |
| 3167 if (result->length() > Code::kMaxArguments) { | |
| 3168 ReportMessage("too_many_parameters"); | |
| 3169 *ok = false; | |
| 3170 return this->NullFormalParameterList(); | |
| 3171 } | |
| 3172 } while (!*is_rest && Check(Token::COMMA)); | |
| 3173 } | |
| 3174 | |
| 3175 if (is_rest && peek() == Token::COMMA) { | |
| 3176 ReportMessageAt(scanner()->peek_location(), "param_after_rest"); | |
| 3177 *ok = false; | |
| 3178 return this->NullFormalParameterList(); | |
| 3179 } | |
| 3180 | |
| 3181 return result; | |
| 3182 } | |
| 3183 | |
| 3184 | |
| 3185 template <class Traits> | |
| 3186 void ParserBase<Traits>::CheckArityRestrictions( | |
| 3187 int param_count, FunctionLiteral::ArityRestriction arity_restriction, | |
| 3188 int formals_start_pos, int formals_end_pos, bool* ok) { | |
| 3189 switch (arity_restriction) { | |
| 3190 case FunctionLiteral::GETTER_ARITY: | |
| 3191 if (param_count != 0) { | |
| 3192 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), | |
| 3193 "bad_getter_arity"); | |
| 3194 *ok = false; | |
| 3195 } | |
| 3196 break; | |
| 3197 case FunctionLiteral::SETTER_ARITY: | |
| 3198 if (param_count != 1) { | |
| 3199 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), | |
| 3200 "bad_setter_arity"); | |
| 3201 *ok = false; | |
| 3202 } | |
| 3203 break; | |
| 3204 default: | |
| 3205 break; | |
| 3206 } | |
| 3207 } | |
| 3208 | |
| 3209 | |
| 3210 template <class Traits> | |
| 3211 typename ParserBase<Traits>::ExpressionT | 3044 typename ParserBase<Traits>::ExpressionT |
| 3212 ParserBase<Traits>::ParseArrowFunctionLiteral( | 3045 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, |
| 3213 int start_pos, FormalParameterListT params, | 3046 ExpressionT params_ast, |
| 3214 const FormalParameterErrorLocations& error_locs, bool has_rest, bool* ok) { | 3047 bool* ok) { |
| 3215 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3048 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
| 3216 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3049 // ASI inserts `;` after arrow parameters if a line terminator is found. |
| 3217 // `=> ...` is never a valid expression, so report as syntax error. | 3050 // `=> ...` is never a valid expression, so report as syntax error. |
| 3218 // If next token is not `=>`, it's a syntax error anyways. | 3051 // If next token is not `=>`, it's a syntax error anyways. |
| 3219 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3052 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
| 3220 *ok = false; | 3053 *ok = false; |
| 3221 return this->EmptyExpression(); | 3054 return this->EmptyExpression(); |
| 3222 } | 3055 } |
| 3223 | 3056 |
| 3224 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); | 3057 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); |
| 3225 typename Traits::Type::StatementList body; | 3058 typename Traits::Type::StatementList body; |
| 3226 int num_parameters = -1; | 3059 int num_parameters = -1; |
| 3227 int materialized_literal_count = -1; | 3060 int materialized_literal_count = -1; |
| 3228 int expected_property_count = -1; | 3061 int expected_property_count = -1; |
| 3229 int handler_count = 0; | 3062 int handler_count = 0; |
| 3230 Scanner::Location super_loc; | 3063 Scanner::Location super_loc; |
| 3231 | 3064 |
| 3232 { | 3065 { |
| 3233 typename Traits::Type::Factory function_factory(ast_value_factory()); | 3066 typename Traits::Type::Factory function_factory(ast_value_factory()); |
| 3234 FunctionState function_state(&function_state_, &scope_, scope, | 3067 FunctionState function_state(&function_state_, &scope_, scope, |
| 3235 kArrowFunction, &function_factory); | 3068 kArrowFunction, &function_factory); |
| 3236 num_parameters = this->DeclareFormalParameters(params, scope_, has_rest); | 3069 Scanner::Location undefined_loc = Scanner::Location::invalid(); |
| 3070 Scanner::Location dupe_loc = Scanner::Location::invalid(); |
| 3071 // TODO(arv): Pass in eval_args_loc and reserved_loc here. |
| 3072 num_parameters = Traits::DeclareArrowParametersFromExpression( |
| 3073 params_ast, scope_, &undefined_loc, &dupe_loc, ok); |
| 3074 if (!*ok) { |
| 3075 ReportMessageAt( |
| 3076 Scanner::Location(start_pos, scanner()->location().beg_pos), |
| 3077 "malformed_arrow_function_parameter_list"); |
| 3078 return this->EmptyExpression(); |
| 3079 } |
| 3080 |
| 3081 if (undefined_loc.IsValid()) { |
| 3082 // Workaround for preparser not keeping track of positions. |
| 3083 undefined_loc = Scanner::Location(start_pos, |
| 3084 scanner()->location().end_pos); |
| 3085 } |
| 3086 if (num_parameters > Code::kMaxArguments) { |
| 3087 ReportMessageAt(Scanner::Location(params_ast->position(), position()), |
| 3088 "too_many_parameters"); |
| 3089 *ok = false; |
| 3090 return this->EmptyExpression(); |
| 3091 } |
| 3237 | 3092 |
| 3238 Expect(Token::ARROW, CHECK_OK); | 3093 Expect(Token::ARROW, CHECK_OK); |
| 3239 | 3094 |
| 3240 if (peek() == Token::LBRACE) { | 3095 if (peek() == Token::LBRACE) { |
| 3241 // Multiple statement body | 3096 // Multiple statement body |
| 3242 Consume(Token::LBRACE); | 3097 Consume(Token::LBRACE); |
| 3243 bool is_lazily_parsed = | 3098 bool is_lazily_parsed = |
| 3244 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); | 3099 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); |
| 3245 if (is_lazily_parsed) { | 3100 if (is_lazily_parsed) { |
| 3246 body = this->NewStatementList(0, zone()); | 3101 body = this->NewStatementList(0, zone()); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3265 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3120 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
| 3266 materialized_literal_count = function_state.materialized_literal_count(); | 3121 materialized_literal_count = function_state.materialized_literal_count(); |
| 3267 expected_property_count = function_state.expected_property_count(); | 3122 expected_property_count = function_state.expected_property_count(); |
| 3268 handler_count = function_state.handler_count(); | 3123 handler_count = function_state.handler_count(); |
| 3269 } | 3124 } |
| 3270 super_loc = function_state.super_call_location(); | 3125 super_loc = function_state.super_call_location(); |
| 3271 | 3126 |
| 3272 scope->set_start_position(start_pos); | 3127 scope->set_start_position(start_pos); |
| 3273 scope->set_end_position(scanner()->location().end_pos); | 3128 scope->set_end_position(scanner()->location().end_pos); |
| 3274 | 3129 |
| 3275 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 3130 // Arrow function *parameter lists* are always checked as in strict mode. |
| 3276 // which is not the same as "parameters of a strict function"; it only means | 3131 // TODO(arv): eval_args_loc and reserved_loc needs to be set by |
| 3277 // that duplicates are not allowed. Of course, the arrow function may | 3132 // DeclareArrowParametersFromExpression. |
| 3278 // itself be strict as well. | 3133 Scanner::Location eval_args_loc = Scanner::Location::invalid(); |
| 3134 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
| 3279 const bool use_strict_params = true; | 3135 const bool use_strict_params = true; |
| 3280 this->CheckFunctionParameterNames(language_mode(), use_strict_params, | 3136 this->CheckFunctionParameterNames(language_mode(), use_strict_params, |
| 3281 error_locs, CHECK_OK); | 3137 eval_args_loc, undefined_loc, dupe_loc, |
| 3138 reserved_loc, CHECK_OK); |
| 3282 | 3139 |
| 3283 // Validate strict mode. | 3140 // Validate strict mode. |
| 3284 if (is_strict(language_mode())) { | 3141 if (is_strict(language_mode())) { |
| 3285 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos, | 3142 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos, |
| 3286 CHECK_OK); | 3143 CHECK_OK); |
| 3287 this->CheckConflictingVarDeclarations(scope, CHECK_OK); | 3144 this->CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 3288 } | 3145 } |
| 3289 } | 3146 } |
| 3290 | 3147 |
| 3291 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3148 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3484 *ok = false; | 3341 *ok = false; |
| 3485 return; | 3342 return; |
| 3486 } | 3343 } |
| 3487 has_seen_constructor_ = true; | 3344 has_seen_constructor_ = true; |
| 3488 return; | 3345 return; |
| 3489 } | 3346 } |
| 3490 } | 3347 } |
| 3491 } } // v8::internal | 3348 } } // v8::internal |
| 3492 | 3349 |
| 3493 #endif // V8_PREPARSER_H | 3350 #endif // V8_PREPARSER_H |
| OLD | NEW |