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

Side by Side Diff: src/preparser.h

Issue 352173004: Relax object literal checking to follow ES6 (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « src/ast.cc ('k') | src/x64/full-codegen-x64.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/func-name-inferrer.h" 10 #include "src/func-name-inferrer.h"
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 enum PropertyKind { 464 enum PropertyKind {
465 kNone = 0, 465 kNone = 0,
466 // Bit patterns representing different object literal property types. 466 // Bit patterns representing different object literal property types.
467 kGetterProperty = 1, 467 kGetterProperty = 1,
468 kSetterProperty = 2, 468 kSetterProperty = 2,
469 kValueProperty = 7, 469 kValueProperty = 7,
470 // Helper constants. 470 // Helper constants.
471 kValueFlag = 4 471 kValueFlag = 4
472 }; 472 };
473 473
474 // Validation per ECMA 262 - 11.1.5 "Object Initialiser".
475 class ObjectLiteralChecker {
476 public:
477 ObjectLiteralChecker(ParserBase* parser, StrictMode strict_mode)
478 : parser_(parser),
479 finder_(scanner()->unicode_cache()),
480 strict_mode_(strict_mode) { }
481
482 void CheckProperty(Token::Value property, PropertyKind type, bool* ok);
483
484 private:
485 ParserBase* parser() const { return parser_; }
486 Scanner* scanner() const { return parser_->scanner(); }
487
488 // Checks the type of conflict based on values coming from PropertyType.
489 bool HasConflict(PropertyKind type1, PropertyKind type2) {
490 return (type1 & type2) != 0;
491 }
492 bool IsDataDataConflict(PropertyKind type1, PropertyKind type2) {
493 return ((type1 & type2) & kValueFlag) != 0;
494 }
495 bool IsDataAccessorConflict(PropertyKind type1, PropertyKind type2) {
496 return ((type1 ^ type2) & kValueFlag) != 0;
497 }
498 bool IsAccessorAccessorConflict(PropertyKind type1, PropertyKind type2) {
499 return ((type1 | type2) & kValueFlag) == 0;
500 }
501
502 ParserBase* parser_;
503 DuplicateFinder finder_;
504 StrictMode strict_mode_;
505 };
506
507 // If true, the next (and immediately following) function literal is 474 // If true, the next (and immediately following) function literal is
508 // preceded by a parenthesis. 475 // preceded by a parenthesis.
509 // Heuristically that means that the function will be called immediately, 476 // Heuristically that means that the function will be called immediately,
510 // so never lazily compile it. 477 // so never lazily compile it.
511 bool parenthesized_function_; 478 bool parenthesized_function_;
512 479
513 typename Traits::Type::Scope* scope_; // Scope stack. 480 typename Traits::Type::Scope* scope_; // Scope stack.
514 FunctionState* function_state_; // Function state stack. 481 FunctionState* function_state_; // Function state stack.
515 v8::Extension* extension_; 482 v8::Extension* extension_;
516 FuncNameInferrer* fni_; 483 FuncNameInferrer* fni_;
(...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after
1544 // (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 1511 // (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
1545 // ) ',')* '}' 1512 // ) ',')* '}'
1546 // (Except that the trailing comma is not required.) 1513 // (Except that the trailing comma is not required.)
1547 1514
1548 int pos = peek_position(); 1515 int pos = peek_position();
1549 typename Traits::Type::PropertyList properties = 1516 typename Traits::Type::PropertyList properties =
1550 this->NewPropertyList(4, zone_); 1517 this->NewPropertyList(4, zone_);
1551 int number_of_boilerplate_properties = 0; 1518 int number_of_boilerplate_properties = 0;
1552 bool has_function = false; 1519 bool has_function = false;
1553 1520
1554 ObjectLiteralChecker checker(this, strict_mode());
1555
1556 Expect(Token::LBRACE, CHECK_OK); 1521 Expect(Token::LBRACE, CHECK_OK);
1557 1522
1558 while (peek() != Token::RBRACE) { 1523 while (peek() != Token::RBRACE) {
1559 if (fni_ != NULL) fni_->Enter(); 1524 if (fni_ != NULL) fni_->Enter();
1560 1525
1561 typename Traits::Type::Literal key = this->EmptyLiteral(); 1526 typename Traits::Type::Literal key = this->EmptyLiteral();
1562 Token::Value next = peek(); 1527 Token::Value next = peek();
1563 int next_pos = peek_position(); 1528 int next_pos = peek_position();
1564 1529
1565 switch (next) { 1530 switch (next) {
(...skipping 14 matching lines...) Expand all
1580 if (next != i::Token::IDENTIFIER && 1545 if (next != i::Token::IDENTIFIER &&
1581 next != i::Token::FUTURE_RESERVED_WORD && 1546 next != i::Token::FUTURE_RESERVED_WORD &&
1582 next != i::Token::FUTURE_STRICT_RESERVED_WORD && 1547 next != i::Token::FUTURE_STRICT_RESERVED_WORD &&
1583 next != i::Token::NUMBER && 1548 next != i::Token::NUMBER &&
1584 next != i::Token::STRING && 1549 next != i::Token::STRING &&
1585 !Token::IsKeyword(next)) { 1550 !Token::IsKeyword(next)) {
1586 ReportUnexpectedToken(next); 1551 ReportUnexpectedToken(next);
1587 *ok = false; 1552 *ok = false;
1588 return this->EmptyLiteral(); 1553 return this->EmptyLiteral();
1589 } 1554 }
1590 // Validate the property.
1591 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
1592 checker.CheckProperty(next, type, CHECK_OK);
1593 IdentifierT name = this->GetSymbol(scanner_); 1555 IdentifierT name = this->GetSymbol(scanner_);
1594 typename Traits::Type::FunctionLiteral value = 1556 typename Traits::Type::FunctionLiteral value =
1595 this->ParseFunctionLiteral( 1557 this->ParseFunctionLiteral(
1596 name, scanner()->location(), 1558 name, scanner()->location(),
1597 false, // reserved words are allowed here 1559 false, // reserved words are allowed here
1598 false, // not a generator 1560 false, // not a generator
1599 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, 1561 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
1600 is_getter ? FunctionLiteral::GETTER_ARITY 1562 is_getter ? FunctionLiteral::GETTER_ARITY
1601 : FunctionLiteral::SETTER_ARITY, 1563 : FunctionLiteral::SETTER_ARITY,
1602 CHECK_OK); 1564 CHECK_OK);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1646 IdentifierT string = this->GetSymbol(scanner_); 1608 IdentifierT string = this->GetSymbol(scanner_);
1647 key = factory()->NewStringLiteral(string, next_pos); 1609 key = factory()->NewStringLiteral(string, next_pos);
1648 } else { 1610 } else {
1649 Token::Value next = Next(); 1611 Token::Value next = Next();
1650 ReportUnexpectedToken(next); 1612 ReportUnexpectedToken(next);
1651 *ok = false; 1613 *ok = false;
1652 return this->EmptyLiteral(); 1614 return this->EmptyLiteral();
1653 } 1615 }
1654 } 1616 }
1655 1617
1656 // Validate the property
1657 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1658
1659 Expect(Token::COLON, CHECK_OK); 1618 Expect(Token::COLON, CHECK_OK);
1660 ExpressionT value = this->ParseAssignmentExpression(true, CHECK_OK); 1619 ExpressionT value = this->ParseAssignmentExpression(true, CHECK_OK);
1661 1620
1662 typename Traits::Type::ObjectLiteralProperty property = 1621 typename Traits::Type::ObjectLiteralProperty property =
1663 factory()->NewObjectLiteralProperty(key, value); 1622 factory()->NewObjectLiteralProperty(key, value);
1664 1623
1665 // Mark top-level object literals that contain function literals and 1624 // Mark top-level object literals that contain function literals and
1666 // pretenure the literal so it can be added as a constant function 1625 // pretenure the literal so it can be added as a constant function
1667 // property. (Parser only.) 1626 // property. (Parser only.)
1668 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, value, 1627 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, value,
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
2173 *ok = false; 2132 *ok = false;
2174 return this->EmptyExpression(); 2133 return this->EmptyExpression();
2175 } 2134 }
2176 } 2135 }
2177 2136
2178 2137
2179 #undef CHECK_OK 2138 #undef CHECK_OK
2180 #undef CHECK_OK_CUSTOM 2139 #undef CHECK_OK_CUSTOM
2181 2140
2182 2141
2183 template <typename Traits>
2184 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
2185 Token::Value property,
2186 PropertyKind type,
2187 bool* ok) {
2188 int old;
2189 if (property == Token::NUMBER) {
2190 old = scanner()->FindNumber(&finder_, type);
2191 } else {
2192 old = scanner()->FindSymbol(&finder_, type);
2193 }
2194 PropertyKind old_type = static_cast<PropertyKind>(old);
2195 if (HasConflict(old_type, type)) {
2196 if (IsDataDataConflict(old_type, type)) {
2197 // Both are data properties.
2198 if (strict_mode_ == SLOPPY) return;
2199 parser()->ReportMessage("strict_duplicate_property");
2200 } else if (IsDataAccessorConflict(old_type, type)) {
2201 // Both a data and an accessor property with the same name.
2202 parser()->ReportMessage("accessor_data_property");
2203 } else {
2204 ASSERT(IsAccessorAccessorConflict(old_type, type));
2205 // Both accessors of the same type.
2206 parser()->ReportMessage("accessor_get_set");
2207 }
2208 *ok = false;
2209 }
2210 }
2211
2212
2213 } } // v8::internal 2142 } } // v8::internal
2214 2143
2215 #endif // V8_PREPARSER_H 2144 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « src/ast.cc ('k') | src/x64/full-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698