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

Side by Side Diff: src/preparser.h

Issue 873823003: Move object literal checking into checker classes (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Split the impl of the checker into 2 classes Created 5 years, 11 months 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
« no previous file with comments | « src/ppc/full-codegen-ppc.cc ('k') | src/preparser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 kAllowEvalOrArguments, 154 kAllowEvalOrArguments,
155 kDontAllowEvalOrArguments 155 kDontAllowEvalOrArguments
156 }; 156 };
157 157
158 enum Mode { 158 enum Mode {
159 PARSE_LAZILY, 159 PARSE_LAZILY,
160 PARSE_EAGERLY 160 PARSE_EAGERLY
161 }; 161 };
162 162
163 class Checkpoint; 163 class Checkpoint;
164 class ObjectLiteralChecker; 164 class ObjectLiteralCheckerBase;
165 165
166 // --------------------------------------------------------------------------- 166 // ---------------------------------------------------------------------------
167 // FunctionState and BlockState together implement the parser's scope stack. 167 // FunctionState and BlockState together implement the parser's scope stack.
168 // The parser's current scope is in scope_. BlockState and FunctionState 168 // The parser's current scope is in scope_. BlockState and FunctionState
169 // constructors push on the scope stack and the destructors pop. They are also 169 // constructors push on the scope stack and the destructors pop. They are also
170 // used to hold the parser's per-function and per-block state. 170 // used to hold the parser's per-function and per-block state.
171 class BlockState BASE_EMBEDDED { 171 class BlockState BASE_EMBEDDED {
172 public: 172 public:
173 BlockState(typename Traits::Type::Scope** scope_stack, 173 BlockState(typename Traits::Type::Scope** scope_stack,
174 typename Traits::Type::Scope* scope) 174 typename Traits::Type::Scope* scope)
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 505
506 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); 506 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok);
507 507
508 ExpressionT ParsePrimaryExpression(bool* ok); 508 ExpressionT ParsePrimaryExpression(bool* ok);
509 ExpressionT ParseExpression(bool accept_IN, bool* ok); 509 ExpressionT ParseExpression(bool accept_IN, bool* ok);
510 ExpressionT ParseArrayLiteral(bool* ok); 510 ExpressionT ParseArrayLiteral(bool* ok);
511 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, 511 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
512 bool* is_static, bool* is_computed_name, 512 bool* is_static, bool* is_computed_name,
513 bool* ok); 513 bool* ok);
514 ExpressionT ParseObjectLiteral(bool* ok); 514 ExpressionT ParseObjectLiteral(bool* ok);
515 ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker, 515 ObjectLiteralPropertyT ParsePropertyDefinition(
516 bool in_class, bool is_static, 516 ObjectLiteralCheckerBase* checker, bool in_class, bool is_static,
517 bool* is_computed_name, 517 bool* is_computed_name, bool* has_seen_constructor, bool* ok);
518 bool* has_seen_constructor,
519 bool* ok);
520 typename Traits::Type::ExpressionList ParseArguments(bool* ok); 518 typename Traits::Type::ExpressionList ParseArguments(bool* ok);
521 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); 519 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok);
522 ExpressionT ParseYieldExpression(bool* ok); 520 ExpressionT ParseYieldExpression(bool* ok);
523 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); 521 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
524 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); 522 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
525 ExpressionT ParseUnaryExpression(bool* ok); 523 ExpressionT ParseUnaryExpression(bool* ok);
526 ExpressionT ParsePostfixExpression(bool* ok); 524 ExpressionT ParsePostfixExpression(bool* ok);
527 ExpressionT ParseLeftHandSideExpression(bool* ok); 525 ExpressionT ParseLeftHandSideExpression(bool* ok);
528 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); 526 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok);
529 ExpressionT ParseMemberExpression(bool* ok); 527 ExpressionT ParseMemberExpression(bool* ok);
530 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, 528 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
531 bool* ok); 529 bool* ok);
532 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, 530 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast,
533 bool* ok); 531 bool* ok);
534 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); 532 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
535 void AddTemplateExpression(ExpressionT); 533 void AddTemplateExpression(ExpressionT);
536 534
537 // Checks if the expression is a valid reference expression (e.g., on the 535 // Checks if the expression is a valid reference expression (e.g., on the
538 // left-hand side of assignments). Although ruled out by ECMA as early errors, 536 // left-hand side of assignments). Although ruled out by ECMA as early errors,
539 // we allow calls for web compatibility and rewrite them to a runtime throw. 537 // we allow calls for web compatibility and rewrite them to a runtime throw.
540 ExpressionT CheckAndRewriteReferenceExpression( 538 ExpressionT CheckAndRewriteReferenceExpression(
541 ExpressionT expression, 539 ExpressionT expression,
542 Scanner::Location location, const char* message, bool* ok); 540 Scanner::Location location, const char* message, bool* ok);
543 541
544 // Used to detect duplicates in object literals. Each of the values 542 // Used to validate property names in object literals and class literals
545 // kGetterProperty, kSetterProperty and kValueProperty represents
546 // a type of object literal property. When parsing a property, its
547 // type value is stored in the DuplicateFinder for the property name.
548 // Values are chosen so that having intersection bits means the there is
549 // an incompatibility.
550 // I.e., you can add a getter to a property that already has a setter, since
551 // kGetterProperty and kSetterProperty doesn't intersect, but not if it
552 // already has a getter or a value. Adding the getter to an existing
553 // setter will store the value (kGetterProperty | kSetterProperty), which
554 // is incompatible with adding any further properties.
555 enum PropertyKind { 543 enum PropertyKind {
556 kNone = 0, 544 kAccessorProperty = 1,
557 // Bit patterns representing different object literal property types. 545 kValueProperty = 2,
558 kGetterProperty = 1, 546 kMethodProperty = 3
adamk 2015/01/27 20:05:48 Given that these are no longer bit patterns, you s
arv (Not doing code reviews) 2015/01/28 02:37:15 Done.
559 kSetterProperty = 2,
560 kValueProperty = 7,
561 // Helper constants.
562 kValueFlag = 4
563 }; 547 };
564 548
565 // Validation per ECMA 262 - 11.1.5 "Object Initializer". 549 class ObjectLiteralCheckerBase {
566 class ObjectLiteralChecker {
567 public: 550 public:
568 ObjectLiteralChecker(ParserBase* parser, StrictMode strict_mode) 551 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {}
569 : parser_(parser),
570 finder_(scanner()->unicode_cache()),
571 strict_mode_(strict_mode) {}
572 552
573 void CheckProperty(Token::Value property, PropertyKind type, bool* ok); 553 virtual void CheckProperty(Token::Value property, PropertyKind type,
554 bool is_static, bool is_generator, bool* ok) = 0;
574 555
575 private: 556 protected:
576 ParserBase* parser() const { return parser_; } 557 ParserBase* parser() const { return parser_; }
577 Scanner* scanner() const { return parser_->scanner(); } 558 Scanner* scanner() const { return parser_->scanner(); }
578 559
579 // Checks the type of conflict based on values coming from PropertyType. 560 private:
580 bool HasConflict(PropertyKind type1, PropertyKind type2) { 561 ParserBase* parser_;
581 return (type1 & type2) != 0; 562 };
563
564 // Validation per ES6 object literals.
565 class ObjectLiteralChecker : public ObjectLiteralCheckerBase {
566 public:
567 explicit ObjectLiteralChecker(ParserBase* parser)
568 : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {}
569
570 void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
571 bool is_generator, bool* ok) OVERRIDE;
572
573 private:
574 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); }
575
576 bool has_seen_proto_;
577 };
578
579 // Validation per ES6 class literals.
580 class ClassLiteralChecker : public ObjectLiteralCheckerBase {
581 public:
582 explicit ClassLiteralChecker(ParserBase* parser)
583 : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {}
584
585 void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
586 bool is_generator, bool* ok) OVERRIDE;
587
588 private:
589 bool IsConstructor() {
590 return this->scanner()->LiteralMatches("constructor", 11);
582 } 591 }
583 bool IsDataDataConflict(PropertyKind type1, PropertyKind type2) { 592 bool IsPrototype() {
584 return ((type1 & type2) & kValueFlag) != 0; 593 return this->scanner()->LiteralMatches("prototype", 9);
585 }
586 bool IsDataAccessorConflict(PropertyKind type1, PropertyKind type2) {
587 return ((type1 ^ type2) & kValueFlag) != 0;
588 }
589 bool IsAccessorAccessorConflict(PropertyKind type1, PropertyKind type2) {
590 return ((type1 | type2) & kValueFlag) == 0;
591 } 594 }
592 595
593 ParserBase* parser_; 596 bool has_seen_constructor_;
594 DuplicateFinder finder_;
595 StrictMode strict_mode_;
596 }; 597 };
597 598
599
598 // If true, the next (and immediately following) function literal is 600 // If true, the next (and immediately following) function literal is
599 // preceded by a parenthesis. 601 // preceded by a parenthesis.
600 // Heuristically that means that the function will be called immediately, 602 // Heuristically that means that the function will be called immediately,
601 // so never lazily compile it. 603 // so never lazily compile it.
602 bool parenthesized_function_; 604 bool parenthesized_function_;
603 605
604 typename Traits::Type::Scope* scope_; // Scope stack. 606 typename Traits::Type::Scope* scope_; // Scope stack.
605 FunctionState* function_state_; // Function state stack. 607 FunctionState* function_state_; // Function state stack.
606 v8::Extension* extension_; 608 v8::Extension* extension_;
607 FuncNameInferrer* fni_; 609 FuncNameInferrer* fni_;
(...skipping 1455 matching lines...) Expand 10 before | Expand all | Expand 10 after
2063 2065
2064 uint32_t index; 2066 uint32_t index;
2065 return this->IsArrayIndex(*name, &index) 2067 return this->IsArrayIndex(*name, &index)
2066 ? factory()->NewNumberLiteral(index, pos) 2068 ? factory()->NewNumberLiteral(index, pos)
2067 : factory()->NewStringLiteral(*name, pos); 2069 : factory()->NewStringLiteral(*name, pos);
2068 } 2070 }
2069 2071
2070 2072
2071 template <class Traits> 2073 template <class Traits>
2072 typename ParserBase<Traits>::ObjectLiteralPropertyT 2074 typename ParserBase<Traits>::ObjectLiteralPropertyT
2073 ParserBase<Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker, 2075 ParserBase<Traits>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker,
2074 bool in_class, bool is_static, 2076 bool in_class, bool is_static,
2075 bool* is_computed_name, 2077 bool* is_computed_name,
2076 bool* has_seen_constructor, 2078 bool* has_seen_constructor,
2077 bool* ok) { 2079 bool* ok) {
2078 DCHECK(!in_class || is_static || has_seen_constructor != NULL); 2080 DCHECK(!in_class || is_static || has_seen_constructor != nullptr);
2079 ExpressionT value = this->EmptyExpression(); 2081 ExpressionT value = this->EmptyExpression();
2080 IdentifierT name = this->EmptyIdentifier(); 2082 IdentifierT name = this->EmptyIdentifier();
2081 bool is_get = false; 2083 bool is_get = false;
2082 bool is_set = false; 2084 bool is_set = false;
2083 bool name_is_static = false; 2085 bool name_is_static = false;
2084 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); 2086 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL);
2085 2087
2086 Token::Value name_token = peek(); 2088 Token::Value name_token = peek();
2087 int next_pos = peek_position(); 2089 int next_pos = peek_position();
2088 ExpressionT name_expression = ParsePropertyName( 2090 ExpressionT name_expression = ParsePropertyName(
2089 &name, &is_get, &is_set, &name_is_static, is_computed_name, 2091 &name, &is_get, &is_set, &name_is_static, is_computed_name,
2090 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2092 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2091 2093
2092 if (fni_ != NULL && !*is_computed_name) { 2094 if (fni_ != nullptr && !*is_computed_name) {
2093 this->PushLiteralName(fni_, name); 2095 this->PushLiteralName(fni_, name);
2094 } 2096 }
2095 2097
2096 if (!in_class && !is_generator && peek() == Token::COLON) { 2098 if (!in_class && !is_generator && peek() == Token::COLON) {
2097 // PropertyDefinition : PropertyName ':' AssignmentExpression 2099 // PropertyDefinition : PropertyName ':' AssignmentExpression
2098 if (!*is_computed_name && checker != NULL) { 2100 if (!*is_computed_name) {
2099 checker->CheckProperty(name_token, kValueProperty, 2101 checker->CheckProperty(name_token, kValueProperty, is_static,
2102 is_generator,
2100 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2103 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2101 } 2104 }
2102 Consume(Token::COLON); 2105 Consume(Token::COLON);
2103 value = this->ParseAssignmentExpression( 2106 value = this->ParseAssignmentExpression(
2104 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2107 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2105 2108
2106 } else if (is_generator || 2109 } else if (is_generator ||
2107 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { 2110 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) {
2108 // Concise Method 2111 // Concise Method
2109 2112 if (!*is_computed_name) {
2110 if (is_static && this->IsPrototype(name)) { 2113 checker->CheckProperty(name_token, kMethodProperty, is_static,
2111 ReportMessageAt(scanner()->location(), "static_prototype"); 2114 is_generator,
2112 *ok = false; 2115 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2113 return this->EmptyObjectLiteralProperty();
2114 } 2116 }
2115 2117
2116 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod 2118 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod
2117 : FunctionKind::kConciseMethod; 2119 : FunctionKind::kConciseMethod;
2118 2120
2119 if (in_class && !is_static && this->IsConstructor(name)) { 2121 if (in_class && !is_static && this->IsConstructor(name)) {
2120 if (is_generator) {
2121 ReportMessageAt(scanner()->location(), "constructor_special_method");
2122 *ok = false;
2123 return this->EmptyObjectLiteralProperty();
2124 }
2125
2126 if (*has_seen_constructor) {
2127 ReportMessageAt(scanner()->location(), "duplicate_constructor");
2128 *ok = false;
2129 return this->EmptyObjectLiteralProperty();
2130 }
2131
2132 *has_seen_constructor = true; 2122 *has_seen_constructor = true;
2133 kind = FunctionKind::kNormalFunction; 2123 kind = FunctionKind::kNormalFunction;
2134 } 2124 }
2135 2125
2136 if (!*is_computed_name && checker != NULL) {
2137 checker->CheckProperty(name_token, kValueProperty,
2138 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2139 }
2140
2141 value = this->ParseFunctionLiteral( 2126 value = this->ParseFunctionLiteral(
2142 name, scanner()->location(), 2127 name, scanner()->location(),
2143 false, // reserved words are allowed here 2128 false, // reserved words are allowed here
2144 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, 2129 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
2145 FunctionLiteral::NORMAL_ARITY, 2130 FunctionLiteral::NORMAL_ARITY,
2146 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2131 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2147 2132
2148 return factory()->NewObjectLiteralProperty(name_expression, value, 2133 return factory()->NewObjectLiteralProperty(name_expression, value,
2149 ObjectLiteralProperty::COMPUTED, 2134 ObjectLiteralProperty::COMPUTED,
2150 is_static, *is_computed_name); 2135 is_static, *is_computed_name);
2151 2136
2152 } else if (in_class && name_is_static && !is_static) { 2137 } else if (in_class && name_is_static && !is_static) {
2153 // static MethodDefinition 2138 // static MethodDefinition
2154 return ParsePropertyDefinition(checker, true, true, is_computed_name, NULL, 2139 return ParsePropertyDefinition(checker, true, true, is_computed_name,
2155 ok); 2140 nullptr, ok);
2156 2141
2157 } else if (is_get || is_set) { 2142 } else if (is_get || is_set) {
2158 // Accessor 2143 // Accessor
2159 name = this->EmptyIdentifier(); 2144 name = this->EmptyIdentifier();
2160 bool dont_care = false; 2145 bool dont_care = false;
2161 name_token = peek(); 2146 name_token = peek();
2162 2147
2163 name_expression = ParsePropertyName( 2148 name_expression = ParsePropertyName(
2164 &name, &dont_care, &dont_care, &dont_care, is_computed_name, 2149 &name, &dont_care, &dont_care, &dont_care, is_computed_name,
2165 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2150 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2166 2151
2167 // Validate the property. 2152 if (!*is_computed_name) {
2168 if (is_static && this->IsPrototype(name)) { 2153 checker->CheckProperty(name_token, kAccessorProperty, is_static,
2169 ReportMessageAt(scanner()->location(), "static_prototype"); 2154 is_generator,
2170 *ok = false;
2171 return this->EmptyObjectLiteralProperty();
2172 } else if (in_class && !is_static && this->IsConstructor(name)) {
2173 ReportMessageAt(scanner()->location(), "constructor_special_method");
2174 *ok = false;
2175 return this->EmptyObjectLiteralProperty();
2176 }
2177 if (!*is_computed_name && checker != NULL) {
2178 checker->CheckProperty(name_token,
2179 is_get ? kGetterProperty : kSetterProperty,
2180 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2155 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2181 } 2156 }
2182 2157
2183 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( 2158 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
2184 name, scanner()->location(), 2159 name, scanner()->location(),
2185 false, // reserved words are allowed here 2160 false, // reserved words are allowed here
2186 FunctionKind::kNormalFunction, RelocInfo::kNoPosition, 2161 FunctionKind::kNormalFunction, RelocInfo::kNoPosition,
2187 FunctionLiteral::ANONYMOUS_EXPRESSION, 2162 FunctionLiteral::ANONYMOUS_EXPRESSION,
2188 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, 2163 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY,
2189 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2164 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2227 bool* ok) { 2202 bool* ok) {
2228 // ObjectLiteral :: 2203 // ObjectLiteral ::
2229 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' 2204 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
2230 2205
2231 int pos = peek_position(); 2206 int pos = peek_position();
2232 typename Traits::Type::PropertyList properties = 2207 typename Traits::Type::PropertyList properties =
2233 this->NewPropertyList(4, zone_); 2208 this->NewPropertyList(4, zone_);
2234 int number_of_boilerplate_properties = 0; 2209 int number_of_boilerplate_properties = 0;
2235 bool has_function = false; 2210 bool has_function = false;
2236 bool has_computed_names = false; 2211 bool has_computed_names = false;
2237 2212 ObjectLiteralChecker checker(this);
2238 ObjectLiteralChecker checker(this, strict_mode());
2239 2213
2240 Expect(Token::LBRACE, CHECK_OK); 2214 Expect(Token::LBRACE, CHECK_OK);
2241 2215
2242 while (peek() != Token::RBRACE) { 2216 while (peek() != Token::RBRACE) {
2243 if (fni_ != NULL) fni_->Enter(); 2217 if (fni_ != nullptr) fni_->Enter();
2244 2218
2245 const bool in_class = false; 2219 const bool in_class = false;
2246 const bool is_static = false; 2220 const bool is_static = false;
2247 bool is_computed_name = false; 2221 bool is_computed_name = false;
2248 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( 2222 ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
2249 &checker, in_class, is_static, &is_computed_name, NULL, CHECK_OK); 2223 &checker, in_class, is_static, &is_computed_name, nullptr, CHECK_OK);
2250 2224
2251 if (is_computed_name) { 2225 if (is_computed_name) {
2252 has_computed_names = true; 2226 has_computed_names = true;
2253 } 2227 }
2254 2228
2255 // Mark top-level object literals that contain function literals and 2229 // Mark top-level object literals that contain function literals and
2256 // pretenure the literal so it can be added as a constant function 2230 // pretenure the literal so it can be added as a constant function
2257 // property. (Parser only.) 2231 // property. (Parser only.)
2258 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, 2232 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property,
2259 &has_function); 2233 &has_function);
2260 2234
2261 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. 2235 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
2262 if (!has_computed_names && this->IsBoilerplateProperty(property)) { 2236 if (!has_computed_names && this->IsBoilerplateProperty(property)) {
2263 number_of_boilerplate_properties++; 2237 number_of_boilerplate_properties++;
2264 } 2238 }
2265 properties->Add(property, zone()); 2239 properties->Add(property, zone());
2266 2240
2267 if (peek() != Token::RBRACE) { 2241 if (peek() != Token::RBRACE) {
2268 // Need {} because of the CHECK_OK macro. 2242 // Need {} because of the CHECK_OK macro.
2269 Expect(Token::COMMA, CHECK_OK); 2243 Expect(Token::COMMA, CHECK_OK);
2270 } 2244 }
2271 2245
2272 if (fni_ != NULL) { 2246 if (fni_ != nullptr) {
2273 fni_->Infer(); 2247 fni_->Infer();
2274 fni_->Leave(); 2248 fni_->Leave();
2275 } 2249 }
2276 } 2250 }
2277 Expect(Token::RBRACE, CHECK_OK); 2251 Expect(Token::RBRACE, CHECK_OK);
2278 2252
2279 // Computation of literal_index must happen before pre parse bailout. 2253 // Computation of literal_index must happen before pre parse bailout.
2280 int literal_index = function_state_->NextMaterializedLiteralIndex(); 2254 int literal_index = function_state_->NextMaterializedLiteralIndex();
2281 2255
2282 return factory()->NewObjectLiteral(properties, 2256 return factory()->NewObjectLiteral(properties,
(...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after
3034 } 3008 }
3035 } 3009 }
3036 3010
3037 3011
3038 #undef CHECK_OK 3012 #undef CHECK_OK
3039 #undef CHECK_OK_CUSTOM 3013 #undef CHECK_OK_CUSTOM
3040 3014
3041 3015
3042 template <typename Traits> 3016 template <typename Traits>
3043 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( 3017 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
3044 Token::Value property, PropertyKind type, bool* ok) { 3018 Token::Value property, PropertyKind type, bool is_static, bool is_generator,
3045 int old; 3019 bool* ok) {
3046 if (property == Token::NUMBER) { 3020 DCHECK(!is_static);
3047 old = scanner()->FindNumber(&finder_, type); 3021 DCHECK(!is_generator || type == kMethodProperty);
3048 } else { 3022
3049 old = scanner()->FindSymbol(&finder_, type); 3023 if (property == Token::NUMBER) return;
3024
3025 if (type == kValueProperty && IsProto()) {
3026 if (has_seen_proto_) {
3027 this->parser()->ReportMessage("duplicate_proto");
3028 *ok = false;
3029 return;
3030 }
3031 has_seen_proto_ = true;
3032 return;
3050 } 3033 }
3051 PropertyKind old_type = static_cast<PropertyKind>(old); 3034 }
3052 if (HasConflict(old_type, type)) { 3035
3053 if (IsDataDataConflict(old_type, type)) { 3036
3054 // Both are data properties. 3037 template <typename Traits>
3055 if (strict_mode_ == SLOPPY) return; 3038 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty(
3056 parser()->ReportMessage("strict_duplicate_property"); 3039 Token::Value property, PropertyKind type, bool is_static, bool is_generator,
adamk 2015/01/27 20:05:48 If this message is now unused, you ought to be abl
arv (Not doing code reviews) 2015/01/28 02:37:15 Done.
3057 } else if (IsDataAccessorConflict(old_type, type)) { 3040 bool* ok) {
3058 // Both a data and an accessor property with the same name. 3041 DCHECK(type == kMethodProperty);
3059 parser()->ReportMessage("accessor_data_property"); 3042
3060 } else { 3043 if (property == Token::NUMBER) return;
3061 DCHECK(IsAccessorAccessorConflict(old_type, type)); 3044
3062 // Both accessors of the same type. 3045 if (is_static) {
3063 parser()->ReportMessage("accessor_get_set"); 3046 if (IsPrototype()) {
3047 this->parser()->ReportMessage("static_prototype");
3048 *ok = false;
3049 return;
3064 } 3050 }
3065 *ok = false; 3051 } else if (IsConstructor()) {
3052 if (is_generator || type == kAccessorProperty) {
3053 this->parser()->ReportMessage("constructor_special_method");
3054 *ok = false;
3055 return;
3056 }
3057 if (has_seen_constructor_) {
3058 this->parser()->ReportMessage("duplicate_constructor");
3059 *ok = false;
3060 return;
3061 }
3062 has_seen_constructor_ = true;
3063 return;
3066 } 3064 }
3067 } 3065 }
3068 } } // v8::internal 3066 } } // v8::internal
3069 3067
3070 #endif // V8_PREPARSER_H 3068 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « 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