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