OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |