| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #ifndef V8_PREPARSER_H | 28 #ifndef V8_PREPARSER_H |
| 29 #define V8_PREPARSER_H | 29 #define V8_PREPARSER_H |
| 30 | 30 |
| 31 #include "hashmap.h" | 31 #include "hashmap.h" |
| 32 #include "scopes.h" | 32 #include "scopes.h" |
| 33 #include "token.h" | 33 #include "token.h" |
| 34 #include "scanner.h" | 34 #include "scanner.h" |
| 35 #include "v8.h" |
| 35 | 36 |
| 36 namespace v8 { | 37 namespace v8 { |
| 37 namespace internal { | 38 namespace internal { |
| 38 | 39 |
| 39 // Common base class shared between parser and pre-parser. | 40 // Common base class shared between parser and pre-parser. |
| 40 template <typename Traits> | 41 template <typename Traits> |
| 41 class ParserBase : public Traits { | 42 class ParserBase : public Traits { |
| 42 public: | 43 public: |
| 43 ParserBase(Scanner* scanner, uintptr_t stack_limit, | 44 ParserBase(Scanner* scanner, uintptr_t stack_limit, |
| 45 v8::Extension* extension, |
| 44 typename Traits::Type::Parser this_object) | 46 typename Traits::Type::Parser this_object) |
| 45 : Traits(this_object), | 47 : Traits(this_object), |
| 46 parenthesized_function_(false), | 48 parenthesized_function_(false), |
| 47 scope_(NULL), | 49 scope_(NULL), |
| 48 function_state_(NULL), | 50 function_state_(NULL), |
| 51 extension_(extension), |
| 49 scanner_(scanner), | 52 scanner_(scanner), |
| 50 stack_limit_(stack_limit), | 53 stack_limit_(stack_limit), |
| 51 stack_overflow_(false), | 54 stack_overflow_(false), |
| 52 allow_lazy_(false), | 55 allow_lazy_(false), |
| 53 allow_natives_syntax_(false), | 56 allow_natives_syntax_(false), |
| 54 allow_generators_(false), | 57 allow_generators_(false), |
| 55 allow_for_of_(false) { } | 58 allow_for_of_(false) { } |
| 56 | 59 |
| 57 // Getters that indicate whether certain syntactical constructs are | 60 // Getters that indicate whether certain syntactical constructs are |
| 58 // allowed to be parsed by this instance of the parser. | 61 // allowed to be parsed by this instance of the parser. |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 typename Traits::Type::Identifier ParseIdentifierOrStrictReservedWord( | 325 typename Traits::Type::Identifier ParseIdentifierOrStrictReservedWord( |
| 323 bool* is_strict_reserved, | 326 bool* is_strict_reserved, |
| 324 bool* ok); | 327 bool* ok); |
| 325 typename Traits::Type::Identifier ParseIdentifierName(bool* ok); | 328 typename Traits::Type::Identifier ParseIdentifierName(bool* ok); |
| 326 // Parses an identifier and determines whether or not it is 'get' or 'set'. | 329 // Parses an identifier and determines whether or not it is 'get' or 'set'. |
| 327 typename Traits::Type::Identifier ParseIdentifierNameOrGetOrSet(bool* is_get, | 330 typename Traits::Type::Identifier ParseIdentifierNameOrGetOrSet(bool* is_get, |
| 328 bool* is_set, | 331 bool* is_set, |
| 329 bool* ok); | 332 bool* ok); |
| 330 | 333 |
| 331 typename Traits::Type::Expression ParseRegExpLiteral(bool seen_equal, | 334 typename Traits::Type::Expression ParseRegExpLiteral(bool seen_equal, |
| 332 bool* ok); | 335 bool* ok); |
| 336 |
| 337 typename Traits::Type::Expression ParsePrimaryExpression(bool* ok); |
| 333 | 338 |
| 334 // Used to detect duplicates in object literals. Each of the values | 339 // Used to detect duplicates in object literals. Each of the values |
| 335 // kGetterProperty, kSetterProperty and kValueProperty represents | 340 // kGetterProperty, kSetterProperty and kValueProperty represents |
| 336 // a type of object literal property. When parsing a property, its | 341 // a type of object literal property. When parsing a property, its |
| 337 // type value is stored in the DuplicateFinder for the property name. | 342 // type value is stored in the DuplicateFinder for the property name. |
| 338 // Values are chosen so that having intersection bits means the there is | 343 // Values are chosen so that having intersection bits means the there is |
| 339 // an incompatibility. | 344 // an incompatibility. |
| 340 // I.e., you can add a getter to a property that already has a setter, since | 345 // I.e., you can add a getter to a property that already has a setter, since |
| 341 // kGetterProperty and kSetterProperty doesn't intersect, but not if it | 346 // kGetterProperty and kSetterProperty doesn't intersect, but not if it |
| 342 // already has a getter or a value. Adding the getter to an existing | 347 // already has a getter or a value. Adding the getter to an existing |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 }; | 391 }; |
| 387 | 392 |
| 388 // If true, the next (and immediately following) function literal is | 393 // If true, the next (and immediately following) function literal is |
| 389 // preceded by a parenthesis. | 394 // preceded by a parenthesis. |
| 390 // Heuristically that means that the function will be called immediately, | 395 // Heuristically that means that the function will be called immediately, |
| 391 // so never lazily compile it. | 396 // so never lazily compile it. |
| 392 bool parenthesized_function_; | 397 bool parenthesized_function_; |
| 393 | 398 |
| 394 typename Traits::Type::Scope* scope_; // Scope stack. | 399 typename Traits::Type::Scope* scope_; // Scope stack. |
| 395 FunctionState* function_state_; // Function state stack. | 400 FunctionState* function_state_; // Function state stack. |
| 401 v8::Extension* extension_; |
| 396 | 402 |
| 397 private: | 403 private: |
| 398 Scanner* scanner_; | 404 Scanner* scanner_; |
| 399 uintptr_t stack_limit_; | 405 uintptr_t stack_limit_; |
| 400 bool stack_overflow_; | 406 bool stack_overflow_; |
| 401 | 407 |
| 402 bool allow_lazy_; | 408 bool allow_lazy_; |
| 403 bool allow_natives_syntax_; | 409 bool allow_natives_syntax_; |
| 404 bool allow_generators_; | 410 bool allow_generators_; |
| 405 bool allow_for_of_; | 411 bool allow_for_of_; |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 634 | 640 |
| 635 // "null" return type creators. | 641 // "null" return type creators. |
| 636 static PreParserIdentifier EmptyIdentifier() { | 642 static PreParserIdentifier EmptyIdentifier() { |
| 637 return PreParserIdentifier::Default(); | 643 return PreParserIdentifier::Default(); |
| 638 } | 644 } |
| 639 static PreParserExpression EmptyExpression() { | 645 static PreParserExpression EmptyExpression() { |
| 640 return PreParserExpression::Default(); | 646 return PreParserExpression::Default(); |
| 641 } | 647 } |
| 642 | 648 |
| 643 // Producing data during the recursive descent. | 649 // Producing data during the recursive descent. |
| 644 PreParserIdentifier GetSymbol(); | 650 PreParserIdentifier GetSymbol(Scanner* scanner); |
| 645 static PreParserIdentifier NextLiteralString(PretenureFlag tenured) { | 651 static PreParserIdentifier NextLiteralString(Scanner* scanner, |
| 652 PretenureFlag tenured) { |
| 646 return PreParserIdentifier::Default(); | 653 return PreParserIdentifier::Default(); |
| 647 } | 654 } |
| 648 | 655 |
| 656 static PreParserExpression ThisExpression(PreParserScope* scope, |
| 657 PreParserFactory* factory) { |
| 658 return PreParserExpression::This(); |
| 659 } |
| 660 |
| 661 static PreParserExpression ExpressionFromLiteral( |
| 662 Token::Value token, int pos, Scanner* scanner, |
| 663 PreParserFactory* factory) { |
| 664 return PreParserExpression::Default(); |
| 665 } |
| 666 |
| 667 static PreParserExpression ExpressionFromIdentifier( |
| 668 PreParserIdentifier name, int pos, PreParserScope* scope, |
| 669 PreParserFactory* factory) { |
| 670 return PreParserExpression::FromIdentifier(name); |
| 671 } |
| 672 |
| 673 PreParserExpression ExpressionFromString(int pos, |
| 674 Scanner* scanner, |
| 675 PreParserFactory* factory = NULL); |
| 676 |
| 677 // Temporary glue; these functions will move to ParserBase. |
| 678 PreParserExpression ParseArrayLiteral(bool* ok); |
| 679 PreParserExpression ParseObjectLiteral(bool* ok); |
| 680 PreParserExpression ParseExpression(bool accept_IN, bool* ok); |
| 681 PreParserExpression ParseV8Intrinsic(bool* ok); |
| 682 |
| 649 private: | 683 private: |
| 650 PreParser* pre_parser_; | 684 PreParser* pre_parser_; |
| 651 }; | 685 }; |
| 652 | 686 |
| 653 | 687 |
| 654 // Preparsing checks a JavaScript program and emits preparse-data that helps | 688 // Preparsing checks a JavaScript program and emits preparse-data that helps |
| 655 // a later parsing to be faster. | 689 // a later parsing to be faster. |
| 656 // See preparse-data-format.h for the data format. | 690 // See preparse-data-format.h for the data format. |
| 657 | 691 |
| 658 // The PreParser checks that the syntax follows the grammar for JavaScript, | 692 // The PreParser checks that the syntax follows the grammar for JavaScript, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 669 typedef PreParserExpression Expression; | 703 typedef PreParserExpression Expression; |
| 670 | 704 |
| 671 enum PreParseResult { | 705 enum PreParseResult { |
| 672 kPreParseStackOverflow, | 706 kPreParseStackOverflow, |
| 673 kPreParseSuccess | 707 kPreParseSuccess |
| 674 }; | 708 }; |
| 675 | 709 |
| 676 PreParser(Scanner* scanner, | 710 PreParser(Scanner* scanner, |
| 677 ParserRecorder* log, | 711 ParserRecorder* log, |
| 678 uintptr_t stack_limit) | 712 uintptr_t stack_limit) |
| 679 : ParserBase<PreParserTraits>(scanner, stack_limit, this), | 713 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, this), |
| 680 log_(log) {} | 714 log_(log) {} |
| 681 | 715 |
| 682 // Pre-parse the program from the character stream; returns true on | 716 // Pre-parse the program from the character stream; returns true on |
| 683 // success (even if parsing failed, the pre-parse data successfully | 717 // success (even if parsing failed, the pre-parse data successfully |
| 684 // captured the syntax error), and false if a stack-overflow happened | 718 // captured the syntax error), and false if a stack-overflow happened |
| 685 // during parsing. | 719 // during parsing. |
| 686 PreParseResult PreParseProgram() { | 720 PreParseResult PreParseProgram() { |
| 687 PreParserScope scope(scope_, GLOBAL_SCOPE); | 721 PreParserScope scope(scope_, GLOBAL_SCOPE); |
| 688 FunctionState top_scope(&function_state_, &scope_, &scope, NULL); | 722 FunctionState top_scope(&function_state_, &scope_, &scope, NULL); |
| 689 bool ok = true; | 723 bool ok = true; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 816 Expression ParseAssignmentExpression(bool accept_IN, bool* ok); | 850 Expression ParseAssignmentExpression(bool accept_IN, bool* ok); |
| 817 Expression ParseYieldExpression(bool* ok); | 851 Expression ParseYieldExpression(bool* ok); |
| 818 Expression ParseConditionalExpression(bool accept_IN, bool* ok); | 852 Expression ParseConditionalExpression(bool accept_IN, bool* ok); |
| 819 Expression ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 853 Expression ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
| 820 Expression ParseUnaryExpression(bool* ok); | 854 Expression ParseUnaryExpression(bool* ok); |
| 821 Expression ParsePostfixExpression(bool* ok); | 855 Expression ParsePostfixExpression(bool* ok); |
| 822 Expression ParseLeftHandSideExpression(bool* ok); | 856 Expression ParseLeftHandSideExpression(bool* ok); |
| 823 Expression ParseNewExpression(bool* ok); | 857 Expression ParseNewExpression(bool* ok); |
| 824 Expression ParseMemberExpression(bool* ok); | 858 Expression ParseMemberExpression(bool* ok); |
| 825 Expression ParseMemberWithNewPrefixesExpression(unsigned new_count, bool* ok); | 859 Expression ParseMemberWithNewPrefixesExpression(unsigned new_count, bool* ok); |
| 826 Expression ParsePrimaryExpression(bool* ok); | |
| 827 Expression ParseArrayLiteral(bool* ok); | 860 Expression ParseArrayLiteral(bool* ok); |
| 828 Expression ParseObjectLiteral(bool* ok); | 861 Expression ParseObjectLiteral(bool* ok); |
| 829 Expression ParseV8Intrinsic(bool* ok); | 862 Expression ParseV8Intrinsic(bool* ok); |
| 830 | 863 |
| 831 Arguments ParseArguments(bool* ok); | 864 Arguments ParseArguments(bool* ok); |
| 832 Expression ParseFunctionLiteral( | 865 Expression ParseFunctionLiteral( |
| 833 Identifier name, | 866 Identifier name, |
| 834 Scanner::Location function_name_location, | 867 Scanner::Location function_name_location, |
| 835 bool name_is_strict_reserved, | 868 bool name_is_strict_reserved, |
| 836 bool is_generator, | 869 bool is_generator, |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 915 } | 948 } |
| 916 } | 949 } |
| 917 | 950 |
| 918 | 951 |
| 919 template<class Traits> | 952 template<class Traits> |
| 920 typename Traits::Type::Identifier ParserBase<Traits>::ParseIdentifier( | 953 typename Traits::Type::Identifier ParserBase<Traits>::ParseIdentifier( |
| 921 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, | 954 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, |
| 922 bool* ok) { | 955 bool* ok) { |
| 923 Token::Value next = Next(); | 956 Token::Value next = Next(); |
| 924 if (next == Token::IDENTIFIER) { | 957 if (next == Token::IDENTIFIER) { |
| 925 typename Traits::Type::Identifier name = this->GetSymbol(); | 958 typename Traits::Type::Identifier name = this->GetSymbol(scanner()); |
| 926 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && | 959 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && |
| 927 !is_classic_mode() && this->IsEvalOrArguments(name)) { | 960 !is_classic_mode() && this->IsEvalOrArguments(name)) { |
| 928 ReportMessageAt(scanner()->location(), "strict_eval_arguments"); | 961 ReportMessageAt(scanner()->location(), "strict_eval_arguments"); |
| 929 *ok = false; | 962 *ok = false; |
| 930 } | 963 } |
| 931 return name; | 964 return name; |
| 932 } else if (is_classic_mode() && (next == Token::FUTURE_STRICT_RESERVED_WORD || | 965 } else if (is_classic_mode() && (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 933 (next == Token::YIELD && !is_generator()))) { | 966 (next == Token::YIELD && !is_generator()))) { |
| 934 return this->GetSymbol(); | 967 return this->GetSymbol(scanner()); |
| 935 } else { | 968 } else { |
| 936 this->ReportUnexpectedToken(next); | 969 this->ReportUnexpectedToken(next); |
| 937 *ok = false; | 970 *ok = false; |
| 938 return Traits::EmptyIdentifier(); | 971 return Traits::EmptyIdentifier(); |
| 939 } | 972 } |
| 940 } | 973 } |
| 941 | 974 |
| 942 | 975 |
| 943 template <class Traits> | 976 template <class Traits> |
| 944 typename Traits::Type::Identifier ParserBase< | 977 typename Traits::Type::Identifier ParserBase< |
| 945 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, | 978 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, |
| 946 bool* ok) { | 979 bool* ok) { |
| 947 Token::Value next = Next(); | 980 Token::Value next = Next(); |
| 948 if (next == Token::IDENTIFIER) { | 981 if (next == Token::IDENTIFIER) { |
| 949 *is_strict_reserved = false; | 982 *is_strict_reserved = false; |
| 950 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || | 983 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 951 (next == Token::YIELD && !this->is_generator())) { | 984 (next == Token::YIELD && !this->is_generator())) { |
| 952 *is_strict_reserved = true; | 985 *is_strict_reserved = true; |
| 953 } else { | 986 } else { |
| 954 ReportUnexpectedToken(next); | 987 ReportUnexpectedToken(next); |
| 955 *ok = false; | 988 *ok = false; |
| 956 return Traits::EmptyIdentifier(); | 989 return Traits::EmptyIdentifier(); |
| 957 } | 990 } |
| 958 return this->GetSymbol(); | 991 return this->GetSymbol(scanner()); |
| 959 } | 992 } |
| 960 | 993 |
| 961 | 994 |
| 962 template <class Traits> | 995 template <class Traits> |
| 963 typename Traits::Type::Identifier ParserBase<Traits>::ParseIdentifierName( | 996 typename Traits::Type::Identifier ParserBase<Traits>::ParseIdentifierName( |
| 964 bool* ok) { | 997 bool* ok) { |
| 965 Token::Value next = Next(); | 998 Token::Value next = Next(); |
| 966 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && | 999 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && |
| 967 next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { | 1000 next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { |
| 968 this->ReportUnexpectedToken(next); | 1001 this->ReportUnexpectedToken(next); |
| 969 *ok = false; | 1002 *ok = false; |
| 970 return Traits::EmptyIdentifier(); | 1003 return Traits::EmptyIdentifier(); |
| 971 } | 1004 } |
| 972 return this->GetSymbol(); | 1005 return this->GetSymbol(scanner()); |
| 973 } | 1006 } |
| 974 | 1007 |
| 975 | 1008 |
| 976 template <class Traits> | 1009 template <class Traits> |
| 977 typename Traits::Type::Identifier | 1010 typename Traits::Type::Identifier |
| 978 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get, | 1011 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get, |
| 979 bool* is_set, | 1012 bool* is_set, |
| 980 bool* ok) { | 1013 bool* ok) { |
| 981 typename Traits::Type::Identifier result = ParseIdentifierName(ok); | 1014 typename Traits::Type::Identifier result = ParseIdentifierName(ok); |
| 982 if (!*ok) return Traits::EmptyIdentifier(); | 1015 if (!*ok) return Traits::EmptyIdentifier(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 997 if (!scanner()->ScanRegExpPattern(seen_equal)) { | 1030 if (!scanner()->ScanRegExpPattern(seen_equal)) { |
| 998 Next(); | 1031 Next(); |
| 999 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); | 1032 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); |
| 1000 *ok = false; | 1033 *ok = false; |
| 1001 return Traits::EmptyExpression(); | 1034 return Traits::EmptyExpression(); |
| 1002 } | 1035 } |
| 1003 | 1036 |
| 1004 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 1037 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
| 1005 | 1038 |
| 1006 typename Traits::Type::Identifier js_pattern = | 1039 typename Traits::Type::Identifier js_pattern = |
| 1007 this->NextLiteralString(TENURED); | 1040 this->NextLiteralString(scanner(), TENURED); |
| 1008 if (!scanner()->ScanRegExpFlags()) { | 1041 if (!scanner()->ScanRegExpFlags()) { |
| 1009 Next(); | 1042 Next(); |
| 1010 ReportMessageAt(scanner()->location(), "invalid_regexp_flags"); | 1043 ReportMessageAt(scanner()->location(), "invalid_regexp_flags"); |
| 1011 *ok = false; | 1044 *ok = false; |
| 1012 return Traits::EmptyExpression(); | 1045 return Traits::EmptyExpression(); |
| 1013 } | 1046 } |
| 1014 typename Traits::Type::Identifier js_flags = | 1047 typename Traits::Type::Identifier js_flags = |
| 1015 this->NextLiteralString(TENURED); | 1048 this->NextLiteralString(scanner(), TENURED); |
| 1016 Next(); | 1049 Next(); |
| 1017 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); | 1050 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); |
| 1018 } | 1051 } |
| 1019 | 1052 |
| 1020 | 1053 |
| 1054 #define CHECK_OK ok); \ |
| 1055 if (!*ok) return this->EmptyExpression(); \ |
| 1056 ((void)0 |
| 1057 #define DUMMY ) // to make indentation work |
| 1058 #undef DUMMY |
| 1059 |
| 1060 template <class Traits> |
| 1061 typename Traits::Type::Expression ParserBase<Traits>::ParsePrimaryExpression( |
| 1062 bool* ok) { |
| 1063 // PrimaryExpression :: |
| 1064 // 'this' |
| 1065 // 'null' |
| 1066 // 'true' |
| 1067 // 'false' |
| 1068 // Identifier |
| 1069 // Number |
| 1070 // String |
| 1071 // ArrayLiteral |
| 1072 // ObjectLiteral |
| 1073 // RegExpLiteral |
| 1074 // '(' Expression ')' |
| 1075 |
| 1076 int pos = peek_position(); |
| 1077 typename Traits::Type::Expression result = this->EmptyExpression(); |
| 1078 Token::Value token = peek(); |
| 1079 switch (token) { |
| 1080 case Token::THIS: { |
| 1081 Consume(Token::THIS); |
| 1082 result = this->ThisExpression(scope_, factory()); |
| 1083 break; |
| 1084 } |
| 1085 |
| 1086 case Token::NULL_LITERAL: |
| 1087 case Token::TRUE_LITERAL: |
| 1088 case Token::FALSE_LITERAL: |
| 1089 case Token::NUMBER: |
| 1090 Next(); |
| 1091 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); |
| 1092 break; |
| 1093 |
| 1094 case Token::IDENTIFIER: |
| 1095 case Token::YIELD: |
| 1096 case Token::FUTURE_STRICT_RESERVED_WORD: { |
| 1097 // Using eval or arguments in this context is OK even in strict mode. |
| 1098 typename Traits::Type::Identifier name = |
| 1099 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 1100 result = |
| 1101 this->ExpressionFromIdentifier(name, pos, scope_, factory()); |
| 1102 break; |
| 1103 } |
| 1104 |
| 1105 case Token::STRING: { |
| 1106 Consume(Token::STRING); |
| 1107 result = this->ExpressionFromString(pos, scanner(), factory()); |
| 1108 break; |
| 1109 } |
| 1110 |
| 1111 case Token::ASSIGN_DIV: |
| 1112 result = this->ParseRegExpLiteral(true, CHECK_OK); |
| 1113 break; |
| 1114 |
| 1115 case Token::DIV: |
| 1116 result = this->ParseRegExpLiteral(false, CHECK_OK); |
| 1117 break; |
| 1118 |
| 1119 case Token::LBRACK: |
| 1120 result = this->ParseArrayLiteral(CHECK_OK); |
| 1121 break; |
| 1122 |
| 1123 case Token::LBRACE: |
| 1124 result = this->ParseObjectLiteral(CHECK_OK); |
| 1125 break; |
| 1126 |
| 1127 case Token::LPAREN: |
| 1128 Consume(Token::LPAREN); |
| 1129 // Heuristically try to detect immediately called functions before |
| 1130 // seeing the call parentheses. |
| 1131 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 1132 result = this->ParseExpression(true, CHECK_OK); |
| 1133 Expect(Token::RPAREN, CHECK_OK); |
| 1134 break; |
| 1135 |
| 1136 case Token::MOD: |
| 1137 if (allow_natives_syntax() || extension_ != NULL) { |
| 1138 result = this->ParseV8Intrinsic(CHECK_OK); |
| 1139 break; |
| 1140 } |
| 1141 // If we're not allowing special syntax we fall-through to the |
| 1142 // default case. |
| 1143 |
| 1144 default: { |
| 1145 Next(); |
| 1146 ReportUnexpectedToken(token); |
| 1147 *ok = false; |
| 1148 } |
| 1149 } |
| 1150 |
| 1151 return result; |
| 1152 } |
| 1153 |
| 1154 #undef CHECK_OK |
| 1155 |
| 1156 |
| 1021 template <typename Traits> | 1157 template <typename Traits> |
| 1022 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( | 1158 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( |
| 1023 Token::Value property, | 1159 Token::Value property, |
| 1024 PropertyKind type, | 1160 PropertyKind type, |
| 1025 bool* ok) { | 1161 bool* ok) { |
| 1026 int old; | 1162 int old; |
| 1027 if (property == Token::NUMBER) { | 1163 if (property == Token::NUMBER) { |
| 1028 old = finder_.AddNumber(scanner()->literal_ascii_string(), type); | 1164 old = finder_.AddNumber(scanner()->literal_ascii_string(), type); |
| 1029 } else if (scanner()->is_literal_ascii()) { | 1165 } else if (scanner()->is_literal_ascii()) { |
| 1030 old = finder_.AddAsciiSymbol(scanner()->literal_ascii_string(), type); | 1166 old = finder_.AddAsciiSymbol(scanner()->literal_ascii_string(), type); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1049 "accessor_get_set"); | 1185 "accessor_get_set"); |
| 1050 } | 1186 } |
| 1051 *ok = false; | 1187 *ok = false; |
| 1052 } | 1188 } |
| 1053 } | 1189 } |
| 1054 | 1190 |
| 1055 | 1191 |
| 1056 } } // v8::internal | 1192 } } // v8::internal |
| 1057 | 1193 |
| 1058 #endif // V8_PREPARSER_H | 1194 #endif // V8_PREPARSER_H |
| OLD | NEW |