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 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 // Parses an identifier and determines whether or not it is 'get' or 'set'. | 499 // Parses an identifier and determines whether or not it is 'get' or 'set'. |
493 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, | 500 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, |
494 bool* is_set, | 501 bool* is_set, |
495 bool* ok); | 502 bool* ok); |
496 | 503 |
497 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); | 504 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); |
498 | 505 |
499 ExpressionT ParsePrimaryExpression(bool* ok); | 506 ExpressionT ParsePrimaryExpression(bool* ok); |
500 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 507 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
501 ExpressionT ParseArrayLiteral(bool* ok); | 508 ExpressionT ParseArrayLiteral(bool* ok); |
502 IdentifierT ParsePropertyName(bool* is_get, bool* is_set, bool* is_static, | 509 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
| 510 bool* is_static, bool* is_computed_name, |
503 bool* ok); | 511 bool* ok); |
504 ExpressionT ParseObjectLiteral(bool* ok); | 512 ExpressionT ParseObjectLiteral(bool* ok); |
505 ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker, | 513 ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker, |
506 bool in_class, bool is_static, | 514 bool in_class, bool is_static, |
| 515 bool* is_computed_name, |
507 bool* has_seen_constructor, | 516 bool* has_seen_constructor, |
508 bool* ok); | 517 bool* ok); |
509 typename Traits::Type::ExpressionList ParseArguments(bool* ok); | 518 typename Traits::Type::ExpressionList ParseArguments(bool* ok); |
510 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 519 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
511 ExpressionT ParseYieldExpression(bool* ok); | 520 ExpressionT ParseYieldExpression(bool* ok); |
512 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 521 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
513 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 522 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
514 ExpressionT ParseUnaryExpression(bool* ok); | 523 ExpressionT ParseUnaryExpression(bool* ok); |
515 ExpressionT ParsePostfixExpression(bool* ok); | 524 ExpressionT ParsePostfixExpression(bool* ok); |
516 ExpressionT ParseLeftHandSideExpression(bool* ok); | 525 ExpressionT ParseLeftHandSideExpression(bool* ok); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
600 | 609 |
601 private: | 610 private: |
602 Scanner* scanner_; | 611 Scanner* scanner_; |
603 bool stack_overflow_; | 612 bool stack_overflow_; |
604 | 613 |
605 bool allow_lazy_; | 614 bool allow_lazy_; |
606 bool allow_natives_; | 615 bool allow_natives_; |
607 bool allow_harmony_arrow_functions_; | 616 bool allow_harmony_arrow_functions_; |
608 bool allow_harmony_object_literals_; | 617 bool allow_harmony_object_literals_; |
609 bool allow_harmony_sloppy_; | 618 bool allow_harmony_sloppy_; |
| 619 bool allow_harmony_computed_property_names_; |
610 | 620 |
611 typename Traits::Type::Zone* zone_; // Only used by Parser. | 621 typename Traits::Type::Zone* zone_; // Only used by Parser. |
612 }; | 622 }; |
613 | 623 |
614 | 624 |
615 class PreParserIdentifier { | 625 class PreParserIdentifier { |
616 public: | 626 public: |
617 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 627 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
618 static PreParserIdentifier Default() { | 628 static PreParserIdentifier Default() { |
619 return PreParserIdentifier(kUnknownIdentifier); | 629 return PreParserIdentifier(kUnknownIdentifier); |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1033 int literal_index, | 1043 int literal_index, |
1034 int pos) { | 1044 int pos) { |
1035 return PreParserExpression::Default(); | 1045 return PreParserExpression::Default(); |
1036 } | 1046 } |
1037 PreParserExpression NewArrayLiteral(PreParserExpressionList values, | 1047 PreParserExpression NewArrayLiteral(PreParserExpressionList values, |
1038 int literal_index, | 1048 int literal_index, |
1039 int pos) { | 1049 int pos) { |
1040 return PreParserExpression::Default(); | 1050 return PreParserExpression::Default(); |
1041 } | 1051 } |
1042 PreParserExpression NewObjectLiteralProperty(bool is_getter, | 1052 PreParserExpression NewObjectLiteralProperty(bool is_getter, |
| 1053 PreParserExpression key, |
1043 PreParserExpression value, | 1054 PreParserExpression value, |
1044 int pos, bool is_static) { | 1055 int pos, bool is_static, |
| 1056 bool is_computed_name) { |
1045 return PreParserExpression::Default(); | 1057 return PreParserExpression::Default(); |
1046 } | 1058 } |
1047 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, | 1059 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, |
1048 PreParserExpression value, | 1060 PreParserExpression value, |
1049 bool is_static) { | 1061 bool is_static, |
| 1062 bool is_computed_name) { |
1050 return PreParserExpression::Default(); | 1063 return PreParserExpression::Default(); |
1051 } | 1064 } |
1052 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, | 1065 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, |
1053 int literal_index, | 1066 int literal_index, |
1054 int boilerplate_properties, | 1067 int boilerplate_properties, |
1055 bool has_function, | 1068 bool has_function, |
1056 int pos) { | 1069 int pos) { |
1057 return PreParserExpression::Default(); | 1070 return PreParserExpression::Default(); |
1058 } | 1071 } |
1059 PreParserExpression NewVariableProxy(void* variable) { | 1072 PreParserExpression NewVariableProxy(void* variable) { |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1225 static PreParserExpression GetPropertyValue(PreParserExpression property) { | 1238 static PreParserExpression GetPropertyValue(PreParserExpression property) { |
1226 return PreParserExpression::Default(); | 1239 return PreParserExpression::Default(); |
1227 } | 1240 } |
1228 | 1241 |
1229 // Functions for encapsulating the differences between parsing and preparsing; | 1242 // Functions for encapsulating the differences between parsing and preparsing; |
1230 // operations interleaved with the recursive descent. | 1243 // operations interleaved with the recursive descent. |
1231 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { | 1244 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { |
1232 // PreParser should not use FuncNameInferrer. | 1245 // PreParser should not use FuncNameInferrer. |
1233 UNREACHABLE(); | 1246 UNREACHABLE(); |
1234 } | 1247 } |
| 1248 |
1235 static void PushPropertyName(FuncNameInferrer* fni, | 1249 static void PushPropertyName(FuncNameInferrer* fni, |
1236 PreParserExpression expression) { | 1250 PreParserExpression expression) { |
1237 // PreParser should not use FuncNameInferrer. | 1251 // PreParser should not use FuncNameInferrer. |
1238 UNREACHABLE(); | 1252 UNREACHABLE(); |
1239 } | 1253 } |
| 1254 |
1240 static void InferFunctionName(FuncNameInferrer* fni, | 1255 static void InferFunctionName(FuncNameInferrer* fni, |
1241 PreParserExpression expression) { | 1256 PreParserExpression expression) { |
1242 // PreParser should not use FuncNameInferrer. | 1257 // PreParser should not use FuncNameInferrer. |
1243 UNREACHABLE(); | 1258 UNREACHABLE(); |
1244 } | 1259 } |
1245 | 1260 |
1246 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( | 1261 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( |
1247 PreParserScope* scope, PreParserExpression property, bool* has_function) { | 1262 PreParserScope* scope, PreParserExpression property, bool* has_function) { |
1248 } | 1263 } |
1249 | 1264 |
(...skipping 740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1990 Expect(Token::RBRACK, CHECK_OK); | 2005 Expect(Token::RBRACK, CHECK_OK); |
1991 | 2006 |
1992 // Update the scope information before the pre-parsing bailout. | 2007 // Update the scope information before the pre-parsing bailout. |
1993 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 2008 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
1994 | 2009 |
1995 return factory()->NewArrayLiteral(values, literal_index, pos); | 2010 return factory()->NewArrayLiteral(values, literal_index, pos); |
1996 } | 2011 } |
1997 | 2012 |
1998 | 2013 |
1999 template <class Traits> | 2014 template <class Traits> |
2000 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParsePropertyName( | 2015 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( |
2001 bool* is_get, bool* is_set, bool* is_static, bool* ok) { | 2016 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static, |
2002 Token::Value next = peek(); | 2017 bool* is_computed_name, bool* ok) { |
2003 switch (next) { | 2018 Token::Value token = peek(); |
| 2019 int pos = peek_position(); |
| 2020 |
| 2021 // For non computed property names we normalize the name a bit: |
| 2022 // |
| 2023 // "12" -> 12 |
| 2024 // 12.3 -> "12.3" |
| 2025 // 12.30 -> "12.3" |
| 2026 // identifier -> "identifier" |
| 2027 // |
| 2028 // This is important because we use the property name as a key in a hash |
| 2029 // table when we compute constant properties. |
| 2030 switch (token) { |
2004 case Token::STRING: | 2031 case Token::STRING: |
2005 Consume(Token::STRING); | 2032 Consume(Token::STRING); |
2006 return this->GetSymbol(scanner_); | 2033 *name = this->GetSymbol(scanner()); |
| 2034 break; |
| 2035 |
2007 case Token::NUMBER: | 2036 case Token::NUMBER: |
2008 Consume(Token::NUMBER); | 2037 Consume(Token::NUMBER); |
2009 return this->GetNumberAsSymbol(scanner_); | 2038 *name = this->GetNumberAsSymbol(scanner()); |
| 2039 break; |
| 2040 |
| 2041 case Token::LBRACK: |
| 2042 if (allow_harmony_computed_property_names_) { |
| 2043 *is_computed_name = true; |
| 2044 Consume(Token::LBRACK); |
| 2045 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); |
| 2046 Expect(Token::RBRACK, CHECK_OK); |
| 2047 return expression; |
| 2048 } |
| 2049 |
| 2050 // Fall through. |
2010 case Token::STATIC: | 2051 case Token::STATIC: |
2011 *is_static = true; | 2052 *is_static = true; |
2012 // Fall through. | 2053 |
| 2054 // Fall through. |
2013 default: | 2055 default: |
2014 return ParseIdentifierNameOrGetOrSet(is_get, is_set, ok); | 2056 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); |
| 2057 break; |
2015 } | 2058 } |
2016 UNREACHABLE(); | 2059 |
2017 return this->EmptyIdentifier(); | 2060 uint32_t index; |
| 2061 return this->IsArrayIndex(*name, &index) |
| 2062 ? factory()->NewNumberLiteral(index, pos) |
| 2063 : factory()->NewStringLiteral(*name, pos); |
2018 } | 2064 } |
2019 | 2065 |
2020 | 2066 |
2021 template <class Traits> | 2067 template <class Traits> |
2022 typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase< | 2068 typename ParserBase<Traits>::ObjectLiteralPropertyT |
2023 Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker, | 2069 ParserBase<Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker, |
2024 bool in_class, bool is_static, | 2070 bool in_class, bool is_static, |
2025 bool* has_seen_constructor, bool* ok) { | 2071 bool* is_computed_name, |
| 2072 bool* has_seen_constructor, |
| 2073 bool* ok) { |
2026 DCHECK(!in_class || is_static || has_seen_constructor != NULL); | 2074 DCHECK(!in_class || is_static || has_seen_constructor != NULL); |
2027 ExpressionT value = this->EmptyExpression(); | 2075 ExpressionT value = this->EmptyExpression(); |
| 2076 IdentifierT name = this->EmptyIdentifier(); |
2028 bool is_get = false; | 2077 bool is_get = false; |
2029 bool is_set = false; | 2078 bool is_set = false; |
2030 bool name_is_static = false; | 2079 bool name_is_static = false; |
2031 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); | 2080 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); |
2032 | 2081 |
2033 Token::Value name_token = peek(); | 2082 Token::Value name_token = peek(); |
2034 int next_pos = peek_position(); | 2083 int next_pos = peek_position(); |
2035 IdentifierT name = | 2084 ExpressionT name_expression = ParsePropertyName( |
2036 ParsePropertyName(&is_get, &is_set, &name_is_static, | 2085 &name, &is_get, &is_set, &name_is_static, is_computed_name, |
2037 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2086 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2038 | 2087 |
2039 if (fni_ != NULL) this->PushLiteralName(fni_, name); | 2088 if (fni_ != NULL && !*is_computed_name) { |
| 2089 this->PushLiteralName(fni_, name); |
| 2090 } |
2040 | 2091 |
2041 if (!in_class && !is_generator && peek() == Token::COLON) { | 2092 if (!in_class && !is_generator && peek() == Token::COLON) { |
2042 // PropertyDefinition : PropertyName ':' AssignmentExpression | 2093 // PropertyDefinition : PropertyName ':' AssignmentExpression |
2043 if (checker != NULL) { | 2094 if (!*is_computed_name && checker != NULL) { |
2044 checker->CheckProperty(name_token, kValueProperty, | 2095 checker->CheckProperty(name_token, kValueProperty, |
2045 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2096 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2046 } | 2097 } |
2047 Consume(Token::COLON); | 2098 Consume(Token::COLON); |
2048 value = this->ParseAssignmentExpression( | 2099 value = this->ParseAssignmentExpression( |
2049 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2100 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2050 | 2101 |
2051 } else if (is_generator || | 2102 } else if (is_generator || |
2052 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { | 2103 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { |
2053 // Concise Method | 2104 // Concise Method |
(...skipping 17 matching lines...) Expand all Loading... |
2071 if (*has_seen_constructor) { | 2122 if (*has_seen_constructor) { |
2072 ReportMessageAt(scanner()->location(), "duplicate_constructor"); | 2123 ReportMessageAt(scanner()->location(), "duplicate_constructor"); |
2073 *ok = false; | 2124 *ok = false; |
2074 return this->EmptyObjectLiteralProperty(); | 2125 return this->EmptyObjectLiteralProperty(); |
2075 } | 2126 } |
2076 | 2127 |
2077 *has_seen_constructor = true; | 2128 *has_seen_constructor = true; |
2078 kind = FunctionKind::kNormalFunction; | 2129 kind = FunctionKind::kNormalFunction; |
2079 } | 2130 } |
2080 | 2131 |
2081 if (checker != NULL) { | 2132 if (!*is_computed_name && checker != NULL) { |
2082 checker->CheckProperty(name_token, kValueProperty, | 2133 checker->CheckProperty(name_token, kValueProperty, |
2083 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2134 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2084 } | 2135 } |
2085 | 2136 |
2086 value = this->ParseFunctionLiteral( | 2137 value = this->ParseFunctionLiteral( |
2087 name, scanner()->location(), | 2138 name, scanner()->location(), |
2088 false, // reserved words are allowed here | 2139 false, // reserved words are allowed here |
2089 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, | 2140 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, |
2090 FunctionLiteral::NORMAL_ARITY, | 2141 FunctionLiteral::NORMAL_ARITY, |
2091 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2142 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2092 | 2143 |
2093 } else if (in_class && name_is_static && !is_static) { | 2144 } else if (in_class && name_is_static && !is_static) { |
2094 // static MethodDefinition | 2145 // static MethodDefinition |
2095 return ParsePropertyDefinition(checker, true, true, NULL, ok); | 2146 return ParsePropertyDefinition(checker, true, true, is_computed_name, NULL, |
| 2147 ok); |
2096 | 2148 |
2097 } else if (is_get || is_set) { | 2149 } else if (is_get || is_set) { |
2098 // Accessor | 2150 // Accessor |
| 2151 name = this->EmptyIdentifier(); |
2099 bool dont_care = false; | 2152 bool dont_care = false; |
2100 name_token = peek(); | 2153 name_token = peek(); |
2101 name = ParsePropertyName(&dont_care, &dont_care, &dont_care, | 2154 |
2102 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2155 name_expression = ParsePropertyName( |
| 2156 &name, &dont_care, &dont_care, &dont_care, is_computed_name, |
| 2157 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2103 | 2158 |
2104 // Validate the property. | 2159 // Validate the property. |
2105 if (is_static && this->IsPrototype(name)) { | 2160 if (is_static && this->IsPrototype(name)) { |
2106 ReportMessageAt(scanner()->location(), "static_prototype"); | 2161 ReportMessageAt(scanner()->location(), "static_prototype"); |
2107 *ok = false; | 2162 *ok = false; |
2108 return this->EmptyObjectLiteralProperty(); | 2163 return this->EmptyObjectLiteralProperty(); |
2109 } else if (in_class && !is_static && this->IsConstructor(name)) { | 2164 } else if (in_class && !is_static && this->IsConstructor(name)) { |
2110 ReportMessageAt(scanner()->location(), "constructor_special_method"); | 2165 ReportMessageAt(scanner()->location(), "constructor_special_method"); |
2111 *ok = false; | 2166 *ok = false; |
2112 return this->EmptyObjectLiteralProperty(); | 2167 return this->EmptyObjectLiteralProperty(); |
2113 } | 2168 } |
2114 if (checker != NULL) { | 2169 if (!*is_computed_name && checker != NULL) { |
2115 checker->CheckProperty(name_token, | 2170 checker->CheckProperty(name_token, |
2116 is_get ? kGetterProperty : kSetterProperty, | 2171 is_get ? kGetterProperty : kSetterProperty, |
2117 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2172 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2118 } | 2173 } |
2119 | 2174 |
2120 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( | 2175 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( |
2121 name, scanner()->location(), | 2176 name, scanner()->location(), |
2122 false, // reserved words are allowed here | 2177 false, // reserved words are allowed here |
2123 FunctionKind::kNormalFunction, RelocInfo::kNoPosition, | 2178 FunctionKind::kNormalFunction, RelocInfo::kNoPosition, |
2124 FunctionLiteral::ANONYMOUS_EXPRESSION, | 2179 FunctionLiteral::ANONYMOUS_EXPRESSION, |
2125 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, | 2180 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, |
2126 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2181 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2127 return factory()->NewObjectLiteralProperty(is_get, value, next_pos, | 2182 |
2128 is_static); | 2183 // Make sure the name expression is a string since we need a Name for |
| 2184 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this |
| 2185 // statically we can skip the extra runtime check. |
| 2186 if (!*is_computed_name) { |
| 2187 name_expression = |
| 2188 factory()->NewStringLiteral(name, name_expression->position()); |
| 2189 } |
| 2190 |
| 2191 return factory()->NewObjectLiteralProperty( |
| 2192 is_get, name_expression, value, next_pos, is_static, *is_computed_name); |
2129 | 2193 |
2130 } else if (!in_class && allow_harmony_object_literals_ && | 2194 } else if (!in_class && allow_harmony_object_literals_ && |
2131 Token::IsIdentifier(name_token, strict_mode(), | 2195 Token::IsIdentifier(name_token, strict_mode(), |
2132 this->is_generator())) { | 2196 this->is_generator())) { |
2133 value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory()); | 2197 value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory()); |
2134 | 2198 |
2135 } else { | 2199 } else { |
2136 Token::Value next = Next(); | 2200 Token::Value next = Next(); |
2137 ReportUnexpectedToken(next); | 2201 ReportUnexpectedToken(next); |
2138 *ok = false; | 2202 *ok = false; |
2139 return this->EmptyObjectLiteralProperty(); | 2203 return this->EmptyObjectLiteralProperty(); |
2140 } | 2204 } |
2141 | 2205 |
2142 uint32_t index; | 2206 return factory()->NewObjectLiteralProperty(name_expression, value, is_static, |
2143 LiteralT key = this->IsArrayIndex(name, &index) | 2207 *is_computed_name); |
2144 ? factory()->NewNumberLiteral(index, next_pos) | |
2145 : factory()->NewStringLiteral(name, next_pos); | |
2146 | |
2147 return factory()->NewObjectLiteralProperty(key, value, is_static); | |
2148 } | 2208 } |
2149 | 2209 |
2150 | 2210 |
2151 template <class Traits> | 2211 template <class Traits> |
2152 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( | 2212 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( |
2153 bool* ok) { | 2213 bool* ok) { |
2154 // ObjectLiteral :: | 2214 // ObjectLiteral :: |
2155 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' | 2215 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
2156 | 2216 |
2157 int pos = peek_position(); | 2217 int pos = peek_position(); |
2158 typename Traits::Type::PropertyList properties = | 2218 typename Traits::Type::PropertyList properties = |
2159 this->NewPropertyList(4, zone_); | 2219 this->NewPropertyList(4, zone_); |
2160 int number_of_boilerplate_properties = 0; | 2220 int number_of_boilerplate_properties = 0; |
2161 bool has_function = false; | 2221 bool has_function = false; |
| 2222 bool has_computed_names = false; |
2162 | 2223 |
2163 ObjectLiteralChecker checker(this, strict_mode()); | 2224 ObjectLiteralChecker checker(this, strict_mode()); |
2164 | 2225 |
2165 Expect(Token::LBRACE, CHECK_OK); | 2226 Expect(Token::LBRACE, CHECK_OK); |
2166 | 2227 |
2167 while (peek() != Token::RBRACE) { | 2228 while (peek() != Token::RBRACE) { |
2168 if (fni_ != NULL) fni_->Enter(); | 2229 if (fni_ != NULL) fni_->Enter(); |
2169 | 2230 |
2170 const bool in_class = false; | 2231 const bool in_class = false; |
2171 const bool is_static = false; | 2232 const bool is_static = false; |
| 2233 bool is_computed_name = false; |
2172 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( | 2234 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( |
2173 &checker, in_class, is_static, NULL, CHECK_OK); | 2235 &checker, in_class, is_static, &is_computed_name, NULL, CHECK_OK); |
| 2236 |
| 2237 if (is_computed_name) { |
| 2238 has_computed_names = true; |
| 2239 } |
2174 | 2240 |
2175 // Mark top-level object literals that contain function literals and | 2241 // Mark top-level object literals that contain function literals and |
2176 // pretenure the literal so it can be added as a constant function | 2242 // pretenure the literal so it can be added as a constant function |
2177 // property. (Parser only.) | 2243 // property. (Parser only.) |
2178 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, | 2244 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, |
2179 &has_function); | 2245 &has_function); |
2180 | 2246 |
2181 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 2247 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
2182 if (this->IsBoilerplateProperty(property)) { | 2248 if (!has_computed_names && this->IsBoilerplateProperty(property)) { |
2183 number_of_boilerplate_properties++; | 2249 number_of_boilerplate_properties++; |
2184 } | 2250 } |
2185 properties->Add(property, zone()); | 2251 properties->Add(property, zone()); |
2186 | 2252 |
2187 if (peek() != Token::RBRACE) { | 2253 if (peek() != Token::RBRACE) { |
2188 // Need {} because of the CHECK_OK macro. | 2254 // Need {} because of the CHECK_OK macro. |
2189 Expect(Token::COMMA, CHECK_OK); | 2255 Expect(Token::COMMA, CHECK_OK); |
2190 } | 2256 } |
2191 | 2257 |
2192 if (fni_ != NULL) { | 2258 if (fni_ != NULL) { |
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2968 DCHECK(IsAccessorAccessorConflict(old_type, type)); | 3034 DCHECK(IsAccessorAccessorConflict(old_type, type)); |
2969 // Both accessors of the same type. | 3035 // Both accessors of the same type. |
2970 parser()->ReportMessage("accessor_get_set"); | 3036 parser()->ReportMessage("accessor_get_set"); |
2971 } | 3037 } |
2972 *ok = false; | 3038 *ok = false; |
2973 } | 3039 } |
2974 } | 3040 } |
2975 } } // v8::internal | 3041 } } // v8::internal |
2976 | 3042 |
2977 #endif // V8_PREPARSER_H | 3043 #endif // V8_PREPARSER_H |
OLD | NEW |