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

Side by Side Diff: src/preparser.h

Issue 194503004: Move ParseArguments to ParserBase and add tests. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: oops 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 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 bool* is_set, 335 bool* is_set,
336 bool* ok); 336 bool* ok);
337 337
338 typename Traits::Type::Expression ParseRegExpLiteral(bool seen_equal, 338 typename Traits::Type::Expression ParseRegExpLiteral(bool seen_equal,
339 bool* ok); 339 bool* ok);
340 340
341 typename Traits::Type::Expression ParsePrimaryExpression(bool* ok); 341 typename Traits::Type::Expression ParsePrimaryExpression(bool* ok);
342 typename Traits::Type::Expression ParseExpression(bool accept_IN, bool* ok); 342 typename Traits::Type::Expression ParseExpression(bool accept_IN, bool* ok);
343 typename Traits::Type::Expression ParseArrayLiteral(bool* ok); 343 typename Traits::Type::Expression ParseArrayLiteral(bool* ok);
344 typename Traits::Type::Expression ParseObjectLiteral(bool* ok); 344 typename Traits::Type::Expression ParseObjectLiteral(bool* ok);
345 typename Traits::Type::ExpressionList ParseArguments(bool* ok);
345 346
346 // Used to detect duplicates in object literals. Each of the values 347 // Used to detect duplicates in object literals. Each of the values
347 // kGetterProperty, kSetterProperty and kValueProperty represents 348 // kGetterProperty, kSetterProperty and kValueProperty represents
348 // a type of object literal property. When parsing a property, its 349 // a type of object literal property. When parsing a property, its
349 // type value is stored in the DuplicateFinder for the property name. 350 // type value is stored in the DuplicateFinder for the property name.
350 // Values are chosen so that having intersection bits means the there is 351 // Values are chosen so that having intersection bits means the there is
351 // an incompatibility. 352 // an incompatibility.
352 // I.e., you can add a getter to a property that already has a setter, since 353 // I.e., you can add a getter to a property that already has a setter, since
353 // kGetterProperty and kSetterProperty doesn't intersect, but not if it 354 // kGetterProperty and kSetterProperty doesn't intersect, but not if it
354 // already has a getter or a value. Adding the getter to an existing 355 // already has a getter or a value. Adding the getter to an existing
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 550
550 int code_; 551 int code_;
551 }; 552 };
552 553
553 554
554 // PreParserExpressionList doesn't actually store the expressions because 555 // PreParserExpressionList doesn't actually store the expressions because
555 // PreParser doesn't need to. 556 // PreParser doesn't need to.
556 class PreParserExpressionList { 557 class PreParserExpressionList {
557 public: 558 public:
558 // These functions make list->Add(some_expression) work (and do nothing). 559 // These functions make list->Add(some_expression) work (and do nothing).
560 PreParserExpressionList() : length_(0) {}
559 PreParserExpressionList* operator->() { return this; } 561 PreParserExpressionList* operator->() { return this; }
560 void Add(PreParserExpression, void*) { } 562 void Add(PreParserExpression, void*) { ++length_; }
563 int length() const { return length_; }
564 private:
565 int length_;
561 }; 566 };
562 567
563 568
564 class PreParserScope { 569 class PreParserScope {
565 public: 570 public:
566 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type) 571 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type)
567 : scope_type_(scope_type) { 572 : scope_type_(scope_type) {
568 if (outer_scope) { 573 if (outer_scope) {
569 scope_inside_with_ = outer_scope->scope_inside_with_ || is_with_scope(); 574 scope_inside_with_ = outer_scope->scope_inside_with_ || is_with_scope();
570 strict_mode_ = outer_scope->strict_mode(); 575 strict_mode_ = outer_scope->strict_mode();
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 // "null" return type creators. 718 // "null" return type creators.
714 static PreParserIdentifier EmptyIdentifier() { 719 static PreParserIdentifier EmptyIdentifier() {
715 return PreParserIdentifier::Default(); 720 return PreParserIdentifier::Default();
716 } 721 }
717 static PreParserExpression EmptyExpression() { 722 static PreParserExpression EmptyExpression() {
718 return PreParserExpression::Default(); 723 return PreParserExpression::Default();
719 } 724 }
720 static PreParserExpression EmptyLiteral() { 725 static PreParserExpression EmptyLiteral() {
721 return PreParserExpression::Default(); 726 return PreParserExpression::Default();
722 } 727 }
728 static PreParserExpressionList NullExpressionList() {
729 return PreParserExpressionList();
730 }
723 731
724 // Odd-ball literal creators. 732 // Odd-ball literal creators.
725 static PreParserExpression GetLiteralTheHole(int position, 733 static PreParserExpression GetLiteralTheHole(int position,
726 PreParserFactory* factory) { 734 PreParserFactory* factory) {
727 return PreParserExpression::Default(); 735 return PreParserExpression::Default();
728 } 736 }
729 737
730 // Producing data during the recursive descent. 738 // Producing data during the recursive descent.
731 PreParserIdentifier GetSymbol(Scanner* scanner); 739 PreParserIdentifier GetSymbol(Scanner* scanner);
732 static PreParserIdentifier NextLiteralString(Scanner* scanner, 740 static PreParserIdentifier NextLiteralString(Scanner* scanner,
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 }; 911 };
904 912
905 explicit Statement(Type code) : code_(code) {} 913 explicit Statement(Type code) : code_(code) {}
906 Type code_; 914 Type code_;
907 }; 915 };
908 916
909 enum SourceElements { 917 enum SourceElements {
910 kUnknownSourceElements 918 kUnknownSourceElements
911 }; 919 };
912 920
913 typedef int Arguments;
914
915 // All ParseXXX functions take as the last argument an *ok parameter 921 // All ParseXXX functions take as the last argument an *ok parameter
916 // which is set to false if parsing failed; it is unchanged otherwise. 922 // which is set to false if parsing failed; it is unchanged otherwise.
917 // By making the 'exception handling' explicit, we are forced to check 923 // By making the 'exception handling' explicit, we are forced to check
918 // for failure at the call sites. 924 // for failure at the call sites.
919 Statement ParseSourceElement(bool* ok); 925 Statement ParseSourceElement(bool* ok);
920 SourceElements ParseSourceElements(int end_token, bool* ok); 926 SourceElements ParseSourceElements(int end_token, bool* ok);
921 Statement ParseStatement(bool* ok); 927 Statement ParseStatement(bool* ok);
922 Statement ParseFunctionDeclaration(bool* ok); 928 Statement ParseFunctionDeclaration(bool* ok);
923 Statement ParseBlock(bool* ok); 929 Statement ParseBlock(bool* ok);
924 Statement ParseVariableStatement(VariableDeclarationContext var_context, 930 Statement ParseVariableStatement(VariableDeclarationContext var_context,
(...skipping 23 matching lines...) Expand all
948 Expression ParseUnaryExpression(bool* ok); 954 Expression ParseUnaryExpression(bool* ok);
949 Expression ParsePostfixExpression(bool* ok); 955 Expression ParsePostfixExpression(bool* ok);
950 Expression ParseLeftHandSideExpression(bool* ok); 956 Expression ParseLeftHandSideExpression(bool* ok);
951 Expression ParseMemberExpression(bool* ok); 957 Expression ParseMemberExpression(bool* ok);
952 Expression ParseMemberExpressionContinuation(PreParserExpression expression, 958 Expression ParseMemberExpressionContinuation(PreParserExpression expression,
953 bool* ok); 959 bool* ok);
954 Expression ParseMemberWithNewPrefixesExpression(bool* ok); 960 Expression ParseMemberWithNewPrefixesExpression(bool* ok);
955 Expression ParseObjectLiteral(bool* ok); 961 Expression ParseObjectLiteral(bool* ok);
956 Expression ParseV8Intrinsic(bool* ok); 962 Expression ParseV8Intrinsic(bool* ok);
957 963
958 Arguments ParseArguments(bool* ok);
959 Expression ParseFunctionLiteral( 964 Expression ParseFunctionLiteral(
960 Identifier name, 965 Identifier name,
961 Scanner::Location function_name_location, 966 Scanner::Location function_name_location,
962 bool name_is_strict_reserved, 967 bool name_is_strict_reserved,
963 bool is_generator, 968 bool is_generator,
964 int function_token_pos, 969 int function_token_pos,
965 FunctionLiteral::FunctionType function_type, 970 FunctionLiteral::FunctionType function_type,
966 bool* ok); 971 bool* ok);
967 void ParseLazyFunctionLiteralBody(bool* ok); 972 void ParseLazyFunctionLiteralBody(bool* ok);
968 973
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1146 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); 1151 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
1147 } 1152 }
1148 1153
1149 1154
1150 #define CHECK_OK ok); \ 1155 #define CHECK_OK ok); \
1151 if (!*ok) return this->EmptyExpression(); \ 1156 if (!*ok) return this->EmptyExpression(); \
1152 ((void)0 1157 ((void)0
1153 #define DUMMY ) // to make indentation work 1158 #define DUMMY ) // to make indentation work
1154 #undef DUMMY 1159 #undef DUMMY
1155 1160
1161 // Used in functions where the return type is not Traits::Type::Expression.
1162 #define CHECK_OK_CUSTOM(x) ok); \
1163 if (!*ok) return this->x(); \
1164 ((void)0
1165 #define DUMMY ) // to make indentation work
1166 #undef DUMMY
1167
1156 template <class Traits> 1168 template <class Traits>
1157 typename Traits::Type::Expression ParserBase<Traits>::ParsePrimaryExpression( 1169 typename Traits::Type::Expression ParserBase<Traits>::ParsePrimaryExpression(
1158 bool* ok) { 1170 bool* ok) {
1159 // PrimaryExpression :: 1171 // PrimaryExpression ::
1160 // 'this' 1172 // 'this'
1161 // 'null' 1173 // 'null'
1162 // 'true' 1174 // 'true'
1163 // 'false' 1175 // 'false'
1164 // Identifier 1176 // Identifier
1165 // Number 1177 // Number
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, 1375 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
1364 CHECK_OK); 1376 CHECK_OK);
1365 // Allow any number of parameters for compatibilty with JSC. 1377 // Allow any number of parameters for compatibilty with JSC.
1366 // Specification only allows zero parameters for get and one for set. 1378 // Specification only allows zero parameters for get and one for set.
1367 typename Traits::Type::ObjectLiteralProperty property = 1379 typename Traits::Type::ObjectLiteralProperty property =
1368 factory()->NewObjectLiteralProperty(is_getter, value, next_pos); 1380 factory()->NewObjectLiteralProperty(is_getter, value, next_pos);
1369 if (this->IsBoilerplateProperty(property)) { 1381 if (this->IsBoilerplateProperty(property)) {
1370 number_of_boilerplate_properties++; 1382 number_of_boilerplate_properties++;
1371 } 1383 }
1372 properties->Add(property, zone()); 1384 properties->Add(property, zone());
1373 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 1385 if (peek() != Token::RBRACE) {
1386 // Need {} because of the CHECK_OK macro.
1387 Expect(Token::COMMA, CHECK_OK);
1388 }
1374 1389
1375 if (fni_ != NULL) { 1390 if (fni_ != NULL) {
1376 fni_->Infer(); 1391 fni_->Infer();
1377 fni_->Leave(); 1392 fni_->Leave();
1378 } 1393 }
1379 continue; // restart the while 1394 continue; // restart the while
1380 } 1395 }
1381 // Failed to parse as get/set property, so it's just a normal property 1396 // 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). 1397 // (which might be called "get" or "set" or something else).
1383 key = factory()->NewLiteral(id, next_pos); 1398 key = factory()->NewLiteral(id, next_pos);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1430 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, value, 1445 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, value,
1431 &has_function); 1446 &has_function);
1432 1447
1433 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. 1448 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
1434 if (this->IsBoilerplateProperty(property)) { 1449 if (this->IsBoilerplateProperty(property)) {
1435 number_of_boilerplate_properties++; 1450 number_of_boilerplate_properties++;
1436 } 1451 }
1437 properties->Add(property, zone()); 1452 properties->Add(property, zone());
1438 1453
1439 // TODO(1240767): Consider allowing trailing comma. 1454 // TODO(1240767): Consider allowing trailing comma.
1440 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 1455 if (peek() != Token::RBRACE) {
1456 // Need {} because of the CHECK_OK macro.
1457 Expect(Token::COMMA, CHECK_OK);
1458 }
1441 1459
1442 if (fni_ != NULL) { 1460 if (fni_ != NULL) {
1443 fni_->Infer(); 1461 fni_->Infer();
1444 fni_->Leave(); 1462 fni_->Leave();
1445 } 1463 }
1446 } 1464 }
1447 Expect(Token::RBRACE, CHECK_OK); 1465 Expect(Token::RBRACE, CHECK_OK);
1448 1466
1449 // Computation of literal_index must happen before pre parse bailout. 1467 // Computation of literal_index must happen before pre parse bailout.
1450 int literal_index = function_state_->NextMaterializedLiteralIndex(); 1468 int literal_index = function_state_->NextMaterializedLiteralIndex();
1451 1469
1452 return factory()->NewObjectLiteral(properties, 1470 return factory()->NewObjectLiteral(properties,
1453 literal_index, 1471 literal_index,
1454 number_of_boilerplate_properties, 1472 number_of_boilerplate_properties,
1455 has_function, 1473 has_function,
1456 pos); 1474 pos);
1457 } 1475 }
1458 1476
1459 1477
1478 template <class Traits>
1479 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
1480 bool* ok) {
1481 // Arguments ::
1482 // '(' (AssignmentExpression)*[','] ')'
1483
1484 typename Traits::Type::ExpressionList result =
1485 this->NewExpressionList(4, zone_);
1486 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1487 bool done = (peek() == Token::RPAREN);
1488 while (!done) {
1489 typename Traits::Type::Expression argument =
1490 this->ParseAssignmentExpression(true,
1491 CHECK_OK_CUSTOM(NullExpressionList));
1492 result->Add(argument, zone_);
1493 if (result->length() > Code::kMaxArguments) {
1494 ReportMessageAt(scanner()->location(), "too_many_arguments");
1495 *ok = false;
1496 return this->NullExpressionList();
1497 }
1498 done = (peek() == Token::RPAREN);
1499 if (!done) {
1500 // Need {} because of the CHECK_OK_CUSTOM macro.
1501 Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList));
1502 }
1503 }
1504 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1505 return result;
1506 }
1507
1460 1508
1461 #undef CHECK_OK 1509 #undef CHECK_OK
1510 #undef CHECK_OK_CUSTOM
1462 1511
1463 1512
1464 template <typename Traits> 1513 template <typename Traits>
1465 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( 1514 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
1466 Token::Value property, 1515 Token::Value property,
1467 PropertyKind type, 1516 PropertyKind type,
1468 bool* ok) { 1517 bool* ok) {
1469 int old; 1518 int old;
1470 if (property == Token::NUMBER) { 1519 if (property == Token::NUMBER) {
1471 old = finder_.AddNumber(scanner()->literal_ascii_string(), type); 1520 old = finder_.AddNumber(scanner()->literal_ascii_string(), type);
(...skipping 20 matching lines...) Expand all
1492 "accessor_get_set"); 1541 "accessor_get_set");
1493 } 1542 }
1494 *ok = false; 1543 *ok = false;
1495 } 1544 }
1496 } 1545 }
1497 1546
1498 1547
1499 } } // v8::internal 1548 } } // v8::internal
1500 1549
1501 #endif // V8_PREPARSER_H 1550 #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