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 |