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), | |
91 zone_(zone) {} | 90 zone_(zone) {} |
92 | 91 |
93 // Getters that indicate whether certain syntactical constructs are | 92 // Getters that indicate whether certain syntactical constructs are |
94 // allowed to be parsed by this instance of the parser. | 93 // allowed to be parsed by this instance of the parser. |
95 bool allow_lazy() const { return allow_lazy_; } | 94 bool allow_lazy() const { return allow_lazy_; } |
96 bool allow_natives() const { return allow_natives_; } | 95 bool allow_natives() const { return allow_natives_; } |
97 bool allow_harmony_arrow_functions() const { | 96 bool allow_harmony_arrow_functions() const { |
98 return allow_harmony_arrow_functions_; | 97 return allow_harmony_arrow_functions_; |
99 } | 98 } |
100 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); } | 99 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); } |
101 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } | 100 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } |
102 bool allow_harmony_numeric_literals() const { | 101 bool allow_harmony_numeric_literals() const { |
103 return scanner()->HarmonyNumericLiterals(); | 102 return scanner()->HarmonyNumericLiterals(); |
104 } | 103 } |
105 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } | 104 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } |
106 bool allow_harmony_object_literals() const { | 105 bool allow_harmony_object_literals() const { |
107 return allow_harmony_object_literals_; | 106 return allow_harmony_object_literals_; |
108 } | 107 } |
109 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); } | 108 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); } |
110 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } | 109 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } |
111 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } | 110 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } |
112 bool allow_harmony_computed_property_names() const { | |
113 return allow_harmony_computed_property_names_; | |
114 } | |
115 | 111 |
116 // Setters that determine whether certain syntactical constructs are | 112 // Setters that determine whether certain syntactical constructs are |
117 // allowed to be parsed by this instance of the parser. | 113 // allowed to be parsed by this instance of the parser. |
118 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 114 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
119 void set_allow_natives(bool allow) { allow_natives_ = allow; } | 115 void set_allow_natives(bool allow) { allow_natives_ = allow; } |
120 void set_allow_harmony_arrow_functions(bool allow) { | 116 void set_allow_harmony_arrow_functions(bool allow) { |
121 allow_harmony_arrow_functions_ = allow; | 117 allow_harmony_arrow_functions_ = allow; |
122 } | 118 } |
123 void set_allow_harmony_modules(bool allow) { | 119 void set_allow_harmony_modules(bool allow) { |
124 scanner()->SetHarmonyModules(allow); | 120 scanner()->SetHarmonyModules(allow); |
(...skipping 12 matching lines...) Expand all Loading... |
137 } | 133 } |
138 void set_allow_harmony_templates(bool allow) { | 134 void set_allow_harmony_templates(bool allow) { |
139 scanner()->SetHarmonyTemplates(allow); | 135 scanner()->SetHarmonyTemplates(allow); |
140 } | 136 } |
141 void set_allow_harmony_sloppy(bool allow) { | 137 void set_allow_harmony_sloppy(bool allow) { |
142 allow_harmony_sloppy_ = allow; | 138 allow_harmony_sloppy_ = allow; |
143 } | 139 } |
144 void set_allow_harmony_unicode(bool allow) { | 140 void set_allow_harmony_unicode(bool allow) { |
145 scanner()->SetHarmonyUnicode(allow); | 141 scanner()->SetHarmonyUnicode(allow); |
146 } | 142 } |
147 void set_allow_harmony_computed_property_names(bool allow) { | |
148 allow_harmony_computed_property_names_ = allow; | |
149 } | |
150 | 143 |
151 protected: | 144 protected: |
152 enum AllowEvalOrArgumentsAsIdentifier { | 145 enum AllowEvalOrArgumentsAsIdentifier { |
153 kAllowEvalOrArguments, | 146 kAllowEvalOrArguments, |
154 kDontAllowEvalOrArguments | 147 kDontAllowEvalOrArguments |
155 }; | 148 }; |
156 | 149 |
157 enum Mode { | 150 enum Mode { |
158 PARSE_LAZILY, | 151 PARSE_LAZILY, |
159 PARSE_EAGERLY | 152 PARSE_EAGERLY |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 // Parses an identifier and determines whether or not it is 'get' or 'set'. | 483 // Parses an identifier and determines whether or not it is 'get' or 'set'. |
491 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, | 484 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, |
492 bool* is_set, | 485 bool* is_set, |
493 bool* ok); | 486 bool* ok); |
494 | 487 |
495 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); | 488 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); |
496 | 489 |
497 ExpressionT ParsePrimaryExpression(bool* ok); | 490 ExpressionT ParsePrimaryExpression(bool* ok); |
498 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 491 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
499 ExpressionT ParseArrayLiteral(bool* ok); | 492 ExpressionT ParseArrayLiteral(bool* ok); |
500 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 493 IdentifierT ParsePropertyName(bool* is_get, bool* is_set, bool* is_static, |
501 bool* is_static, bool* is_computed_name, | |
502 bool* ok); | 494 bool* ok); |
503 ExpressionT ParseObjectLiteral(bool* ok); | 495 ExpressionT ParseObjectLiteral(bool* ok); |
504 ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker, | 496 ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker, |
505 bool in_class, bool is_static, | 497 bool in_class, bool is_static, |
506 bool* is_computed_name, | |
507 bool* has_seen_constructor, | 498 bool* has_seen_constructor, |
508 bool* ok); | 499 bool* ok); |
509 typename Traits::Type::ExpressionList ParseArguments(bool* ok); | 500 typename Traits::Type::ExpressionList ParseArguments(bool* ok); |
510 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 501 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
511 ExpressionT ParseYieldExpression(bool* ok); | 502 ExpressionT ParseYieldExpression(bool* ok); |
512 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 503 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
513 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 504 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
514 ExpressionT ParseUnaryExpression(bool* ok); | 505 ExpressionT ParseUnaryExpression(bool* ok); |
515 ExpressionT ParsePostfixExpression(bool* ok); | 506 ExpressionT ParsePostfixExpression(bool* ok); |
516 ExpressionT ParseLeftHandSideExpression(bool* ok); | 507 ExpressionT ParseLeftHandSideExpression(bool* ok); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
600 | 591 |
601 private: | 592 private: |
602 Scanner* scanner_; | 593 Scanner* scanner_; |
603 bool stack_overflow_; | 594 bool stack_overflow_; |
604 | 595 |
605 bool allow_lazy_; | 596 bool allow_lazy_; |
606 bool allow_natives_; | 597 bool allow_natives_; |
607 bool allow_harmony_arrow_functions_; | 598 bool allow_harmony_arrow_functions_; |
608 bool allow_harmony_object_literals_; | 599 bool allow_harmony_object_literals_; |
609 bool allow_harmony_sloppy_; | 600 bool allow_harmony_sloppy_; |
610 bool allow_harmony_computed_property_names_; | |
611 | 601 |
612 typename Traits::Type::Zone* zone_; // Only used by Parser. | 602 typename Traits::Type::Zone* zone_; // Only used by Parser. |
613 }; | 603 }; |
614 | 604 |
615 | 605 |
616 class PreParserIdentifier { | 606 class PreParserIdentifier { |
617 public: | 607 public: |
618 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 608 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
619 static PreParserIdentifier Default() { | 609 static PreParserIdentifier Default() { |
620 return PreParserIdentifier(kUnknownIdentifier); | 610 return PreParserIdentifier(kUnknownIdentifier); |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1034 int literal_index, | 1024 int literal_index, |
1035 int pos) { | 1025 int pos) { |
1036 return PreParserExpression::Default(); | 1026 return PreParserExpression::Default(); |
1037 } | 1027 } |
1038 PreParserExpression NewArrayLiteral(PreParserExpressionList values, | 1028 PreParserExpression NewArrayLiteral(PreParserExpressionList values, |
1039 int literal_index, | 1029 int literal_index, |
1040 int pos) { | 1030 int pos) { |
1041 return PreParserExpression::Default(); | 1031 return PreParserExpression::Default(); |
1042 } | 1032 } |
1043 PreParserExpression NewObjectLiteralProperty(bool is_getter, | 1033 PreParserExpression NewObjectLiteralProperty(bool is_getter, |
1044 PreParserExpression key, | |
1045 PreParserExpression value, | 1034 PreParserExpression value, |
1046 int pos, bool is_static, | 1035 int pos, bool is_static) { |
1047 bool is_computed_name) { | |
1048 return PreParserExpression::Default(); | 1036 return PreParserExpression::Default(); |
1049 } | 1037 } |
1050 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, | 1038 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, |
1051 PreParserExpression value, | 1039 PreParserExpression value, |
1052 bool is_static, | 1040 bool is_static) { |
1053 bool is_computed_name) { | |
1054 return PreParserExpression::Default(); | 1041 return PreParserExpression::Default(); |
1055 } | 1042 } |
1056 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, | 1043 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, |
1057 int literal_index, | 1044 int literal_index, |
1058 int boilerplate_properties, | 1045 int boilerplate_properties, |
1059 bool has_function, | 1046 bool has_function, |
1060 int pos) { | 1047 int pos) { |
1061 return PreParserExpression::Default(); | 1048 return PreParserExpression::Default(); |
1062 } | 1049 } |
1063 PreParserExpression NewVariableProxy(void* variable) { | 1050 PreParserExpression NewVariableProxy(void* variable) { |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1229 static PreParserExpression GetPropertyValue(PreParserExpression property) { | 1216 static PreParserExpression GetPropertyValue(PreParserExpression property) { |
1230 return PreParserExpression::Default(); | 1217 return PreParserExpression::Default(); |
1231 } | 1218 } |
1232 | 1219 |
1233 // Functions for encapsulating the differences between parsing and preparsing; | 1220 // Functions for encapsulating the differences between parsing and preparsing; |
1234 // operations interleaved with the recursive descent. | 1221 // operations interleaved with the recursive descent. |
1235 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { | 1222 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { |
1236 // PreParser should not use FuncNameInferrer. | 1223 // PreParser should not use FuncNameInferrer. |
1237 UNREACHABLE(); | 1224 UNREACHABLE(); |
1238 } | 1225 } |
1239 | |
1240 static void PushPropertyName(FuncNameInferrer* fni, | 1226 static void PushPropertyName(FuncNameInferrer* fni, |
1241 PreParserExpression expression) { | 1227 PreParserExpression expression) { |
1242 // PreParser should not use FuncNameInferrer. | 1228 // PreParser should not use FuncNameInferrer. |
1243 UNREACHABLE(); | 1229 UNREACHABLE(); |
1244 } | 1230 } |
1245 | |
1246 static void InferFunctionName(FuncNameInferrer* fni, | 1231 static void InferFunctionName(FuncNameInferrer* fni, |
1247 PreParserExpression expression) { | 1232 PreParserExpression expression) { |
1248 // PreParser should not use FuncNameInferrer. | 1233 // PreParser should not use FuncNameInferrer. |
1249 UNREACHABLE(); | 1234 UNREACHABLE(); |
1250 } | 1235 } |
1251 | 1236 |
1252 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( | 1237 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( |
1253 PreParserScope* scope, PreParserExpression property, bool* has_function) { | 1238 PreParserScope* scope, PreParserExpression property, bool* has_function) { |
1254 } | 1239 } |
1255 | 1240 |
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1995 Expect(Token::RBRACK, CHECK_OK); | 1980 Expect(Token::RBRACK, CHECK_OK); |
1996 | 1981 |
1997 // Update the scope information before the pre-parsing bailout. | 1982 // Update the scope information before the pre-parsing bailout. |
1998 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 1983 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
1999 | 1984 |
2000 return factory()->NewArrayLiteral(values, literal_index, pos); | 1985 return factory()->NewArrayLiteral(values, literal_index, pos); |
2001 } | 1986 } |
2002 | 1987 |
2003 | 1988 |
2004 template <class Traits> | 1989 template <class Traits> |
2005 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( | 1990 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParsePropertyName( |
2006 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static, | 1991 bool* is_get, bool* is_set, bool* is_static, bool* ok) { |
2007 bool* is_computed_name, bool* ok) { | 1992 Token::Value next = peek(); |
2008 Token::Value token = peek(); | 1993 switch (next) { |
2009 int pos = peek_position(); | |
2010 | |
2011 // For non computed property names we normalize the name a bit: | |
2012 // | |
2013 // "12" -> 12 | |
2014 // 12.3 -> "12.3" | |
2015 // 12.30 -> "12.3" | |
2016 // identifier -> "identifier" | |
2017 // | |
2018 // This is important because we use the property name as a key in a hash | |
2019 // table when we compute constant properties. | |
2020 switch (token) { | |
2021 case Token::STRING: | 1994 case Token::STRING: |
2022 Consume(Token::STRING); | 1995 Consume(Token::STRING); |
2023 *name = this->GetSymbol(scanner()); | 1996 return this->GetSymbol(scanner_); |
2024 break; | |
2025 | |
2026 case Token::NUMBER: | 1997 case Token::NUMBER: |
2027 Consume(Token::NUMBER); | 1998 Consume(Token::NUMBER); |
2028 *name = this->GetNumberAsSymbol(scanner()); | 1999 return this->GetNumberAsSymbol(scanner_); |
2029 break; | |
2030 | |
2031 case Token::LBRACK: | |
2032 if (allow_harmony_computed_property_names_) { | |
2033 *is_computed_name = true; | |
2034 Consume(Token::LBRACK); | |
2035 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); | |
2036 Expect(Token::RBRACK, CHECK_OK); | |
2037 return expression; | |
2038 } | |
2039 | |
2040 // Fall through. | |
2041 case Token::STATIC: | 2000 case Token::STATIC: |
2042 *is_static = true; | 2001 *is_static = true; |
2043 | 2002 // Fall through. |
2044 // Fall through. | |
2045 default: | 2003 default: |
2046 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); | 2004 return ParseIdentifierNameOrGetOrSet(is_get, is_set, ok); |
2047 break; | |
2048 } | 2005 } |
2049 | 2006 UNREACHABLE(); |
2050 uint32_t index; | 2007 return this->EmptyIdentifier(); |
2051 return this->IsArrayIndex(*name, &index) | |
2052 ? factory()->NewNumberLiteral(index, pos) | |
2053 : factory()->NewStringLiteral(*name, pos); | |
2054 } | 2008 } |
2055 | 2009 |
2056 | 2010 |
2057 template <class Traits> | 2011 template <class Traits> |
2058 typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase< | 2012 typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase< |
2059 Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker, | 2013 Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker, |
2060 bool in_class, bool is_static, | 2014 bool in_class, bool is_static, |
2061 bool* is_computed_name, | |
2062 bool* has_seen_constructor, bool* ok) { | 2015 bool* has_seen_constructor, bool* ok) { |
2063 DCHECK(!in_class || is_static || has_seen_constructor != NULL); | 2016 DCHECK(!in_class || is_static || has_seen_constructor != NULL); |
2064 ExpressionT value = this->EmptyExpression(); | 2017 ExpressionT value = this->EmptyExpression(); |
2065 IdentifierT name = this->EmptyIdentifier(); | |
2066 bool is_get = false; | 2018 bool is_get = false; |
2067 bool is_set = false; | 2019 bool is_set = false; |
2068 bool name_is_static = false; | 2020 bool name_is_static = false; |
2069 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); | 2021 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); |
2070 | 2022 |
2071 Token::Value name_token = peek(); | 2023 Token::Value name_token = peek(); |
2072 int next_pos = peek_position(); | 2024 int next_pos = peek_position(); |
2073 ExpressionT name_expression = ParsePropertyName( | 2025 IdentifierT name = |
2074 &name, &is_get, &is_set, &name_is_static, is_computed_name, | 2026 ParsePropertyName(&is_get, &is_set, &name_is_static, |
2075 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2027 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2076 | 2028 |
2077 if (fni_ != NULL && !*is_computed_name) { | 2029 if (fni_ != NULL) this->PushLiteralName(fni_, name); |
2078 this->PushLiteralName(fni_, name); | |
2079 } | |
2080 | 2030 |
2081 if (!in_class && !is_generator && peek() == Token::COLON) { | 2031 if (!in_class && !is_generator && peek() == Token::COLON) { |
2082 // PropertyDefinition : PropertyName ':' AssignmentExpression | 2032 // PropertyDefinition : PropertyName ':' AssignmentExpression |
2083 if (!*is_computed_name && checker != NULL) { | 2033 if (checker != NULL) { |
2084 checker->CheckProperty(name_token, kValueProperty, | 2034 checker->CheckProperty(name_token, kValueProperty, |
2085 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2035 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2086 } | 2036 } |
2087 Consume(Token::COLON); | 2037 Consume(Token::COLON); |
2088 value = this->ParseAssignmentExpression( | 2038 value = this->ParseAssignmentExpression( |
2089 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2039 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2090 | 2040 |
2091 } else if (is_generator || | 2041 } else if (is_generator || |
2092 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { | 2042 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { |
2093 // Concise Method | 2043 // Concise Method |
(...skipping 17 matching lines...) Expand all Loading... |
2111 if (*has_seen_constructor) { | 2061 if (*has_seen_constructor) { |
2112 ReportMessageAt(scanner()->location(), "duplicate_constructor"); | 2062 ReportMessageAt(scanner()->location(), "duplicate_constructor"); |
2113 *ok = false; | 2063 *ok = false; |
2114 return this->EmptyObjectLiteralProperty(); | 2064 return this->EmptyObjectLiteralProperty(); |
2115 } | 2065 } |
2116 | 2066 |
2117 *has_seen_constructor = true; | 2067 *has_seen_constructor = true; |
2118 kind = FunctionKind::kNormalFunction; | 2068 kind = FunctionKind::kNormalFunction; |
2119 } | 2069 } |
2120 | 2070 |
2121 if (!*is_computed_name && checker != NULL) { | 2071 if (checker != NULL) { |
2122 checker->CheckProperty(name_token, kValueProperty, | 2072 checker->CheckProperty(name_token, kValueProperty, |
2123 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2073 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2124 } | 2074 } |
2125 | 2075 |
2126 value = this->ParseFunctionLiteral( | 2076 value = this->ParseFunctionLiteral( |
2127 name, scanner()->location(), | 2077 name, scanner()->location(), |
2128 false, // reserved words are allowed here | 2078 false, // reserved words are allowed here |
2129 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, | 2079 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, |
2130 FunctionLiteral::NORMAL_ARITY, | 2080 FunctionLiteral::NORMAL_ARITY, |
2131 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2081 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2132 | 2082 |
2133 } else if (in_class && name_is_static && !is_static) { | 2083 } else if (in_class && name_is_static && !is_static) { |
2134 // static MethodDefinition | 2084 // static MethodDefinition |
2135 return ParsePropertyDefinition(checker, true, true, is_computed_name, NULL, | 2085 return ParsePropertyDefinition(checker, true, true, NULL, ok); |
2136 ok); | |
2137 | 2086 |
2138 } else if (is_get || is_set) { | 2087 } else if (is_get || is_set) { |
2139 // Accessor | 2088 // Accessor |
2140 name = this->EmptyIdentifier(); | |
2141 bool dont_care = false; | 2089 bool dont_care = false; |
2142 name_token = peek(); | 2090 name_token = peek(); |
2143 | 2091 name = ParsePropertyName(&dont_care, &dont_care, &dont_care, |
2144 name_expression = ParsePropertyName( | 2092 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2145 &name, &dont_care, &dont_care, &dont_care, is_computed_name, | |
2146 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
2147 | 2093 |
2148 // Validate the property. | 2094 // Validate the property. |
2149 if (is_static && this->IsPrototype(name)) { | 2095 if (is_static && this->IsPrototype(name)) { |
2150 ReportMessageAt(scanner()->location(), "static_prototype"); | 2096 ReportMessageAt(scanner()->location(), "static_prototype"); |
2151 *ok = false; | 2097 *ok = false; |
2152 return this->EmptyObjectLiteralProperty(); | 2098 return this->EmptyObjectLiteralProperty(); |
2153 } else if (in_class && !is_static && this->IsConstructor(name)) { | 2099 } else if (in_class && !is_static && this->IsConstructor(name)) { |
2154 ReportMessageAt(scanner()->location(), "constructor_special_method"); | 2100 ReportMessageAt(scanner()->location(), "constructor_special_method"); |
2155 *ok = false; | 2101 *ok = false; |
2156 return this->EmptyObjectLiteralProperty(); | 2102 return this->EmptyObjectLiteralProperty(); |
2157 } | 2103 } |
2158 if (!*is_computed_name && checker != NULL) { | 2104 if (checker != NULL) { |
2159 checker->CheckProperty(name_token, | 2105 checker->CheckProperty(name_token, |
2160 is_get ? kGetterProperty : kSetterProperty, | 2106 is_get ? kGetterProperty : kSetterProperty, |
2161 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2107 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2162 } | 2108 } |
2163 | 2109 |
2164 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( | 2110 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( |
2165 name, scanner()->location(), | 2111 name, scanner()->location(), |
2166 false, // reserved words are allowed here | 2112 false, // reserved words are allowed here |
2167 FunctionKind::kNormalFunction, RelocInfo::kNoPosition, | 2113 FunctionKind::kNormalFunction, RelocInfo::kNoPosition, |
2168 FunctionLiteral::ANONYMOUS_EXPRESSION, | 2114 FunctionLiteral::ANONYMOUS_EXPRESSION, |
2169 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, | 2115 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, |
2170 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2116 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2171 | 2117 return factory()->NewObjectLiteralProperty(is_get, value, next_pos, |
2172 // Make sure the name expression is a string since we need a Name for | 2118 is_static); |
2173 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this | |
2174 // statically we can skip the extra runtime check. | |
2175 if (!*is_computed_name) { | |
2176 name_expression = | |
2177 factory()->NewStringLiteral(name, name_expression->position()); | |
2178 } | |
2179 | |
2180 return factory()->NewObjectLiteralProperty( | |
2181 is_get, name_expression, value, next_pos, is_static, *is_computed_name); | |
2182 | 2119 |
2183 } else if (!in_class && allow_harmony_object_literals_ && | 2120 } else if (!in_class && allow_harmony_object_literals_ && |
2184 Token::IsIdentifier(name_token, strict_mode(), | 2121 Token::IsIdentifier(name_token, strict_mode(), |
2185 this->is_generator())) { | 2122 this->is_generator())) { |
2186 value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory()); | 2123 value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory()); |
2187 | 2124 |
2188 } else { | 2125 } else { |
2189 Token::Value next = Next(); | 2126 Token::Value next = Next(); |
2190 ReportUnexpectedToken(next); | 2127 ReportUnexpectedToken(next); |
2191 *ok = false; | 2128 *ok = false; |
2192 return this->EmptyObjectLiteralProperty(); | 2129 return this->EmptyObjectLiteralProperty(); |
2193 } | 2130 } |
2194 | 2131 |
2195 return factory()->NewObjectLiteralProperty(name_expression, value, is_static, | 2132 uint32_t index; |
2196 *is_computed_name); | 2133 LiteralT key = this->IsArrayIndex(name, &index) |
| 2134 ? factory()->NewNumberLiteral(index, next_pos) |
| 2135 : factory()->NewStringLiteral(name, next_pos); |
| 2136 |
| 2137 return factory()->NewObjectLiteralProperty(key, value, is_static); |
2197 } | 2138 } |
2198 | 2139 |
2199 | 2140 |
2200 template <class Traits> | 2141 template <class Traits> |
2201 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( | 2142 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( |
2202 bool* ok) { | 2143 bool* ok) { |
2203 // ObjectLiteral :: | 2144 // ObjectLiteral :: |
2204 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' | 2145 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
2205 | 2146 |
2206 int pos = peek_position(); | 2147 int pos = peek_position(); |
2207 typename Traits::Type::PropertyList properties = | 2148 typename Traits::Type::PropertyList properties = |
2208 this->NewPropertyList(4, zone_); | 2149 this->NewPropertyList(4, zone_); |
2209 int number_of_boilerplate_properties = 0; | 2150 int number_of_boilerplate_properties = 0; |
2210 bool has_function = false; | 2151 bool has_function = false; |
2211 bool has_computed_names = false; | |
2212 | 2152 |
2213 ObjectLiteralChecker checker(this, strict_mode()); | 2153 ObjectLiteralChecker checker(this, strict_mode()); |
2214 | 2154 |
2215 Expect(Token::LBRACE, CHECK_OK); | 2155 Expect(Token::LBRACE, CHECK_OK); |
2216 | 2156 |
2217 while (peek() != Token::RBRACE) { | 2157 while (peek() != Token::RBRACE) { |
2218 if (fni_ != NULL) fni_->Enter(); | 2158 if (fni_ != NULL) fni_->Enter(); |
2219 | 2159 |
2220 const bool in_class = false; | 2160 const bool in_class = false; |
2221 const bool is_static = false; | 2161 const bool is_static = false; |
2222 bool is_computed_name = false; | |
2223 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( | 2162 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( |
2224 &checker, in_class, is_static, &is_computed_name, NULL, CHECK_OK); | 2163 &checker, in_class, is_static, NULL, CHECK_OK); |
2225 | |
2226 if (is_computed_name) { | |
2227 has_computed_names = true; | |
2228 } | |
2229 | 2164 |
2230 // Mark top-level object literals that contain function literals and | 2165 // Mark top-level object literals that contain function literals and |
2231 // pretenure the literal so it can be added as a constant function | 2166 // pretenure the literal so it can be added as a constant function |
2232 // property. (Parser only.) | 2167 // property. (Parser only.) |
2233 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, | 2168 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, |
2234 &has_function); | 2169 &has_function); |
2235 | 2170 |
2236 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 2171 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
2237 if (!has_computed_names && this->IsBoilerplateProperty(property)) { | 2172 if (this->IsBoilerplateProperty(property)) { |
2238 number_of_boilerplate_properties++; | 2173 number_of_boilerplate_properties++; |
2239 } | 2174 } |
2240 properties->Add(property, zone()); | 2175 properties->Add(property, zone()); |
2241 | 2176 |
2242 if (peek() != Token::RBRACE) { | 2177 if (peek() != Token::RBRACE) { |
2243 // Need {} because of the CHECK_OK macro. | 2178 // Need {} because of the CHECK_OK macro. |
2244 Expect(Token::COMMA, CHECK_OK); | 2179 Expect(Token::COMMA, CHECK_OK); |
2245 } | 2180 } |
2246 | 2181 |
2247 if (fni_ != NULL) { | 2182 if (fni_ != NULL) { |
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3019 DCHECK(IsAccessorAccessorConflict(old_type, type)); | 2954 DCHECK(IsAccessorAccessorConflict(old_type, type)); |
3020 // Both accessors of the same type. | 2955 // Both accessors of the same type. |
3021 parser()->ReportMessage("accessor_get_set"); | 2956 parser()->ReportMessage("accessor_get_set"); |
3022 } | 2957 } |
3023 *ok = false; | 2958 *ok = false; |
3024 } | 2959 } |
3025 } | 2960 } |
3026 } } // v8::internal | 2961 } } // v8::internal |
3027 | 2962 |
3028 #endif // V8_PREPARSER_H | 2963 #endif // V8_PREPARSER_H |
OLD | NEW |