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

Side by Side Diff: src/preparser.h

Issue 192993002: Move ParseObjectLiteral to ParserBase. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebased on top of rossberg@s changes Created 6 years, 9 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/parser.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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 10 matching lines...) Expand all
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #ifndef V8_PREPARSER_H 28 #ifndef V8_PREPARSER_H
29 #define V8_PREPARSER_H 29 #define V8_PREPARSER_H
30 30
31 #include "func-name-inferrer.h"
31 #include "hashmap.h" 32 #include "hashmap.h"
32 #include "scopes.h" 33 #include "scopes.h"
33 #include "token.h" 34 #include "token.h"
34 #include "scanner.h" 35 #include "scanner.h"
35 #include "v8.h" 36 #include "v8.h"
36 37
37 namespace v8 { 38 namespace v8 {
38 namespace internal { 39 namespace internal {
39 40
40 // Common base class shared between parser and pre-parser. 41 // Common base class shared between parser and pre-parser.
41 template <typename Traits> 42 template <typename Traits>
42 class ParserBase : public Traits { 43 class ParserBase : public Traits {
43 public: 44 public:
44 ParserBase(Scanner* scanner, uintptr_t stack_limit, 45 ParserBase(Scanner* scanner, uintptr_t stack_limit,
45 v8::Extension* extension, 46 v8::Extension* extension,
46 typename Traits::Type::Zone* zone, 47 typename Traits::Type::Zone* zone,
47 typename Traits::Type::Parser this_object) 48 typename Traits::Type::Parser this_object)
48 : Traits(this_object), 49 : Traits(this_object),
49 parenthesized_function_(false), 50 parenthesized_function_(false),
50 scope_(NULL), 51 scope_(NULL),
51 function_state_(NULL), 52 function_state_(NULL),
52 extension_(extension), 53 extension_(extension),
54 fni_(NULL),
53 scanner_(scanner), 55 scanner_(scanner),
54 stack_limit_(stack_limit), 56 stack_limit_(stack_limit),
55 stack_overflow_(false), 57 stack_overflow_(false),
56 allow_lazy_(false), 58 allow_lazy_(false),
57 allow_natives_syntax_(false), 59 allow_natives_syntax_(false),
58 allow_generators_(false), 60 allow_generators_(false),
59 allow_for_of_(false), 61 allow_for_of_(false),
60 zone_(zone) { } 62 zone_(zone) { }
61 63
62 // Getters that indicate whether certain syntactical constructs are 64 // Getters that indicate whether certain syntactical constructs are
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 AllowEvalOrArgumentsAsIdentifier, 325 AllowEvalOrArgumentsAsIdentifier,
324 bool* ok); 326 bool* ok);
325 // Parses an identifier or a strict mode future reserved word, and indicate 327 // Parses an identifier or a strict mode future reserved word, and indicate
326 // whether it is strict mode future reserved. 328 // whether it is strict mode future reserved.
327 typename Traits::Type::Identifier ParseIdentifierOrStrictReservedWord( 329 typename Traits::Type::Identifier ParseIdentifierOrStrictReservedWord(
328 bool* is_strict_reserved, 330 bool* is_strict_reserved,
329 bool* ok); 331 bool* ok);
330 typename Traits::Type::Identifier ParseIdentifierName(bool* ok); 332 typename Traits::Type::Identifier ParseIdentifierName(bool* ok);
331 // Parses an identifier and determines whether or not it is 'get' or 'set'. 333 // Parses an identifier and determines whether or not it is 'get' or 'set'.
332 typename Traits::Type::Identifier ParseIdentifierNameOrGetOrSet(bool* is_get, 334 typename Traits::Type::Identifier ParseIdentifierNameOrGetOrSet(bool* is_get,
333 bool* is_set, 335 bool* is_set,
334 bool* ok); 336 bool* ok);
335 337
336 typename Traits::Type::Expression ParseRegExpLiteral(bool seen_equal, 338 typename Traits::Type::Expression ParseRegExpLiteral(bool seen_equal,
337 bool* ok); 339 bool* ok);
338 340
339 typename Traits::Type::Expression ParsePrimaryExpression(bool* ok); 341 typename Traits::Type::Expression ParsePrimaryExpression(bool* ok);
340 typename Traits::Type::Expression ParseExpression(bool accept_IN, bool* ok); 342 typename Traits::Type::Expression ParseExpression(bool accept_IN, bool* ok);
341 typename Traits::Type::Expression ParseArrayLiteral(bool* ok); 343 typename Traits::Type::Expression ParseArrayLiteral(bool* ok);
344 typename Traits::Type::Expression ParseObjectLiteral(bool* ok);
342 345
343 // Used to detect duplicates in object literals. Each of the values 346 // Used to detect duplicates in object literals. Each of the values
344 // kGetterProperty, kSetterProperty and kValueProperty represents 347 // kGetterProperty, kSetterProperty and kValueProperty represents
345 // a type of object literal property. When parsing a property, its 348 // a type of object literal property. When parsing a property, its
346 // type value is stored in the DuplicateFinder for the property name. 349 // type value is stored in the DuplicateFinder for the property name.
347 // Values are chosen so that having intersection bits means the there is 350 // Values are chosen so that having intersection bits means the there is
348 // an incompatibility. 351 // an incompatibility.
349 // I.e., you can add a getter to a property that already has a setter, since 352 // I.e., you can add a getter to a property that already has a setter, since
350 // kGetterProperty and kSetterProperty doesn't intersect, but not if it 353 // kGetterProperty and kSetterProperty doesn't intersect, but not if it
351 // already has a getter or a value. Adding the getter to an existing 354 // already has a getter or a value. Adding the getter to an existing
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 399
397 // If true, the next (and immediately following) function literal is 400 // If true, the next (and immediately following) function literal is
398 // preceded by a parenthesis. 401 // preceded by a parenthesis.
399 // Heuristically that means that the function will be called immediately, 402 // Heuristically that means that the function will be called immediately,
400 // so never lazily compile it. 403 // so never lazily compile it.
401 bool parenthesized_function_; 404 bool parenthesized_function_;
402 405
403 typename Traits::Type::Scope* scope_; // Scope stack. 406 typename Traits::Type::Scope* scope_; // Scope stack.
404 FunctionState* function_state_; // Function state stack. 407 FunctionState* function_state_; // Function state stack.
405 v8::Extension* extension_; 408 v8::Extension* extension_;
409 FuncNameInferrer* fni_;
406 410
407 private: 411 private:
408 Scanner* scanner_; 412 Scanner* scanner_;
409 uintptr_t stack_limit_; 413 uintptr_t stack_limit_;
410 bool stack_overflow_; 414 bool stack_overflow_;
411 415
412 bool allow_lazy_; 416 bool allow_lazy_;
413 bool allow_natives_syntax_; 417 bool allow_natives_syntax_;
414 bool allow_generators_; 418 bool allow_generators_;
415 bool allow_for_of_; 419 bool allow_for_of_;
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 PreParserExpression NewBinaryOperation(Token::Value op, 603 PreParserExpression NewBinaryOperation(Token::Value op,
600 PreParserExpression left, 604 PreParserExpression left,
601 PreParserExpression right, int pos) { 605 PreParserExpression right, int pos) {
602 return PreParserExpression::Default(); 606 return PreParserExpression::Default();
603 } 607 }
604 PreParserExpression NewArrayLiteral(PreParserExpressionList values, 608 PreParserExpression NewArrayLiteral(PreParserExpressionList values,
605 int literal_index, 609 int literal_index,
606 int pos) { 610 int pos) {
607 return PreParserExpression::Default(); 611 return PreParserExpression::Default();
608 } 612 }
613
614 PreParserExpression NewObjectLiteralProperty(bool is_getter,
615 PreParserExpression value,
616 int pos) {
617 return PreParserExpression::Default();
618 }
619
620 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
621 PreParserExpression value) {
622 return PreParserExpression::Default();
623 }
624
625 PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
626 int literal_index,
627 int boilerplate_properties,
628 bool has_function,
629 int pos) {
630 return PreParserExpression::Default();
631 }
632
633 PreParserExpression NewLiteral(PreParserIdentifier identifier,
634 int pos) {
635 return PreParserExpression::Default();
636 }
637
638 PreParserExpression NewNumberLiteral(double number,
639 int pos) {
640 return PreParserExpression::Default();
641 }
609 }; 642 };
610 643
611 644
612 class PreParser; 645 class PreParser;
613 646
614 class PreParserTraits { 647 class PreParserTraits {
615 public: 648 public:
616 struct Type { 649 struct Type {
617 typedef PreParser* Parser; 650 typedef PreParser* Parser;
618 651
619 // Types used by FunctionState and BlockState. 652 // Types used by FunctionState and BlockState.
620 typedef PreParserScope Scope; 653 typedef PreParserScope Scope;
621 typedef PreParserFactory Factory; 654 typedef PreParserFactory Factory;
622 // PreParser doesn't need to store generator variables. 655 // PreParser doesn't need to store generator variables.
623 typedef void GeneratorVariable; 656 typedef void GeneratorVariable;
624 // No interaction with Zones. 657 // No interaction with Zones.
625 typedef void Zone; 658 typedef void Zone;
626 659
627 // Return types for traversing functions. 660 // Return types for traversing functions.
628 typedef PreParserIdentifier Identifier; 661 typedef PreParserIdentifier Identifier;
629 typedef PreParserExpression Expression; 662 typedef PreParserExpression Expression;
663 typedef PreParserExpression FunctionLiteral;
664 typedef PreParserExpression ObjectLiteralProperty;
665 typedef PreParserExpression Literal;
630 typedef PreParserExpressionList ExpressionList; 666 typedef PreParserExpressionList ExpressionList;
667 typedef PreParserExpressionList PropertyList;
631 }; 668 };
632 669
633 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} 670 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
634 671
635 // Custom operations executed when FunctionStates are created and 672 // Custom operations executed when FunctionStates are created and
636 // destructed. (The PreParser doesn't need to do anything.) 673 // destructed. (The PreParser doesn't need to do anything.)
637 template<typename FunctionState> 674 template<typename FunctionState>
638 static void SetUpFunctionState(FunctionState* function_state, void*) {} 675 static void SetUpFunctionState(FunctionState* function_state, void*) {}
639 template<typename FunctionState> 676 template<typename FunctionState>
640 static void TearDownFunctionState(FunctionState* function_state) {} 677 static void TearDownFunctionState(FunctionState* function_state) {}
641 678
642 // Helper functions for recursive descent. 679 // Helper functions for recursive descent.
643 static bool IsEvalOrArguments(PreParserIdentifier identifier) { 680 static bool IsEvalOrArguments(PreParserIdentifier identifier) {
644 return identifier.IsEvalOrArguments(); 681 return identifier.IsEvalOrArguments();
645 } 682 }
646 683
684 static bool IsBoilerplateProperty(PreParserExpression property) {
685 // PreParser doesn't count boilerplate properties.
686 return false;
687 }
688
689 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
690 return false;
691 }
692
693 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
694 // PreParser should not use FuncNameInferrer.
695 ASSERT(false);
696 }
697
698 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
699 PreParserScope* scope, PreParserExpression value, bool* has_function) {}
700
647 // Reporting errors. 701 // Reporting errors.
648 void ReportMessageAt(Scanner::Location location, 702 void ReportMessageAt(Scanner::Location location,
649 const char* message, 703 const char* message,
650 Vector<const char*> args); 704 Vector<const char*> args);
651 void ReportMessageAt(Scanner::Location location, 705 void ReportMessageAt(Scanner::Location location,
652 const char* type, 706 const char* type,
653 const char* name_opt); 707 const char* name_opt);
654 void ReportMessageAt(int start_pos, 708 void ReportMessageAt(int start_pos,
655 int end_pos, 709 int end_pos,
656 const char* type, 710 const char* type,
657 const char* name_opt); 711 const char* name_opt);
658 712
659 // "null" return type creators. 713 // "null" return type creators.
660 static PreParserIdentifier EmptyIdentifier() { 714 static PreParserIdentifier EmptyIdentifier() {
661 return PreParserIdentifier::Default(); 715 return PreParserIdentifier::Default();
662 } 716 }
663 static PreParserExpression EmptyExpression() { 717 static PreParserExpression EmptyExpression() {
664 return PreParserExpression::Default(); 718 return PreParserExpression::Default();
665 } 719 }
720 static PreParserExpression EmptyLiteral() {
721 return PreParserExpression::Default();
722 }
666 723
667 // Odd-ball literal creators. 724 // Odd-ball literal creators.
668 static PreParserExpression GetLiteralTheHole(int position, 725 static PreParserExpression GetLiteralTheHole(int position,
669 PreParserFactory* factory) { 726 PreParserFactory* factory) {
670 return PreParserExpression::Default(); 727 return PreParserExpression::Default();
671 } 728 }
672 729
673 // Producing data during the recursive descent. 730 // Producing data during the recursive descent.
674 PreParserIdentifier GetSymbol(Scanner* scanner); 731 PreParserIdentifier GetSymbol(Scanner* scanner);
675 static PreParserIdentifier NextLiteralString(Scanner* scanner, 732 static PreParserIdentifier NextLiteralString(Scanner* scanner,
(...skipping 19 matching lines...) Expand all
695 } 752 }
696 753
697 PreParserExpression ExpressionFromString(int pos, 754 PreParserExpression ExpressionFromString(int pos,
698 Scanner* scanner, 755 Scanner* scanner,
699 PreParserFactory* factory = NULL); 756 PreParserFactory* factory = NULL);
700 757
701 static PreParserExpressionList NewExpressionList(int size, void* zone) { 758 static PreParserExpressionList NewExpressionList(int size, void* zone) {
702 return PreParserExpressionList(); 759 return PreParserExpressionList();
703 } 760 }
704 761
762 static PreParserExpressionList NewPropertyList(int size, void* zone) {
763 return PreParserExpressionList();
764 }
765
705 // Temporary glue; these functions will move to ParserBase. 766 // Temporary glue; these functions will move to ParserBase.
706 PreParserExpression ParseAssignmentExpression(bool accept_IN, bool* ok); 767 PreParserExpression ParseAssignmentExpression(bool accept_IN, bool* ok);
707 PreParserExpression ParseObjectLiteral(bool* ok);
708 PreParserExpression ParseV8Intrinsic(bool* ok); 768 PreParserExpression ParseV8Intrinsic(bool* ok);
769 PreParserExpression ParseFunctionLiteral(
770 PreParserIdentifier name,
771 Scanner::Location function_name_location,
772 bool name_is_strict_reserved,
773 bool is_generator,
774 int function_token_position,
775 FunctionLiteral::FunctionType type,
776 bool* ok);
709 777
710 private: 778 private:
711 PreParser* pre_parser_; 779 PreParser* pre_parser_;
712 }; 780 };
713 781
714 782
715 // Preparsing checks a JavaScript program and emits preparse-data that helps 783 // Preparsing checks a JavaScript program and emits preparse-data that helps
716 // a later parsing to be faster. 784 // a later parsing to be faster.
717 // See preparse-data-format.h for the data format. 785 // See preparse-data-format.h for the data format.
718 786
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 } 1291 }
1224 } 1292 }
1225 Expect(Token::RBRACK, CHECK_OK); 1293 Expect(Token::RBRACK, CHECK_OK);
1226 1294
1227 // Update the scope information before the pre-parsing bailout. 1295 // Update the scope information before the pre-parsing bailout.
1228 int literal_index = function_state_->NextMaterializedLiteralIndex(); 1296 int literal_index = function_state_->NextMaterializedLiteralIndex();
1229 1297
1230 return factory()->NewArrayLiteral(values, literal_index, pos); 1298 return factory()->NewArrayLiteral(values, literal_index, pos);
1231 } 1299 }
1232 1300
1301
1302 template <class Traits>
1303 typename Traits::Type::Expression ParserBase<Traits>::ParseObjectLiteral(
1304 bool* ok) {
1305 // ObjectLiteral ::
1306 // '{' ((
1307 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
1308 // (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
1309 // ) ',')* '}'
1310 // (Except that trailing comma is not required and not allowed.)
1311
1312 int pos = peek_position();
1313 typename Traits::Type::PropertyList properties =
1314 this->NewPropertyList(4, zone_);
1315 int number_of_boilerplate_properties = 0;
1316 bool has_function = false;
1317
1318 ObjectLiteralChecker checker(this, strict_mode());
1319
1320 Expect(Token::LBRACE, CHECK_OK);
1321
1322 while (peek() != Token::RBRACE) {
1323 if (fni_ != NULL) fni_->Enter();
1324
1325 typename Traits::Type::Literal key = this->EmptyLiteral();
1326 Token::Value next = peek();
1327 int next_pos = peek_position();
1328
1329 switch (next) {
1330 case Token::FUTURE_RESERVED_WORD:
1331 case Token::FUTURE_STRICT_RESERVED_WORD:
1332 case Token::IDENTIFIER: {
1333 bool is_getter = false;
1334 bool is_setter = false;
1335 typename Traits::Type::Identifier id =
1336 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
1337 if (fni_ != NULL) this->PushLiteralName(fni_, id);
1338
1339 if ((is_getter || is_setter) && peek() != Token::COLON) {
1340 // Special handling of getter and setter syntax:
1341 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
1342 // We have already read the "get" or "set" keyword.
1343 Token::Value next = Next();
1344 if (next != i::Token::IDENTIFIER &&
1345 next != i::Token::FUTURE_RESERVED_WORD &&
1346 next != i::Token::FUTURE_STRICT_RESERVED_WORD &&
1347 next != i::Token::NUMBER &&
1348 next != i::Token::STRING &&
1349 !Token::IsKeyword(next)) {
1350 ReportUnexpectedToken(next);
1351 *ok = false;
1352 return this->EmptyLiteral();
1353 }
1354 // Validate the property.
1355 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
1356 checker.CheckProperty(next, type, CHECK_OK);
1357 typename Traits::Type::Identifier name = this->GetSymbol(scanner_);
1358 typename Traits::Type::FunctionLiteral value =
1359 this->ParseFunctionLiteral(
1360 name, scanner()->location(),
1361 false, // reserved words are allowed here
1362 false, // not a generator
1363 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
1364 CHECK_OK);
1365 // Allow any number of parameters for compatibilty with JSC.
1366 // Specification only allows zero parameters for get and one for set.
1367 typename Traits::Type::ObjectLiteralProperty property =
1368 factory()->NewObjectLiteralProperty(is_getter, value, next_pos);
1369 if (this->IsBoilerplateProperty(property)) {
1370 number_of_boilerplate_properties++;
1371 }
1372 properties->Add(property, zone());
1373 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
1374
1375 if (fni_ != NULL) {
1376 fni_->Infer();
1377 fni_->Leave();
1378 }
1379 continue; // restart the while
1380 }
1381 // Failed to parse as get/set property, so it's just a normal property
1382 // (which might be called "get" or "set" or something else).
1383 key = factory()->NewLiteral(id, next_pos);
1384 break;
1385 }
1386 case Token::STRING: {
1387 Consume(Token::STRING);
1388 typename Traits::Type::Identifier string = this->GetSymbol(scanner_);
1389 if (fni_ != NULL) this->PushLiteralName(fni_, string);
1390 uint32_t index;
1391 if (this->IsArrayIndex(string, &index)) {
1392 key = factory()->NewNumberLiteral(index, next_pos);
1393 break;
1394 }
1395 key = factory()->NewLiteral(string, next_pos);
1396 break;
1397 }
1398 case Token::NUMBER: {
1399 Consume(Token::NUMBER);
1400 key = this->ExpressionFromLiteral(Token::NUMBER, next_pos, scanner_,
1401 factory());
1402 break;
1403 }
1404 default:
1405 if (Token::IsKeyword(next)) {
1406 Consume(next);
1407 typename Traits::Type::Identifier string = this->GetSymbol(scanner_);
1408 key = factory()->NewLiteral(string, next_pos);
1409 } else {
1410 Token::Value next = Next();
1411 ReportUnexpectedToken(next);
1412 *ok = false;
1413 return this->EmptyLiteral();
1414 }
1415 }
1416
1417 // Validate the property
1418 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1419
1420 Expect(Token::COLON, CHECK_OK);
1421 typename Traits::Type::Expression value =
1422 this->ParseAssignmentExpression(true, CHECK_OK);
1423
1424 typename Traits::Type::ObjectLiteralProperty property =
1425 factory()->NewObjectLiteralProperty(key, value);
1426
1427 // Mark top-level object literals that contain function literals and
1428 // pretenure the literal so it can be added as a constant function
1429 // property. (Parser only.)
1430 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, value,
1431 &has_function);
1432
1433 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
1434 if (this->IsBoilerplateProperty(property)) {
1435 number_of_boilerplate_properties++;
1436 }
1437 properties->Add(property, zone());
1438
1439 // TODO(1240767): Consider allowing trailing comma.
1440 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
1441
1442 if (fni_ != NULL) {
1443 fni_->Infer();
1444 fni_->Leave();
1445 }
1446 }
1447 Expect(Token::RBRACE, CHECK_OK);
1448
1449 // Computation of literal_index must happen before pre parse bailout.
1450 int literal_index = function_state_->NextMaterializedLiteralIndex();
1451
1452 return factory()->NewObjectLiteral(properties,
1453 literal_index,
1454 number_of_boilerplate_properties,
1455 has_function,
1456 pos);
1457 }
1458
1459
1460
1233 #undef CHECK_OK 1461 #undef CHECK_OK
1234 1462
1235 1463
1236 template <typename Traits> 1464 template <typename Traits>
1237 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( 1465 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
1238 Token::Value property, 1466 Token::Value property,
1239 PropertyKind type, 1467 PropertyKind type,
1240 bool* ok) { 1468 bool* ok) {
1241 int old; 1469 int old;
1242 if (property == Token::NUMBER) { 1470 if (property == Token::NUMBER) {
(...skipping 21 matching lines...) Expand all
1264 "accessor_get_set"); 1492 "accessor_get_set");
1265 } 1493 }
1266 *ok = false; 1494 *ok = false;
1267 } 1495 }
1268 } 1496 }
1269 1497
1270 1498
1271 } } // v8::internal 1499 } } // v8::internal
1272 1500
1273 #endif // V8_PREPARSER_H 1501 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698