Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: src/preparser.h

Issue 795573005: ES6 computed property names (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Moar tests Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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 719 matching lines...) Expand 10 before | Expand all | Expand 10 after
1948 Expect(Token::RBRACK, CHECK_OK); 1970 Expect(Token::RBRACK, CHECK_OK);
1949 1971
1950 // Update the scope information before the pre-parsing bailout. 1972 // Update the scope information before the pre-parsing bailout.
1951 int literal_index = function_state_->NextMaterializedLiteralIndex(); 1973 int literal_index = function_state_->NextMaterializedLiteralIndex();
1952 1974
1953 return factory()->NewArrayLiteral(values, literal_index, pos); 1975 return factory()->NewArrayLiteral(values, literal_index, pos);
1954 } 1976 }
1955 1977
1956 1978
1957 template <class Traits> 1979 template <class Traits>
1958 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParsePropertyName( 1980 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
1959 bool* is_get, bool* is_set, bool* is_static, bool* ok) { 1981 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static,
1960 Token::Value next = peek(); 1982 bool* is_computed_name, bool* ok) {
1961 switch (next) { 1983 Token::Value token = peek();
1984 int pos = peek_position();
1985
1986 // For non computed property names we normalize the name a bit:
1987 //
1988 // "12" -> 12
1989 // 12.3 -> "12.3"
1990 // 12.30 -> "12.3"
1991 // identifier -> "identifier"
1992 //
1993 // This is important because we use the property name as a key in a hash
1994 // table when we computed constant properties.
1995 switch (token) {
1962 case Token::STRING: 1996 case Token::STRING:
1963 Consume(Token::STRING); 1997 Consume(Token::STRING);
1964 return this->GetSymbol(scanner_); 1998 *name = this->GetSymbol(scanner());
1999 break;
2000
1965 case Token::NUMBER: 2001 case Token::NUMBER:
1966 Consume(Token::NUMBER); 2002 Consume(Token::NUMBER);
1967 return this->GetNumberAsSymbol(scanner_); 2003 *name = this->GetNumberAsSymbol(scanner());
2004 break;
2005
2006 case Token::LBRACK:
2007 if (allow_harmony_computed_property_names_) {
2008 *is_computed_name = true;
2009 Consume(Token::LBRACK);
2010 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK);
2011 Expect(Token::RBRACK, CHECK_OK);
2012 return expression;
2013 }
2014
2015 // Fall through.
1968 case Token::STATIC: 2016 case Token::STATIC:
1969 *is_static = true; 2017 *is_static = true;
1970 // Fall through. 2018
2019 // Fall through.
1971 default: 2020 default:
1972 return ParseIdentifierNameOrGetOrSet(is_get, is_set, ok); 2021 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
2022 break;
1973 } 2023 }
1974 UNREACHABLE(); 2024
1975 return this->EmptyIdentifier(); 2025 uint32_t index;
2026 return this->IsArrayIndex(*name, &index)
2027 ? factory()->NewNumberLiteral(index, pos)
2028 : factory()->NewStringLiteral(*name, pos);
1976 } 2029 }
1977 2030
1978 2031
1979 template <class Traits> 2032 template <class Traits>
1980 typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase< 2033 typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase<
1981 Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker, 2034 Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker,
1982 bool in_class, bool is_static, 2035 bool in_class, bool is_static,
2036 bool* is_computed_name,
1983 bool* has_seen_constructor, bool* ok) { 2037 bool* has_seen_constructor, bool* ok) {
1984 DCHECK(!in_class || is_static || has_seen_constructor != NULL); 2038 DCHECK(!in_class || is_static || has_seen_constructor != NULL);
1985 ExpressionT value = this->EmptyExpression(); 2039 ExpressionT value = this->EmptyExpression();
2040 IdentifierT name = this->EmptyIdentifier();
1986 bool is_get = false; 2041 bool is_get = false;
1987 bool is_set = false; 2042 bool is_set = false;
1988 bool name_is_static = false; 2043 bool name_is_static = false;
1989 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); 2044 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL);
1990 2045
1991 Token::Value name_token = peek(); 2046 Token::Value name_token = peek();
1992 int next_pos = peek_position(); 2047 int next_pos = peek_position();
1993 IdentifierT name = 2048 ExpressionT name_expression = ParsePropertyName(
1994 ParsePropertyName(&is_get, &is_set, &name_is_static, 2049 &name, &is_get, &is_set, &name_is_static, is_computed_name,
1995 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2050 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1996 2051
1997 if (fni_ != NULL) this->PushLiteralName(fni_, name); 2052 if (fni_ != NULL && !*is_computed_name) {
2053 this->PushLiteralName(fni_, name);
2054 }
1998 2055
1999 if (!in_class && !is_generator && peek() == Token::COLON) { 2056 if (!in_class && !is_generator && peek() == Token::COLON) {
2000 // PropertyDefinition : PropertyName ':' AssignmentExpression 2057 // PropertyDefinition : PropertyName ':' AssignmentExpression
2001 if (checker != NULL) { 2058 if (!*is_computed_name && checker != NULL) {
2002 checker->CheckProperty(name_token, kValueProperty, 2059 checker->CheckProperty(name_token, kValueProperty,
2003 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2060 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2004 } 2061 }
2005 Consume(Token::COLON); 2062 Consume(Token::COLON);
2006 value = this->ParseAssignmentExpression( 2063 value = this->ParseAssignmentExpression(
2007 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2064 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2008 2065
2009 } else if (is_generator || 2066 } else if (is_generator ||
2010 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { 2067 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) {
2011 // Concise Method 2068 // Concise Method
(...skipping 17 matching lines...) Expand all
2029 if (*has_seen_constructor) { 2086 if (*has_seen_constructor) {
2030 ReportMessageAt(scanner()->location(), "duplicate_constructor"); 2087 ReportMessageAt(scanner()->location(), "duplicate_constructor");
2031 *ok = false; 2088 *ok = false;
2032 return this->EmptyObjectLiteralProperty(); 2089 return this->EmptyObjectLiteralProperty();
2033 } 2090 }
2034 2091
2035 *has_seen_constructor = true; 2092 *has_seen_constructor = true;
2036 kind = FunctionKind::kNormalFunction; 2093 kind = FunctionKind::kNormalFunction;
2037 } 2094 }
2038 2095
2039 if (checker != NULL) { 2096 if (!*is_computed_name && checker != NULL) {
2040 checker->CheckProperty(name_token, kValueProperty, 2097 checker->CheckProperty(name_token, kValueProperty,
2041 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2098 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2042 } 2099 }
2043 2100
2044 value = this->ParseFunctionLiteral( 2101 value = this->ParseFunctionLiteral(
2045 name, scanner()->location(), 2102 name, scanner()->location(),
2046 false, // reserved words are allowed here 2103 false, // reserved words are allowed here
2047 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, 2104 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
2048 FunctionLiteral::NORMAL_ARITY, 2105 FunctionLiteral::NORMAL_ARITY,
2049 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2106 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2050 2107
2051 } else if (in_class && name_is_static && !is_static) { 2108 } else if (in_class && name_is_static && !is_static) {
2052 // static MethodDefinition 2109 // static MethodDefinition
2053 return ParsePropertyDefinition(checker, true, true, NULL, ok); 2110 return ParsePropertyDefinition(checker, true, true, is_computed_name, NULL,
2111 ok);
2054 2112
2055 } else if (is_get || is_set) { 2113 } else if (is_get || is_set) {
2056 // Accessor 2114 // Accessor
2115 name = this->EmptyIdentifier();
2057 bool dont_care = false; 2116 bool dont_care = false;
2058 name_token = peek(); 2117 name_token = peek();
2059 name = ParsePropertyName(&dont_care, &dont_care, &dont_care, 2118
2060 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2119 name_expression = ParsePropertyName(
2120 &name, &dont_care, &dont_care, &dont_care, is_computed_name,
2121 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2061 2122
2062 // Validate the property. 2123 // Validate the property.
2063 if (is_static && this->IsPrototype(name)) { 2124 if (is_static && this->IsPrototype(name)) {
2064 ReportMessageAt(scanner()->location(), "static_prototype"); 2125 ReportMessageAt(scanner()->location(), "static_prototype");
2065 *ok = false; 2126 *ok = false;
2066 return this->EmptyObjectLiteralProperty(); 2127 return this->EmptyObjectLiteralProperty();
2067 } else if (in_class && !is_static && this->IsConstructor(name)) { 2128 } else if (in_class && !is_static && this->IsConstructor(name)) {
2068 ReportMessageAt(scanner()->location(), "constructor_special_method"); 2129 ReportMessageAt(scanner()->location(), "constructor_special_method");
2069 *ok = false; 2130 *ok = false;
2070 return this->EmptyObjectLiteralProperty(); 2131 return this->EmptyObjectLiteralProperty();
2071 } 2132 }
2072 if (checker != NULL) { 2133 if (!*is_computed_name && checker != NULL) {
2073 checker->CheckProperty(name_token, 2134 checker->CheckProperty(name_token,
2074 is_get ? kGetterProperty : kSetterProperty, 2135 is_get ? kGetterProperty : kSetterProperty,
2075 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2136 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2076 } 2137 }
2077 2138
2078 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( 2139 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
2079 name, scanner()->location(), 2140 name, scanner()->location(),
2080 false, // reserved words are allowed here 2141 false, // reserved words are allowed here
2081 FunctionKind::kNormalFunction, RelocInfo::kNoPosition, 2142 FunctionKind::kNormalFunction, RelocInfo::kNoPosition,
2082 FunctionLiteral::ANONYMOUS_EXPRESSION, 2143 FunctionLiteral::ANONYMOUS_EXPRESSION,
2083 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, 2144 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY,
2084 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2145 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2085 return factory()->NewObjectLiteralProperty(is_get, value, next_pos, 2146
2086 is_static); 2147 // For non computed property names we always use string based keys for
2148 // accessors. This is because accessors are not elements.
2149 if (!*is_computed_name) {
2150 name_expression =
2151 factory()->NewStringLiteral(name, name_expression->position());
2152 }
2153
2154 return factory()->NewObjectLiteralProperty(
2155 is_get, name_expression, value, next_pos, is_static, *is_computed_name);
2087 2156
2088 } else if (!in_class && allow_harmony_object_literals_ && 2157 } else if (!in_class && allow_harmony_object_literals_ &&
2089 Token::IsIdentifier(name_token, strict_mode(), 2158 Token::IsIdentifier(name_token, strict_mode(),
2090 this->is_generator())) { 2159 this->is_generator())) {
2091 value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory()); 2160 value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory());
2092 2161
2093 } else { 2162 } else {
2094 Token::Value next = Next(); 2163 Token::Value next = Next();
2095 ReportUnexpectedToken(next); 2164 ReportUnexpectedToken(next);
2096 *ok = false; 2165 *ok = false;
2097 return this->EmptyObjectLiteralProperty(); 2166 return this->EmptyObjectLiteralProperty();
2098 } 2167 }
2099 2168
2100 uint32_t index; 2169 return factory()->NewObjectLiteralProperty(name_expression, value, is_static,
2101 LiteralT key = this->IsArrayIndex(name, &index) 2170 *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 } 2171 }
2107 2172
2108 2173
2109 template <class Traits> 2174 template <class Traits>
2110 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( 2175 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
2111 bool* ok) { 2176 bool* ok) {
2112 // ObjectLiteral :: 2177 // ObjectLiteral ::
2113 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' 2178 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
2114 2179
2115 int pos = peek_position(); 2180 int pos = peek_position();
2116 typename Traits::Type::PropertyList properties = 2181 typename Traits::Type::PropertyList properties =
2117 this->NewPropertyList(4, zone_); 2182 this->NewPropertyList(4, zone_);
2118 int number_of_boilerplate_properties = 0; 2183 int number_of_boilerplate_properties = 0;
2119 bool has_function = false; 2184 bool has_function = false;
2185 bool has_computed_names = false;
2120 2186
2121 ObjectLiteralChecker checker(this, strict_mode()); 2187 ObjectLiteralChecker checker(this, strict_mode());
2122 2188
2123 Expect(Token::LBRACE, CHECK_OK); 2189 Expect(Token::LBRACE, CHECK_OK);
2124 2190
2125 while (peek() != Token::RBRACE) { 2191 while (peek() != Token::RBRACE) {
2126 if (fni_ != NULL) fni_->Enter(); 2192 if (fni_ != NULL) fni_->Enter();
2127 2193
2128 const bool in_class = false; 2194 const bool in_class = false;
2129 const bool is_static = false; 2195 const bool is_static = false;
2196 bool is_computed_name = false;
2130 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( 2197 ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
2131 &checker, in_class, is_static, NULL, CHECK_OK); 2198 &checker, in_class, is_static, &is_computed_name, NULL, CHECK_OK);
2199
2200 if (is_computed_name) {
2201 has_computed_names = true;
2202 }
2132 2203
2133 // Mark top-level object literals that contain function literals and 2204 // Mark top-level object literals that contain function literals and
2134 // pretenure the literal so it can be added as a constant function 2205 // pretenure the literal so it can be added as a constant function
2135 // property. (Parser only.) 2206 // property. (Parser only.)
2136 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, 2207 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property,
2137 &has_function); 2208 &has_function);
2138 2209
2139 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. 2210 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
2140 if (this->IsBoilerplateProperty(property)) { 2211 if (!has_computed_names && this->IsBoilerplateProperty(property)) {
2141 number_of_boilerplate_properties++; 2212 number_of_boilerplate_properties++;
2142 } 2213 }
2143 properties->Add(property, zone()); 2214 properties->Add(property, zone());
2144 2215
2145 if (peek() != Token::RBRACE) { 2216 if (peek() != Token::RBRACE) {
2146 // Need {} because of the CHECK_OK macro. 2217 // Need {} because of the CHECK_OK macro.
2147 Expect(Token::COMMA, CHECK_OK); 2218 Expect(Token::COMMA, CHECK_OK);
2148 } 2219 }
2149 2220
2150 if (fni_ != NULL) { 2221 if (fni_ != NULL) {
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
2922 DCHECK(IsAccessorAccessorConflict(old_type, type)); 2993 DCHECK(IsAccessorAccessorConflict(old_type, type));
2923 // Both accessors of the same type. 2994 // Both accessors of the same type.
2924 parser()->ReportMessage("accessor_get_set"); 2995 parser()->ReportMessage("accessor_get_set");
2925 } 2996 }
2926 *ok = false; 2997 *ok = false;
2927 } 2998 }
2928 } 2999 }
2929 } } // v8::internal 3000 } } // v8::internal
2930 3001
2931 #endif // V8_PREPARSER_H 3002 #endif // V8_PREPARSER_H
OLDNEW
« src/arm/full-codegen-arm.cc ('K') | « src/ppc/full-codegen-ppc.cc ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698