OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
80 log_(log), | 80 log_(log), |
81 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. | 81 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. |
82 stack_limit_(stack_limit), | 82 stack_limit_(stack_limit), |
83 scanner_(scanner), | 83 scanner_(scanner), |
84 stack_overflow_(false), | 84 stack_overflow_(false), |
85 allow_lazy_(false), | 85 allow_lazy_(false), |
86 allow_natives_(false), | 86 allow_natives_(false), |
87 allow_harmony_arrow_functions_(false), | 87 allow_harmony_arrow_functions_(false), |
88 allow_harmony_object_literals_(false), | 88 allow_harmony_object_literals_(false), |
89 allow_harmony_sloppy_(false), | 89 allow_harmony_sloppy_(false), |
90 allow_harmony_computed_property_names_(false), | |
90 zone_(zone) {} | 91 zone_(zone) {} |
91 | 92 |
92 // Getters that indicate whether certain syntactical constructs are | 93 // Getters that indicate whether certain syntactical constructs are |
93 // allowed to be parsed by this instance of the parser. | 94 // allowed to be parsed by this instance of the parser. |
94 bool allow_lazy() const { return allow_lazy_; } | 95 bool allow_lazy() const { return allow_lazy_; } |
95 bool allow_natives() const { return allow_natives_; } | 96 bool allow_natives() const { return allow_natives_; } |
96 bool allow_harmony_arrow_functions() const { | 97 bool allow_harmony_arrow_functions() const { |
97 return allow_harmony_arrow_functions_; | 98 return allow_harmony_arrow_functions_; |
98 } | 99 } |
99 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); } | 100 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); } |
100 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } | 101 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } |
101 bool allow_harmony_numeric_literals() const { | 102 bool allow_harmony_numeric_literals() const { |
102 return scanner()->HarmonyNumericLiterals(); | 103 return scanner()->HarmonyNumericLiterals(); |
103 } | 104 } |
104 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } | 105 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } |
105 bool allow_harmony_object_literals() const { | 106 bool allow_harmony_object_literals() const { |
106 return allow_harmony_object_literals_; | 107 return allow_harmony_object_literals_; |
107 } | 108 } |
108 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); } | 109 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); } |
109 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } | 110 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } |
110 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } | 111 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } |
112 bool allow_harmony_computed_property_names() const { | |
113 return allow_harmony_computed_property_names_; | |
114 } | |
111 | 115 |
112 // Setters that determine whether certain syntactical constructs are | 116 // Setters that determine whether certain syntactical constructs are |
113 // allowed to be parsed by this instance of the parser. | 117 // allowed to be parsed by this instance of the parser. |
114 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 118 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
115 void set_allow_natives(bool allow) { allow_natives_ = allow; } | 119 void set_allow_natives(bool allow) { allow_natives_ = allow; } |
116 void set_allow_harmony_arrow_functions(bool allow) { | 120 void set_allow_harmony_arrow_functions(bool allow) { |
117 allow_harmony_arrow_functions_ = allow; | 121 allow_harmony_arrow_functions_ = allow; |
118 } | 122 } |
119 void set_allow_harmony_modules(bool allow) { | 123 void set_allow_harmony_modules(bool allow) { |
120 scanner()->SetHarmonyModules(allow); | 124 scanner()->SetHarmonyModules(allow); |
(...skipping 12 matching lines...) Expand all Loading... | |
133 } | 137 } |
134 void set_allow_harmony_templates(bool allow) { | 138 void set_allow_harmony_templates(bool allow) { |
135 scanner()->SetHarmonyTemplates(allow); | 139 scanner()->SetHarmonyTemplates(allow); |
136 } | 140 } |
137 void set_allow_harmony_sloppy(bool allow) { | 141 void set_allow_harmony_sloppy(bool allow) { |
138 allow_harmony_sloppy_ = allow; | 142 allow_harmony_sloppy_ = allow; |
139 } | 143 } |
140 void set_allow_harmony_unicode(bool allow) { | 144 void set_allow_harmony_unicode(bool allow) { |
141 scanner()->SetHarmonyUnicode(allow); | 145 scanner()->SetHarmonyUnicode(allow); |
142 } | 146 } |
147 void set_allow_harmony_computed_property_names(bool allow) { | |
148 allow_harmony_computed_property_names_ = allow; | |
149 } | |
143 | 150 |
144 protected: | 151 protected: |
145 enum AllowEvalOrArgumentsAsIdentifier { | 152 enum AllowEvalOrArgumentsAsIdentifier { |
146 kAllowEvalOrArguments, | 153 kAllowEvalOrArguments, |
147 kDontAllowEvalOrArguments | 154 kDontAllowEvalOrArguments |
148 }; | 155 }; |
149 | 156 |
150 enum Mode { | 157 enum Mode { |
151 PARSE_LAZILY, | 158 PARSE_LAZILY, |
152 PARSE_EAGERLY | 159 PARSE_EAGERLY |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
483 // Parses an identifier and determines whether or not it is 'get' or 'set'. | 490 // Parses an identifier and determines whether or not it is 'get' or 'set'. |
484 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, | 491 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, |
485 bool* is_set, | 492 bool* is_set, |
486 bool* ok); | 493 bool* ok); |
487 | 494 |
488 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); | 495 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); |
489 | 496 |
490 ExpressionT ParsePrimaryExpression(bool* ok); | 497 ExpressionT ParsePrimaryExpression(bool* ok); |
491 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 498 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
492 ExpressionT ParseArrayLiteral(bool* ok); | 499 ExpressionT ParseArrayLiteral(bool* ok); |
493 IdentifierT ParsePropertyName(bool* is_get, bool* is_set, bool* is_static, | 500 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
501 bool* is_static, bool* is_computed_name, | |
494 bool* ok); | 502 bool* ok); |
495 ExpressionT ParseObjectLiteral(bool* ok); | 503 ExpressionT ParseObjectLiteral(bool* ok); |
496 ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker, | 504 ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker, |
497 bool in_class, bool is_static, | 505 bool in_class, bool is_static, |
506 bool* is_computed_name, | |
498 bool* has_seen_constructor, | 507 bool* has_seen_constructor, |
499 bool* ok); | 508 bool* ok); |
500 typename Traits::Type::ExpressionList ParseArguments(bool* ok); | 509 typename Traits::Type::ExpressionList ParseArguments(bool* ok); |
501 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 510 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
502 ExpressionT ParseYieldExpression(bool* ok); | 511 ExpressionT ParseYieldExpression(bool* ok); |
503 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 512 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
504 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 513 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
505 ExpressionT ParseUnaryExpression(bool* ok); | 514 ExpressionT ParseUnaryExpression(bool* ok); |
506 ExpressionT ParsePostfixExpression(bool* ok); | 515 ExpressionT ParsePostfixExpression(bool* ok); |
507 ExpressionT ParseLeftHandSideExpression(bool* ok); | 516 ExpressionT ParseLeftHandSideExpression(bool* ok); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
591 | 600 |
592 private: | 601 private: |
593 Scanner* scanner_; | 602 Scanner* scanner_; |
594 bool stack_overflow_; | 603 bool stack_overflow_; |
595 | 604 |
596 bool allow_lazy_; | 605 bool allow_lazy_; |
597 bool allow_natives_; | 606 bool allow_natives_; |
598 bool allow_harmony_arrow_functions_; | 607 bool allow_harmony_arrow_functions_; |
599 bool allow_harmony_object_literals_; | 608 bool allow_harmony_object_literals_; |
600 bool allow_harmony_sloppy_; | 609 bool allow_harmony_sloppy_; |
610 bool allow_harmony_computed_property_names_; | |
601 | 611 |
602 typename Traits::Type::Zone* zone_; // Only used by Parser. | 612 typename Traits::Type::Zone* zone_; // Only used by Parser. |
603 }; | 613 }; |
604 | 614 |
605 | 615 |
606 class PreParserIdentifier { | 616 class PreParserIdentifier { |
607 public: | 617 public: |
608 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 618 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
609 static PreParserIdentifier Default() { | 619 static PreParserIdentifier Default() { |
610 return PreParserIdentifier(kUnknownIdentifier); | 620 return PreParserIdentifier(kUnknownIdentifier); |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1012 int literal_index, | 1022 int literal_index, |
1013 int pos) { | 1023 int pos) { |
1014 return PreParserExpression::Default(); | 1024 return PreParserExpression::Default(); |
1015 } | 1025 } |
1016 PreParserExpression NewArrayLiteral(PreParserExpressionList values, | 1026 PreParserExpression NewArrayLiteral(PreParserExpressionList values, |
1017 int literal_index, | 1027 int literal_index, |
1018 int pos) { | 1028 int pos) { |
1019 return PreParserExpression::Default(); | 1029 return PreParserExpression::Default(); |
1020 } | 1030 } |
1021 PreParserExpression NewObjectLiteralProperty(bool is_getter, | 1031 PreParserExpression NewObjectLiteralProperty(bool is_getter, |
1032 PreParserExpression key, | |
1022 PreParserExpression value, | 1033 PreParserExpression value, |
1023 int pos, bool is_static) { | 1034 int pos, bool is_static, |
1035 bool is_computed_name) { | |
1024 return PreParserExpression::Default(); | 1036 return PreParserExpression::Default(); |
1025 } | 1037 } |
1026 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, | 1038 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, |
1027 PreParserExpression value, | 1039 PreParserExpression value, |
1028 bool is_static) { | 1040 bool is_static, |
1041 bool is_computed_name) { | |
1029 return PreParserExpression::Default(); | 1042 return PreParserExpression::Default(); |
1030 } | 1043 } |
1031 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, | 1044 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, |
1032 int literal_index, | 1045 int literal_index, |
1033 int boilerplate_properties, | 1046 int boilerplate_properties, |
1034 bool has_function, | 1047 bool has_function, |
1035 int pos) { | 1048 int pos) { |
1036 return PreParserExpression::Default(); | 1049 return PreParserExpression::Default(); |
1037 } | 1050 } |
1038 PreParserExpression NewVariableProxy(void* variable) { | 1051 PreParserExpression NewVariableProxy(void* variable) { |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1204 static PreParserExpression GetPropertyValue(PreParserExpression property) { | 1217 static PreParserExpression GetPropertyValue(PreParserExpression property) { |
1205 return PreParserExpression::Default(); | 1218 return PreParserExpression::Default(); |
1206 } | 1219 } |
1207 | 1220 |
1208 // Functions for encapsulating the differences between parsing and preparsing; | 1221 // Functions for encapsulating the differences between parsing and preparsing; |
1209 // operations interleaved with the recursive descent. | 1222 // operations interleaved with the recursive descent. |
1210 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { | 1223 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { |
1211 // PreParser should not use FuncNameInferrer. | 1224 // PreParser should not use FuncNameInferrer. |
1212 UNREACHABLE(); | 1225 UNREACHABLE(); |
1213 } | 1226 } |
1227 static void PushLiteralName(FuncNameInferrer* fni, | |
1228 PreParserExpression expression) { | |
1229 // PreParser should not use FuncNameInferrer. | |
1230 UNREACHABLE(); | |
1231 } | |
1214 static void PushPropertyName(FuncNameInferrer* fni, | 1232 static void PushPropertyName(FuncNameInferrer* fni, |
1215 PreParserExpression expression) { | 1233 PreParserExpression expression) { |
1216 // PreParser should not use FuncNameInferrer. | 1234 // PreParser should not use FuncNameInferrer. |
1217 UNREACHABLE(); | 1235 UNREACHABLE(); |
1218 } | 1236 } |
1237 static void PushVariableName(FuncNameInferrer* fni, PreParserIdentifier id) { | |
1238 // PreParser should not use FuncNameInferrer. | |
1239 UNREACHABLE(); | |
1240 } | |
1219 static void InferFunctionName(FuncNameInferrer* fni, | 1241 static void InferFunctionName(FuncNameInferrer* fni, |
1220 PreParserExpression expression) { | 1242 PreParserExpression expression) { |
1221 // PreParser should not use FuncNameInferrer. | 1243 // PreParser should not use FuncNameInferrer. |
1222 UNREACHABLE(); | 1244 UNREACHABLE(); |
1223 } | 1245 } |
1224 | 1246 |
1225 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( | 1247 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( |
1226 PreParserScope* scope, PreParserExpression property, bool* has_function) { | 1248 PreParserScope* scope, PreParserExpression property, bool* has_function) { |
1227 } | 1249 } |
1228 | 1250 |
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1808 break; | 1830 break; |
1809 | 1831 |
1810 case Token::IDENTIFIER: | 1832 case Token::IDENTIFIER: |
1811 case Token::LET: | 1833 case Token::LET: |
1812 case Token::STATIC: | 1834 case Token::STATIC: |
1813 case Token::YIELD: | 1835 case Token::YIELD: |
1814 case Token::FUTURE_STRICT_RESERVED_WORD: { | 1836 case Token::FUTURE_STRICT_RESERVED_WORD: { |
1815 // Using eval or arguments in this context is OK even in strict mode. | 1837 // Using eval or arguments in this context is OK even in strict mode. |
1816 IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1838 IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
1817 result = this->ExpressionFromIdentifier(name, pos, scope_, factory()); | 1839 result = this->ExpressionFromIdentifier(name, pos, scope_, factory()); |
1840 if (fni_ != NULL) this->PushVariableName(fni_, name); | |
1818 break; | 1841 break; |
1819 } | 1842 } |
1820 | 1843 |
1821 case Token::STRING: { | 1844 case Token::STRING: { |
1822 Consume(Token::STRING); | 1845 Consume(Token::STRING); |
1823 result = this->ExpressionFromString(pos, scanner(), factory()); | 1846 result = this->ExpressionFromString(pos, scanner(), factory()); |
1847 if (fni_ != NULL) this->PushLiteralName(fni_, result); | |
1824 break; | 1848 break; |
1825 } | 1849 } |
1826 | 1850 |
1827 case Token::ASSIGN_DIV: | 1851 case Token::ASSIGN_DIV: |
1828 result = this->ParseRegExpLiteral(true, CHECK_OK); | 1852 result = this->ParseRegExpLiteral(true, CHECK_OK); |
1829 break; | 1853 break; |
1830 | 1854 |
1831 case Token::DIV: | 1855 case Token::DIV: |
1832 result = this->ParseRegExpLiteral(false, CHECK_OK); | 1856 result = this->ParseRegExpLiteral(false, CHECK_OK); |
1833 break; | 1857 break; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1948 Expect(Token::RBRACK, CHECK_OK); | 1972 Expect(Token::RBRACK, CHECK_OK); |
1949 | 1973 |
1950 // Update the scope information before the pre-parsing bailout. | 1974 // Update the scope information before the pre-parsing bailout. |
1951 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 1975 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
1952 | 1976 |
1953 return factory()->NewArrayLiteral(values, literal_index, pos); | 1977 return factory()->NewArrayLiteral(values, literal_index, pos); |
1954 } | 1978 } |
1955 | 1979 |
1956 | 1980 |
1957 template <class Traits> | 1981 template <class Traits> |
1958 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParsePropertyName( | 1982 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( |
1959 bool* is_get, bool* is_set, bool* is_static, bool* ok) { | 1983 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static, |
1960 Token::Value next = peek(); | 1984 bool* is_computed_name, bool* ok) { |
1961 switch (next) { | 1985 Token::Value token = peek(); |
1986 int pos = peek_position(); | |
1987 | |
1988 // For non computed property names we normalize the name a bit: | |
1989 // | |
1990 // "12" -> 12 | |
1991 // 12.3 -> "12.3" | |
1992 // 12.30 -> "12.3" | |
1993 // identifier -> "identifier" | |
1994 // | |
1995 // This is important because we use the property name as a key in a hash | |
1996 // table when we computed constant properties. | |
1997 switch (token) { | |
1962 case Token::STRING: | 1998 case Token::STRING: |
1963 Consume(Token::STRING); | 1999 Consume(Token::STRING); |
1964 return this->GetSymbol(scanner_); | 2000 *name = this->GetSymbol(scanner()); |
2001 break; | |
2002 | |
1965 case Token::NUMBER: | 2003 case Token::NUMBER: |
1966 Consume(Token::NUMBER); | 2004 Consume(Token::NUMBER); |
1967 return this->GetNumberAsSymbol(scanner_); | 2005 *name = this->GetNumberAsSymbol(scanner()); |
2006 break; | |
2007 | |
2008 case Token::LBRACK: | |
2009 if (allow_harmony_computed_property_names_) { | |
2010 *is_computed_name = true; | |
2011 Consume(Token::LBRACK); | |
2012 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); | |
2013 Consume(Token::RBRACK); | |
2014 return expression; | |
2015 } | |
2016 | |
2017 // Fall through. | |
1968 case Token::STATIC: | 2018 case Token::STATIC: |
1969 *is_static = true; | 2019 *is_static = true; |
1970 // Fall through. | 2020 |
2021 // Fall through. | |
1971 default: | 2022 default: |
1972 return ParseIdentifierNameOrGetOrSet(is_get, is_set, ok); | 2023 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); |
2024 break; | |
1973 } | 2025 } |
1974 UNREACHABLE(); | 2026 |
1975 return this->EmptyIdentifier(); | 2027 uint32_t index; |
2028 return this->IsArrayIndex(*name, &index) | |
2029 ? factory()->NewNumberLiteral(index, pos) | |
2030 : factory()->NewStringLiteral(*name, pos); | |
1976 } | 2031 } |
1977 | 2032 |
1978 | 2033 |
1979 template <class Traits> | 2034 template <class Traits> |
1980 typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase< | 2035 typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase< |
1981 Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker, | 2036 Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker, |
1982 bool in_class, bool is_static, | 2037 bool in_class, bool is_static, |
2038 bool* is_computed_name, | |
1983 bool* has_seen_constructor, bool* ok) { | 2039 bool* has_seen_constructor, bool* ok) { |
1984 DCHECK(!in_class || is_static || has_seen_constructor != NULL); | 2040 DCHECK(!in_class || is_static || has_seen_constructor != NULL); |
1985 ExpressionT value = this->EmptyExpression(); | 2041 ExpressionT value = this->EmptyExpression(); |
2042 IdentifierT name = this->EmptyIdentifier(); | |
1986 bool is_get = false; | 2043 bool is_get = false; |
1987 bool is_set = false; | 2044 bool is_set = false; |
1988 bool name_is_static = false; | 2045 bool name_is_static = false; |
1989 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); | 2046 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); |
1990 | 2047 |
1991 Token::Value name_token = peek(); | 2048 Token::Value name_token = peek(); |
1992 int next_pos = peek_position(); | 2049 int next_pos = peek_position(); |
1993 IdentifierT name = | 2050 ExpressionT name_expression = ParsePropertyName( |
1994 ParsePropertyName(&is_get, &is_set, &name_is_static, | 2051 &name, &is_get, &is_set, &name_is_static, is_computed_name, |
1995 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2052 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1996 | 2053 |
1997 if (fni_ != NULL) this->PushLiteralName(fni_, name); | 2054 if (!*is_computed_name && fni_ != NULL) { |
arv (Not doing code reviews)
2014/12/10 23:38:13
if (fni_ != NULL) {
since name is empty string fo
arv (Not doing code reviews)
2014/12/11 23:10:33
This one is needed.
| |
2055 this->PushLiteralName(fni_, name); | |
2056 } | |
1998 | 2057 |
1999 if (!in_class && !is_generator && peek() == Token::COLON) { | 2058 if (!in_class && !is_generator && peek() == Token::COLON) { |
2000 // PropertyDefinition : PropertyName ':' AssignmentExpression | 2059 // PropertyDefinition : PropertyName ':' AssignmentExpression |
2001 if (checker != NULL) { | 2060 if (!*is_computed_name && checker != NULL) { |
arv (Not doing code reviews)
2014/12/10 23:38:13
maybe same here... need to check
arv (Not doing code reviews)
2014/12/11 23:10:33
This one is needed too.
| |
2002 checker->CheckProperty(name_token, kValueProperty, | 2061 checker->CheckProperty(name_token, kValueProperty, |
2003 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2062 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2004 } | 2063 } |
2005 Consume(Token::COLON); | 2064 Consume(Token::COLON); |
2006 value = this->ParseAssignmentExpression( | 2065 value = this->ParseAssignmentExpression( |
2007 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2066 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2008 | 2067 |
2009 } else if (is_generator || | 2068 } else if (is_generator || |
2010 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { | 2069 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { |
2011 // Concise Method | 2070 // Concise Method |
(...skipping 17 matching lines...) Expand all Loading... | |
2029 if (*has_seen_constructor) { | 2088 if (*has_seen_constructor) { |
2030 ReportMessageAt(scanner()->location(), "duplicate_constructor"); | 2089 ReportMessageAt(scanner()->location(), "duplicate_constructor"); |
2031 *ok = false; | 2090 *ok = false; |
2032 return this->EmptyObjectLiteralProperty(); | 2091 return this->EmptyObjectLiteralProperty(); |
2033 } | 2092 } |
2034 | 2093 |
2035 *has_seen_constructor = true; | 2094 *has_seen_constructor = true; |
2036 kind = FunctionKind::kNormalFunction; | 2095 kind = FunctionKind::kNormalFunction; |
2037 } | 2096 } |
2038 | 2097 |
2039 if (checker != NULL) { | 2098 if (!*is_computed_name && checker != NULL) { |
2040 checker->CheckProperty(name_token, kValueProperty, | 2099 checker->CheckProperty(name_token, kValueProperty, |
2041 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2100 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2042 } | 2101 } |
2043 | 2102 |
2044 value = this->ParseFunctionLiteral( | 2103 value = this->ParseFunctionLiteral( |
2045 name, scanner()->location(), | 2104 name, scanner()->location(), |
2046 false, // reserved words are allowed here | 2105 false, // reserved words are allowed here |
2047 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, | 2106 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, |
2048 FunctionLiteral::NORMAL_ARITY, | 2107 FunctionLiteral::NORMAL_ARITY, |
2049 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2108 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2050 | 2109 |
2051 } else if (in_class && name_is_static && !is_static) { | 2110 } else if (in_class && name_is_static && !is_static) { |
2052 // static MethodDefinition | 2111 // static MethodDefinition |
2053 return ParsePropertyDefinition(checker, true, true, NULL, ok); | 2112 return ParsePropertyDefinition(checker, true, true, is_computed_name, NULL, |
2113 ok); | |
2054 | 2114 |
2055 } else if (is_get || is_set) { | 2115 } else if (is_get || is_set) { |
2056 // Accessor | 2116 // Accessor |
2117 name = this->EmptyIdentifier(); | |
2057 bool dont_care = false; | 2118 bool dont_care = false; |
2058 name_token = peek(); | 2119 name_token = peek(); |
2059 name = ParsePropertyName(&dont_care, &dont_care, &dont_care, | 2120 |
2060 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2121 name_expression = ParsePropertyName( |
2122 &name, &dont_care, &dont_care, &dont_care, is_computed_name, | |
2123 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
2061 | 2124 |
2062 // Validate the property. | 2125 // Validate the property. |
2063 if (is_static && this->IsPrototype(name)) { | 2126 if (is_static && !*is_computed_name && this->IsPrototype(name)) { |
arv (Not doing code reviews)
2014/12/11 23:10:34
this one is not needed because IsPrototype will be
| |
2064 ReportMessageAt(scanner()->location(), "static_prototype"); | 2127 ReportMessageAt(scanner()->location(), "static_prototype"); |
2065 *ok = false; | 2128 *ok = false; |
2066 return this->EmptyObjectLiteralProperty(); | 2129 return this->EmptyObjectLiteralProperty(); |
2067 } else if (in_class && !is_static && this->IsConstructor(name)) { | 2130 } else if (in_class && !is_static && this->IsConstructor(name)) { |
2068 ReportMessageAt(scanner()->location(), "constructor_special_method"); | 2131 ReportMessageAt(scanner()->location(), "constructor_special_method"); |
2069 *ok = false; | 2132 *ok = false; |
2070 return this->EmptyObjectLiteralProperty(); | 2133 return this->EmptyObjectLiteralProperty(); |
2071 } | 2134 } |
2072 if (checker != NULL) { | 2135 if (!*is_computed_name && checker != NULL) { |
2073 checker->CheckProperty(name_token, | 2136 checker->CheckProperty(name_token, |
2074 is_get ? kGetterProperty : kSetterProperty, | 2137 is_get ? kGetterProperty : kSetterProperty, |
2075 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2138 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2076 } | 2139 } |
2077 | 2140 |
2078 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( | 2141 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( |
2079 name, scanner()->location(), | 2142 name, scanner()->location(), |
2080 false, // reserved words are allowed here | 2143 false, // reserved words are allowed here |
2081 FunctionKind::kNormalFunction, RelocInfo::kNoPosition, | 2144 FunctionKind::kNormalFunction, RelocInfo::kNoPosition, |
2082 FunctionLiteral::ANONYMOUS_EXPRESSION, | 2145 FunctionLiteral::ANONYMOUS_EXPRESSION, |
2083 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, | 2146 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, |
2084 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2147 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2085 return factory()->NewObjectLiteralProperty(is_get, value, next_pos, | 2148 |
2086 is_static); | 2149 return factory()->NewObjectLiteralProperty( |
2150 is_get, name_expression, value, next_pos, is_static, *is_computed_name); | |
2087 | 2151 |
2088 } else if (!in_class && allow_harmony_object_literals_ && | 2152 } else if (!in_class && allow_harmony_object_literals_ && |
2089 Token::IsIdentifier(name_token, strict_mode(), | 2153 Token::IsIdentifier(name_token, strict_mode(), |
2090 this->is_generator())) { | 2154 this->is_generator())) { |
2091 value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory()); | 2155 value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory()); |
2092 | 2156 |
2093 } else { | 2157 } else { |
2094 Token::Value next = Next(); | 2158 Token::Value next = Next(); |
2095 ReportUnexpectedToken(next); | 2159 ReportUnexpectedToken(next); |
2096 *ok = false; | 2160 *ok = false; |
2097 return this->EmptyObjectLiteralProperty(); | 2161 return this->EmptyObjectLiteralProperty(); |
2098 } | 2162 } |
2099 | 2163 |
2100 uint32_t index; | 2164 return factory()->NewObjectLiteralProperty(name_expression, value, is_static, |
2101 LiteralT key = this->IsArrayIndex(name, &index) | 2165 *is_computed_name); |
2102 ? factory()->NewNumberLiteral(index, next_pos) | |
2103 : factory()->NewStringLiteral(name, next_pos); | |
2104 | |
2105 return factory()->NewObjectLiteralProperty(key, value, is_static); | |
2106 } | 2166 } |
2107 | 2167 |
2108 | 2168 |
2109 template <class Traits> | 2169 template <class Traits> |
2110 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( | 2170 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( |
2111 bool* ok) { | 2171 bool* ok) { |
2112 // ObjectLiteral :: | 2172 // ObjectLiteral :: |
2113 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' | 2173 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
2114 | 2174 |
2115 int pos = peek_position(); | 2175 int pos = peek_position(); |
2116 typename Traits::Type::PropertyList properties = | 2176 typename Traits::Type::PropertyList properties = |
2117 this->NewPropertyList(4, zone_); | 2177 this->NewPropertyList(4, zone_); |
2118 int number_of_boilerplate_properties = 0; | 2178 int number_of_boilerplate_properties = 0; |
2119 bool has_function = false; | 2179 bool has_function = false; |
2180 bool has_computed_names = false; | |
2120 | 2181 |
2121 ObjectLiteralChecker checker(this, strict_mode()); | 2182 ObjectLiteralChecker checker(this, strict_mode()); |
2122 | 2183 |
2123 Expect(Token::LBRACE, CHECK_OK); | 2184 Expect(Token::LBRACE, CHECK_OK); |
2124 | 2185 |
2125 while (peek() != Token::RBRACE) { | 2186 while (peek() != Token::RBRACE) { |
2126 if (fni_ != NULL) fni_->Enter(); | 2187 if (fni_ != NULL) fni_->Enter(); |
2127 | 2188 |
2128 const bool in_class = false; | 2189 const bool in_class = false; |
2129 const bool is_static = false; | 2190 const bool is_static = false; |
2191 bool is_computed_name = false; | |
2130 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( | 2192 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( |
2131 &checker, in_class, is_static, NULL, CHECK_OK); | 2193 &checker, in_class, is_static, &is_computed_name, NULL, CHECK_OK); |
2194 | |
2195 if (is_computed_name) { | |
2196 has_computed_names = true; | |
2197 } | |
2132 | 2198 |
2133 // Mark top-level object literals that contain function literals and | 2199 // Mark top-level object literals that contain function literals and |
2134 // pretenure the literal so it can be added as a constant function | 2200 // pretenure the literal so it can be added as a constant function |
2135 // property. (Parser only.) | 2201 // property. (Parser only.) |
2136 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, | 2202 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, |
2137 &has_function); | 2203 &has_function); |
2138 | 2204 |
2139 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 2205 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
2140 if (this->IsBoilerplateProperty(property)) { | 2206 if (!has_computed_names && this->IsBoilerplateProperty(property)) { |
2141 number_of_boilerplate_properties++; | 2207 number_of_boilerplate_properties++; |
2142 } | 2208 } |
2143 properties->Add(property, zone()); | 2209 properties->Add(property, zone()); |
2144 | 2210 |
2145 if (peek() != Token::RBRACE) { | 2211 if (peek() != Token::RBRACE) { |
2146 // Need {} because of the CHECK_OK macro. | 2212 // Need {} because of the CHECK_OK macro. |
2147 Expect(Token::COMMA, CHECK_OK); | 2213 Expect(Token::COMMA, CHECK_OK); |
2148 } | 2214 } |
2149 | 2215 |
2150 if (fni_ != NULL) { | 2216 if (fni_ != NULL) { |
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2922 DCHECK(IsAccessorAccessorConflict(old_type, type)); | 2988 DCHECK(IsAccessorAccessorConflict(old_type, type)); |
2923 // Both accessors of the same type. | 2989 // Both accessors of the same type. |
2924 parser()->ReportMessage("accessor_get_set"); | 2990 parser()->ReportMessage("accessor_get_set"); |
2925 } | 2991 } |
2926 *ok = false; | 2992 *ok = false; |
2927 } | 2993 } |
2928 } | 2994 } |
2929 } } // v8::internal | 2995 } } // v8::internal |
2930 | 2996 |
2931 #endif // V8_PREPARSER_H | 2997 #endif // V8_PREPARSER_H |
OLD | NEW |