OLD | NEW |
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" |
11 #include "src/func-name-inferrer.h" | 11 #include "src/func-name-inferrer.h" |
12 #include "src/hashmap.h" | 12 #include "src/hashmap.h" |
13 #include "src/scanner.h" | 13 #include "src/scanner.h" |
14 #include "src/scopes.h" | 14 #include "src/scopes.h" |
15 #include "src/token.h" | 15 #include "src/token.h" |
16 | 16 |
17 namespace v8 { | 17 namespace v8 { |
18 namespace internal { | 18 namespace internal { |
19 | 19 |
| 20 |
| 21 // When parsing the formal parameters of a function, we usually don't yet know |
| 22 // if the function will be strict, so we cannot yet produce errors for |
| 23 // parameter names or duplicates. Instead, we remember the locations of these |
| 24 // errors if they occur and produce the errors later. |
| 25 class FormalParameterErrorLocations BASE_EMBEDDED { |
| 26 public: |
| 27 FormalParameterErrorLocations() |
| 28 : eval_or_arguments(Scanner::Location::invalid()), |
| 29 undefined(Scanner::Location::invalid()), |
| 30 duplicate(Scanner::Location::invalid()), |
| 31 reserved(Scanner::Location::invalid()) {} |
| 32 |
| 33 Scanner::Location eval_or_arguments; |
| 34 Scanner::Location undefined; |
| 35 Scanner::Location duplicate; |
| 36 Scanner::Location reserved; |
| 37 }; |
| 38 |
| 39 |
20 // Common base class shared between parser and pre-parser. Traits encapsulate | 40 // Common base class shared between parser and pre-parser. Traits encapsulate |
21 // the differences between Parser and PreParser: | 41 // the differences between Parser and PreParser: |
22 | 42 |
23 // - Return types: For example, Parser functions return Expression* and | 43 // - Return types: For example, Parser functions return Expression* and |
24 // PreParser functions return PreParserExpression. | 44 // PreParser functions return PreParserExpression. |
25 | 45 |
26 // - Creating parse tree nodes: Parser generates an AST during the recursive | 46 // - Creating parse tree nodes: Parser generates an AST during the recursive |
27 // descent. PreParser doesn't create a tree. Instead, it passes around minimal | 47 // descent. PreParser doesn't create a tree. Instead, it passes around minimal |
28 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain | 48 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain |
29 // just enough data for the upper layer functions. PreParserFactory is | 49 // just enough data for the upper layer functions. PreParserFactory is |
(...skipping 14 matching lines...) Expand all Loading... |
44 // typedef GeneratorVariable; | 64 // typedef GeneratorVariable; |
45 // // Return types for traversing functions. | 65 // // Return types for traversing functions. |
46 // typedef Identifier; | 66 // typedef Identifier; |
47 // typedef Expression; | 67 // typedef Expression; |
48 // typedef FunctionLiteral; | 68 // typedef FunctionLiteral; |
49 // typedef ClassLiteral; | 69 // typedef ClassLiteral; |
50 // typedef ObjectLiteralProperty; | 70 // typedef ObjectLiteralProperty; |
51 // typedef Literal; | 71 // typedef Literal; |
52 // typedef ExpressionList; | 72 // typedef ExpressionList; |
53 // typedef PropertyList; | 73 // typedef PropertyList; |
| 74 // typedef FormalParameter; |
| 75 // typedef FormalParameterScope; |
54 // // For constructing objects returned by the traversing functions. | 76 // // For constructing objects returned by the traversing functions. |
55 // typedef Factory; | 77 // typedef Factory; |
56 // }; | 78 // }; |
57 // // ... | 79 // // ... |
58 // }; | 80 // }; |
59 | 81 |
60 template <typename Traits> | 82 template <typename Traits> |
61 class ParserBase : public Traits { | 83 class ParserBase : public Traits { |
62 public: | 84 public: |
63 // Shorten type names defined by Traits. | 85 // Shorten type names defined by Traits. |
64 typedef typename Traits::Type::Expression ExpressionT; | 86 typedef typename Traits::Type::Expression ExpressionT; |
65 typedef typename Traits::Type::Identifier IdentifierT; | 87 typedef typename Traits::Type::Identifier IdentifierT; |
| 88 typedef typename Traits::Type::FormalParameter FormalParameterT; |
| 89 typedef typename Traits::Type::FormalParameterScope FormalParameterScopeT; |
66 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; | 90 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; |
67 typedef typename Traits::Type::Literal LiteralT; | 91 typedef typename Traits::Type::Literal LiteralT; |
68 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; | 92 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; |
69 | 93 |
70 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, | 94 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, |
71 v8::Extension* extension, AstValueFactory* ast_value_factory, | 95 v8::Extension* extension, AstValueFactory* ast_value_factory, |
72 ParserRecorder* log, typename Traits::Type::Parser this_object) | 96 ParserRecorder* log, typename Traits::Type::Parser this_object) |
73 : Traits(this_object), | 97 : Traits(this_object), |
74 parenthesized_function_(false), | 98 parenthesized_function_(false), |
75 scope_(NULL), | 99 scope_(NULL), |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 Traits::ReportMessageAt(function_name_loc, "strong_undefined"); | 512 Traits::ReportMessageAt(function_name_loc, "strong_undefined"); |
489 *ok = false; | 513 *ok = false; |
490 return; | 514 return; |
491 } | 515 } |
492 } | 516 } |
493 | 517 |
494 // Checking the parameter names of a function literal. This has to be done | 518 // Checking the parameter names of a function literal. This has to be done |
495 // after parsing the function, since the function can declare itself strict. | 519 // after parsing the function, since the function can declare itself strict. |
496 void CheckFunctionParameterNames(LanguageMode language_mode, | 520 void CheckFunctionParameterNames(LanguageMode language_mode, |
497 bool strict_params, | 521 bool strict_params, |
498 const Scanner::Location& eval_args_loc, | 522 const FormalParameterErrorLocations& locs, |
499 const Scanner::Location& undefined_loc, | |
500 const Scanner::Location& dupe_loc, | |
501 const Scanner::Location& reserved_loc, | |
502 bool* ok) { | 523 bool* ok) { |
503 if (is_sloppy(language_mode) && !strict_params) return; | 524 if (is_sloppy(language_mode) && !strict_params) return; |
504 if (is_strict(language_mode) && eval_args_loc.IsValid()) { | 525 if (is_strict(language_mode) && locs.eval_or_arguments.IsValid()) { |
505 Traits::ReportMessageAt(eval_args_loc, "strict_eval_arguments"); | 526 Traits::ReportMessageAt(locs.eval_or_arguments, "strict_eval_arguments"); |
506 *ok = false; | 527 *ok = false; |
507 return; | 528 return; |
508 } | 529 } |
509 if (is_strong(language_mode) && undefined_loc.IsValid()) { | 530 if (is_strong(language_mode) && locs.undefined.IsValid()) { |
510 Traits::ReportMessageAt(undefined_loc, "strong_undefined"); | 531 Traits::ReportMessageAt(locs.undefined, "strong_undefined"); |
511 *ok = false; | 532 *ok = false; |
512 return; | 533 return; |
513 } | 534 } |
514 // TODO(arv): When we add support for destructuring in setters we also need | 535 // TODO(arv): When we add support for destructuring in setters we also need |
515 // to check for duplicate names. | 536 // to check for duplicate names. |
516 if (dupe_loc.IsValid()) { | 537 if (locs.duplicate.IsValid()) { |
517 Traits::ReportMessageAt(dupe_loc, "strict_param_dupe"); | 538 Traits::ReportMessageAt(locs.duplicate, "strict_param_dupe"); |
518 *ok = false; | 539 *ok = false; |
519 return; | 540 return; |
520 } | 541 } |
521 if (reserved_loc.IsValid()) { | 542 if (locs.reserved.IsValid()) { |
522 Traits::ReportMessageAt(reserved_loc, "unexpected_strict_reserved"); | 543 Traits::ReportMessageAt(locs.reserved, "unexpected_strict_reserved"); |
523 *ok = false; | 544 *ok = false; |
524 return; | 545 return; |
525 } | 546 } |
526 } | 547 } |
527 | 548 |
528 // Determine precedence of given token. | 549 // Determine precedence of given token. |
529 static int Precedence(Token::Value token, bool accept_IN) { | 550 static int Precedence(Token::Value token, bool accept_IN) { |
530 if (token == Token::IN && !accept_IN) | 551 if (token == Token::IN && !accept_IN) |
531 return 0; // 0 precedence will terminate binary expression parsing | 552 return 0; // 0 precedence will terminate binary expression parsing |
532 return Token::Precedence(token); | 553 return Token::Precedence(token); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 620 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
600 ExpressionT ParseMemberExpression(bool* ok); | 621 ExpressionT ParseMemberExpression(bool* ok); |
601 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 622 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
602 bool* ok); | 623 bool* ok); |
603 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, | 624 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, |
604 bool* ok); | 625 bool* ok); |
605 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 626 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
606 void AddTemplateExpression(ExpressionT); | 627 void AddTemplateExpression(ExpressionT); |
607 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 628 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
608 | 629 |
| 630 void ParseFormalParameter(FormalParameterScopeT* scope, |
| 631 FormalParameterErrorLocations* locs, bool is_rest, |
| 632 bool* ok); |
| 633 int ParseFormalParameterList(FormalParameterScopeT* scope, |
| 634 FormalParameterErrorLocations* locs, |
| 635 bool* has_rest, bool* ok); |
| 636 void CheckArityRestrictions( |
| 637 int param_count, FunctionLiteral::ArityRestriction arity_restriction, |
| 638 int formals_start_pos, int formals_end_pos, bool* ok); |
| 639 |
609 // Checks if the expression is a valid reference expression (e.g., on the | 640 // Checks if the expression is a valid reference expression (e.g., on the |
610 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 641 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
611 // we allow calls for web compatibility and rewrite them to a runtime throw. | 642 // we allow calls for web compatibility and rewrite them to a runtime throw. |
612 ExpressionT CheckAndRewriteReferenceExpression( | 643 ExpressionT CheckAndRewriteReferenceExpression( |
613 ExpressionT expression, | 644 ExpressionT expression, |
614 Scanner::Location location, const char* message, bool* ok); | 645 Scanner::Location location, const char* message, bool* ok); |
615 | 646 |
616 // Used to validate property names in object literals and class literals | 647 // Used to validate property names in object literals and class literals |
617 enum PropertyKind { | 648 enum PropertyKind { |
618 kAccessorProperty, | 649 kAccessorProperty, |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
904 | 935 |
905 bool IsCall() const { | 936 bool IsCall() const { |
906 return TypeField::decode(code_) == kExpression && | 937 return TypeField::decode(code_) == kExpression && |
907 ExpressionTypeField::decode(code_) == kCallExpression; | 938 ExpressionTypeField::decode(code_) == kCallExpression; |
908 } | 939 } |
909 | 940 |
910 bool IsValidReferenceExpression() const { | 941 bool IsValidReferenceExpression() const { |
911 return IsIdentifier() || IsProperty(); | 942 return IsIdentifier() || IsProperty(); |
912 } | 943 } |
913 | 944 |
914 bool IsValidArrowParamList(Scanner::Location* undefined_loc) const { | 945 bool IsValidArrowParamList(FormalParameterErrorLocations* locs) const { |
915 ValidArrowParam valid = ValidateArrowParams(); | 946 ValidArrowParam valid = ValidateArrowParams(); |
916 if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) { | 947 if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) { |
917 return false; | 948 return false; |
918 } | 949 } |
919 if (valid == kValidArrowParam) { | 950 if (valid == kValidArrowParam) { |
920 return true; | 951 return true; |
921 } else if (valid == kInvalidStrongArrowParam) { | 952 } else if (valid == kInvalidStrongArrowParam) { |
922 // Return true for now regardless of strong mode for compatibility with | 953 // Return true for now regardless of strong mode for compatibility with |
923 // parser. | 954 // parser. |
924 *undefined_loc = Scanner::Location(); | 955 locs->undefined = Scanner::Location(); |
925 return true; | 956 return true; |
926 } else { | 957 } else { |
927 return false; | 958 return false; |
928 } | 959 } |
929 } | 960 } |
930 | 961 |
931 // At the moment PreParser doesn't track these expression types. | 962 // At the moment PreParser doesn't track these expression types. |
932 bool IsFunctionLiteral() const { return false; } | 963 bool IsFunctionLiteral() const { return false; } |
933 bool IsCallNew() const { return false; } | 964 bool IsCallNew() const { return false; } |
934 | 965 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1033 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 1064 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
1034 typedef BitField<ValidArrowParam, ParenthesizationField::kNext, 2> | 1065 typedef BitField<ValidArrowParam, ParenthesizationField::kNext, 2> |
1035 IsValidArrowParamListField; | 1066 IsValidArrowParamListField; |
1036 typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10> | 1067 typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10> |
1037 IdentifierTypeField; | 1068 IdentifierTypeField; |
1038 | 1069 |
1039 uint32_t code_; | 1070 uint32_t code_; |
1040 }; | 1071 }; |
1041 | 1072 |
1042 | 1073 |
1043 // PreParserExpressionList doesn't actually store the expressions because | 1074 // The pre-parser doesn't need to build lists of expressions, identifiers, or |
1044 // PreParser doesn't need to. | 1075 // the like. |
1045 class PreParserExpressionList { | 1076 template <typename T> |
| 1077 class PreParserList { |
1046 public: | 1078 public: |
1047 // These functions make list->Add(some_expression) work (and do nothing). | 1079 // These functions make list->Add(some_expression) work (and do nothing). |
1048 PreParserExpressionList() : length_(0) {} | 1080 PreParserList() : length_(0) {} |
1049 PreParserExpressionList* operator->() { return this; } | 1081 PreParserList* operator->() { return this; } |
1050 void Add(PreParserExpression, void*) { ++length_; } | 1082 void Add(T, void*) { ++length_; } |
1051 int length() const { return length_; } | 1083 int length() const { return length_; } |
1052 private: | 1084 private: |
1053 int length_; | 1085 int length_; |
1054 }; | 1086 }; |
1055 | 1087 |
1056 | 1088 |
| 1089 typedef PreParserList<PreParserExpression> PreParserExpressionList; |
| 1090 |
| 1091 |
1057 class PreParserStatement { | 1092 class PreParserStatement { |
1058 public: | 1093 public: |
1059 static PreParserStatement Default() { | 1094 static PreParserStatement Default() { |
1060 return PreParserStatement(kUnknownStatement); | 1095 return PreParserStatement(kUnknownStatement); |
1061 } | 1096 } |
1062 | 1097 |
1063 static PreParserStatement Jump() { | 1098 static PreParserStatement Jump() { |
1064 return PreParserStatement(kJumpStatement); | 1099 return PreParserStatement(kJumpStatement); |
1065 } | 1100 } |
1066 | 1101 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1111 kUseStrictExpressionStatement, | 1146 kUseStrictExpressionStatement, |
1112 kUseStrongExpressionStatement, | 1147 kUseStrongExpressionStatement, |
1113 kFunctionDeclaration | 1148 kFunctionDeclaration |
1114 }; | 1149 }; |
1115 | 1150 |
1116 explicit PreParserStatement(Type code) : code_(code) {} | 1151 explicit PreParserStatement(Type code) : code_(code) {} |
1117 Type code_; | 1152 Type code_; |
1118 }; | 1153 }; |
1119 | 1154 |
1120 | 1155 |
1121 | 1156 typedef PreParserList<PreParserStatement> PreParserStatementList; |
1122 // PreParserStatementList doesn't actually store the statements because | |
1123 // the PreParser does not need them. | |
1124 class PreParserStatementList { | |
1125 public: | |
1126 // These functions make list->Add(some_expression) work as no-ops. | |
1127 PreParserStatementList() {} | |
1128 PreParserStatementList* operator->() { return this; } | |
1129 void Add(PreParserStatement, void*) {} | |
1130 }; | |
1131 | 1157 |
1132 | 1158 |
1133 class PreParserFactory { | 1159 class PreParserFactory { |
1134 public: | 1160 public: |
1135 explicit PreParserFactory(void* unused_value_factory) {} | 1161 explicit PreParserFactory(void* unused_value_factory) {} |
1136 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, | 1162 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, |
1137 int pos) { | 1163 int pos) { |
1138 return PreParserExpression::Default(); | 1164 return PreParserExpression::Default(); |
1139 } | 1165 } |
1140 PreParserExpression NewNumberLiteral(double number, | 1166 PreParserExpression NewNumberLiteral(double number, |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1285 // Return types for traversing functions. | 1311 // Return types for traversing functions. |
1286 typedef PreParserIdentifier Identifier; | 1312 typedef PreParserIdentifier Identifier; |
1287 typedef PreParserExpression Expression; | 1313 typedef PreParserExpression Expression; |
1288 typedef PreParserExpression YieldExpression; | 1314 typedef PreParserExpression YieldExpression; |
1289 typedef PreParserExpression FunctionLiteral; | 1315 typedef PreParserExpression FunctionLiteral; |
1290 typedef PreParserExpression ClassLiteral; | 1316 typedef PreParserExpression ClassLiteral; |
1291 typedef PreParserExpression ObjectLiteralProperty; | 1317 typedef PreParserExpression ObjectLiteralProperty; |
1292 typedef PreParserExpression Literal; | 1318 typedef PreParserExpression Literal; |
1293 typedef PreParserExpressionList ExpressionList; | 1319 typedef PreParserExpressionList ExpressionList; |
1294 typedef PreParserExpressionList PropertyList; | 1320 typedef PreParserExpressionList PropertyList; |
| 1321 typedef PreParserIdentifier FormalParameter; |
| 1322 typedef DuplicateFinder FormalParameterScope; |
1295 typedef PreParserStatementList StatementList; | 1323 typedef PreParserStatementList StatementList; |
1296 | 1324 |
1297 // For constructing objects returned by the traversing functions. | 1325 // For constructing objects returned by the traversing functions. |
1298 typedef PreParserFactory Factory; | 1326 typedef PreParserFactory Factory; |
1299 }; | 1327 }; |
1300 | 1328 |
1301 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} | 1329 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} |
1302 | 1330 |
1303 // Helper functions for recursive descent. | 1331 // Helper functions for recursive descent. |
1304 static bool IsEval(PreParserIdentifier identifier) { | 1332 static bool IsEval(PreParserIdentifier identifier) { |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1519 int* expected_property_count, bool* ok) { | 1547 int* expected_property_count, bool* ok) { |
1520 UNREACHABLE(); | 1548 UNREACHABLE(); |
1521 } | 1549 } |
1522 | 1550 |
1523 V8_INLINE PreParserStatementList | 1551 V8_INLINE PreParserStatementList |
1524 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, | 1552 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
1525 Variable* fvar, Token::Value fvar_init_op, | 1553 Variable* fvar, Token::Value fvar_init_op, |
1526 FunctionKind kind, bool* ok); | 1554 FunctionKind kind, bool* ok); |
1527 | 1555 |
1528 // Utility functions | 1556 // Utility functions |
1529 int DeclareArrowParametersFromExpression(PreParserExpression expression, | 1557 V8_INLINE int DeclareArrowParametersFromExpression( |
1530 Scope* scope, | 1558 PreParserExpression expression, Scope* scope, |
1531 Scanner::Location* undefined_loc, | 1559 FormalParameterErrorLocations* locs, bool* ok) { |
1532 Scanner::Location* dupe_loc, | 1560 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect eval or |
1533 bool* ok) { | 1561 // arguments. Detect reserved words. |
1534 // TODO(aperez): Detect duplicated identifiers in paramlists. | 1562 *ok = expression.IsValidArrowParamList(locs); |
1535 *ok = expression.IsValidArrowParamList(undefined_loc); | |
1536 return 0; | 1563 return 0; |
1537 } | 1564 } |
1538 | 1565 |
1539 struct TemplateLiteralState {}; | 1566 struct TemplateLiteralState {}; |
1540 | 1567 |
1541 TemplateLiteralState OpenTemplateLiteral(int pos) { | 1568 TemplateLiteralState OpenTemplateLiteral(int pos) { |
1542 return TemplateLiteralState(); | 1569 return TemplateLiteralState(); |
1543 } | 1570 } |
1544 void AddTemplateSpan(TemplateLiteralState*, bool) {} | 1571 void AddTemplateSpan(TemplateLiteralState*, bool) {} |
1545 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} | 1572 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} |
1546 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int, | 1573 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int, |
1547 PreParserExpression tag) { | 1574 PreParserExpression tag) { |
1548 if (IsTaggedTemplate(tag)) { | 1575 if (IsTaggedTemplate(tag)) { |
1549 // Emulate generation of array literals for tag callsite | 1576 // Emulate generation of array literals for tag callsite |
1550 // 1st is array of cooked strings, second is array of raw strings | 1577 // 1st is array of cooked strings, second is array of raw strings |
1551 MaterializeTemplateCallsiteLiterals(); | 1578 MaterializeTemplateCallsiteLiterals(); |
1552 } | 1579 } |
1553 return EmptyExpression(); | 1580 return EmptyExpression(); |
1554 } | 1581 } |
1555 inline void MaterializeTemplateCallsiteLiterals(); | 1582 inline void MaterializeTemplateCallsiteLiterals(); |
1556 PreParserExpression NoTemplateTag() { | 1583 PreParserExpression NoTemplateTag() { |
1557 return PreParserExpression::NoTemplateTag(); | 1584 return PreParserExpression::NoTemplateTag(); |
1558 } | 1585 } |
1559 static bool IsTaggedTemplate(const PreParserExpression tag) { | 1586 static bool IsTaggedTemplate(const PreParserExpression tag) { |
1560 return !tag.IsNoTemplateTag(); | 1587 return !tag.IsNoTemplateTag(); |
1561 } | 1588 } |
1562 | 1589 |
| 1590 V8_INLINE bool DeclareFormalParameter(DuplicateFinder* scope, |
| 1591 PreParserIdentifier param, |
| 1592 bool is_rest); |
| 1593 |
1563 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} | 1594 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} |
1564 | 1595 |
1565 // Temporary glue; these functions will move to ParserBase. | 1596 // Temporary glue; these functions will move to ParserBase. |
1566 PreParserExpression ParseV8Intrinsic(bool* ok); | 1597 PreParserExpression ParseV8Intrinsic(bool* ok); |
1567 PreParserExpression ParseFunctionLiteral( | 1598 PreParserExpression ParseFunctionLiteral( |
1568 PreParserIdentifier name, Scanner::Location function_name_location, | 1599 PreParserIdentifier name, Scanner::Location function_name_location, |
1569 bool name_is_strict_reserved, FunctionKind kind, | 1600 bool name_is_strict_reserved, FunctionKind kind, |
1570 int function_token_position, FunctionLiteral::FunctionType type, | 1601 int function_token_position, FunctionLiteral::FunctionType type, |
1571 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); | 1602 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); |
1572 | 1603 |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1741 return pre_parser_->factory()->NewCall(function, args, pos); | 1772 return pre_parser_->factory()->NewCall(function, args, pos); |
1742 } | 1773 } |
1743 | 1774 |
1744 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, | 1775 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, |
1745 PreParserExpressionList args, | 1776 PreParserExpressionList args, |
1746 int pos) { | 1777 int pos) { |
1747 return pre_parser_->factory()->NewCallNew(function, args, pos); | 1778 return pre_parser_->factory()->NewCallNew(function, args, pos); |
1748 } | 1779 } |
1749 | 1780 |
1750 | 1781 |
| 1782 bool PreParserTraits::DeclareFormalParameter( |
| 1783 DuplicateFinder* duplicate_finder, PreParserIdentifier current_identifier, |
| 1784 bool is_rest) { |
| 1785 return pre_parser_->scanner()->FindSymbol(duplicate_finder, 1) != 0; |
| 1786 } |
| 1787 |
| 1788 |
1751 PreParserStatementList PreParser::ParseEagerFunctionBody( | 1789 PreParserStatementList PreParser::ParseEagerFunctionBody( |
1752 PreParserIdentifier function_name, int pos, Variable* fvar, | 1790 PreParserIdentifier function_name, int pos, Variable* fvar, |
1753 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { | 1791 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { |
1754 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1792 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
1755 | 1793 |
1756 ParseStatementList(Token::RBRACE, ok); | 1794 ParseStatementList(Token::RBRACE, ok); |
1757 if (!*ok) return PreParserStatementList(); | 1795 if (!*ok) return PreParserStatementList(); |
1758 | 1796 |
1759 Expect(Token::RBRACE, ok); | 1797 Expect(Token::RBRACE, ok); |
1760 return PreParserStatementList(); | 1798 return PreParserStatementList(); |
(...skipping 1273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3034 default: | 3072 default: |
3035 return expression; | 3073 return expression; |
3036 } | 3074 } |
3037 } | 3075 } |
3038 DCHECK(false); | 3076 DCHECK(false); |
3039 return this->EmptyExpression(); | 3077 return this->EmptyExpression(); |
3040 } | 3078 } |
3041 | 3079 |
3042 | 3080 |
3043 template <class Traits> | 3081 template <class Traits> |
| 3082 void ParserBase<Traits>::ParseFormalParameter( |
| 3083 FormalParameterScopeT* scope, FormalParameterErrorLocations* locs, |
| 3084 bool is_rest, bool* ok) { |
| 3085 // FormalParameter[Yield,GeneratorParameter] : |
| 3086 // BindingElement[?Yield, ?GeneratorParameter] |
| 3087 bool is_strict_reserved; |
| 3088 IdentifierT name = |
| 3089 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, ok); |
| 3090 if (!*ok) return; |
| 3091 |
| 3092 // Store locations for possible future error reports. |
| 3093 if (!locs->eval_or_arguments.IsValid() && this->IsEvalOrArguments(name)) { |
| 3094 locs->eval_or_arguments = scanner()->location(); |
| 3095 } |
| 3096 if (!locs->undefined.IsValid() && this->IsUndefined(name)) { |
| 3097 locs->undefined = scanner()->location(); |
| 3098 } |
| 3099 if (!locs->reserved.IsValid() && is_strict_reserved) { |
| 3100 locs->reserved = scanner()->location(); |
| 3101 } |
| 3102 bool was_declared = Traits::DeclareFormalParameter(scope, name, is_rest); |
| 3103 if (!locs->duplicate.IsValid() && was_declared) { |
| 3104 locs->duplicate = scanner()->location(); |
| 3105 } |
| 3106 } |
| 3107 |
| 3108 |
| 3109 template <class Traits> |
| 3110 int ParserBase<Traits>::ParseFormalParameterList( |
| 3111 FormalParameterScopeT* scope, FormalParameterErrorLocations* locs, |
| 3112 bool* is_rest, bool* ok) { |
| 3113 // FormalParameters[Yield,GeneratorParameter] : |
| 3114 // [empty] |
| 3115 // FormalParameterList[?Yield, ?GeneratorParameter] |
| 3116 // |
| 3117 // FormalParameterList[Yield,GeneratorParameter] : |
| 3118 // FunctionRestParameter[?Yield] |
| 3119 // FormalsList[?Yield, ?GeneratorParameter] |
| 3120 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield] |
| 3121 // |
| 3122 // FormalsList[Yield,GeneratorParameter] : |
| 3123 // FormalParameter[?Yield, ?GeneratorParameter] |
| 3124 // FormalsList[?Yield, ?GeneratorParameter] , |
| 3125 // FormalParameter[?Yield,?GeneratorParameter] |
| 3126 |
| 3127 int parameter_count = 0; |
| 3128 |
| 3129 if (peek() != Token::RPAREN) { |
| 3130 do { |
| 3131 if (++parameter_count > Code::kMaxArguments) { |
| 3132 ReportMessage("too_many_parameters"); |
| 3133 *ok = false; |
| 3134 return -1; |
| 3135 } |
| 3136 *is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS); |
| 3137 ParseFormalParameter(scope, locs, *is_rest, ok); |
| 3138 if (!*ok) return -1; |
| 3139 } while (!*is_rest && Check(Token::COMMA)); |
| 3140 |
| 3141 if (*is_rest && peek() == Token::COMMA) { |
| 3142 ReportMessageAt(scanner()->peek_location(), "param_after_rest"); |
| 3143 *ok = false; |
| 3144 return -1; |
| 3145 } |
| 3146 } |
| 3147 |
| 3148 return parameter_count; |
| 3149 } |
| 3150 |
| 3151 |
| 3152 template <class Traits> |
| 3153 void ParserBase<Traits>::CheckArityRestrictions( |
| 3154 int param_count, FunctionLiteral::ArityRestriction arity_restriction, |
| 3155 int formals_start_pos, int formals_end_pos, bool* ok) { |
| 3156 switch (arity_restriction) { |
| 3157 case FunctionLiteral::GETTER_ARITY: |
| 3158 if (param_count != 0) { |
| 3159 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), |
| 3160 "bad_getter_arity"); |
| 3161 *ok = false; |
| 3162 } |
| 3163 break; |
| 3164 case FunctionLiteral::SETTER_ARITY: |
| 3165 if (param_count != 1) { |
| 3166 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), |
| 3167 "bad_setter_arity"); |
| 3168 *ok = false; |
| 3169 } |
| 3170 break; |
| 3171 default: |
| 3172 break; |
| 3173 } |
| 3174 } |
| 3175 |
| 3176 template <class Traits> |
3044 typename ParserBase<Traits>::ExpressionT | 3177 typename ParserBase<Traits>::ExpressionT |
3045 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, | 3178 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, |
3046 ExpressionT params_ast, | 3179 ExpressionT params_ast, |
3047 bool* ok) { | 3180 bool* ok) { |
3048 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3181 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
3049 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3182 // ASI inserts `;` after arrow parameters if a line terminator is found. |
3050 // `=> ...` is never a valid expression, so report as syntax error. | 3183 // `=> ...` is never a valid expression, so report as syntax error. |
3051 // If next token is not `=>`, it's a syntax error anyways. | 3184 // If next token is not `=>`, it's a syntax error anyways. |
3052 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3185 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
3053 *ok = false; | 3186 *ok = false; |
3054 return this->EmptyExpression(); | 3187 return this->EmptyExpression(); |
3055 } | 3188 } |
3056 | 3189 |
3057 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); | 3190 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); |
3058 typename Traits::Type::StatementList body; | 3191 typename Traits::Type::StatementList body; |
3059 int num_parameters = -1; | 3192 int num_parameters = -1; |
3060 int materialized_literal_count = -1; | 3193 int materialized_literal_count = -1; |
3061 int expected_property_count = -1; | 3194 int expected_property_count = -1; |
3062 int handler_count = 0; | 3195 int handler_count = 0; |
3063 Scanner::Location super_loc; | 3196 Scanner::Location super_loc; |
3064 | 3197 |
3065 { | 3198 { |
3066 typename Traits::Type::Factory function_factory(ast_value_factory()); | 3199 typename Traits::Type::Factory function_factory(ast_value_factory()); |
3067 FunctionState function_state(&function_state_, &scope_, scope, | 3200 FunctionState function_state(&function_state_, &scope_, scope, |
3068 kArrowFunction, &function_factory); | 3201 kArrowFunction, &function_factory); |
3069 Scanner::Location undefined_loc = Scanner::Location::invalid(); | 3202 FormalParameterErrorLocations error_locs; |
3070 Scanner::Location dupe_loc = Scanner::Location::invalid(); | |
3071 // TODO(arv): Pass in eval_args_loc and reserved_loc here. | |
3072 num_parameters = Traits::DeclareArrowParametersFromExpression( | 3203 num_parameters = Traits::DeclareArrowParametersFromExpression( |
3073 params_ast, scope_, &undefined_loc, &dupe_loc, ok); | 3204 params_ast, scope_, &error_locs, ok); |
3074 if (!*ok) { | 3205 if (!*ok) { |
3075 ReportMessageAt( | 3206 ReportMessageAt( |
3076 Scanner::Location(start_pos, scanner()->location().beg_pos), | 3207 Scanner::Location(start_pos, scanner()->location().beg_pos), |
3077 "malformed_arrow_function_parameter_list"); | 3208 "malformed_arrow_function_parameter_list"); |
3078 return this->EmptyExpression(); | 3209 return this->EmptyExpression(); |
3079 } | 3210 } |
3080 | 3211 |
3081 if (undefined_loc.IsValid()) { | 3212 if (error_locs.undefined.IsValid()) { |
3082 // Workaround for preparser not keeping track of positions. | 3213 // Workaround for preparser not keeping track of positions. |
3083 undefined_loc = Scanner::Location(start_pos, | 3214 error_locs.undefined = |
3084 scanner()->location().end_pos); | 3215 Scanner::Location(start_pos, scanner()->location().end_pos); |
3085 } | 3216 } |
3086 if (num_parameters > Code::kMaxArguments) { | 3217 if (num_parameters > Code::kMaxArguments) { |
3087 ReportMessageAt(Scanner::Location(params_ast->position(), position()), | 3218 ReportMessageAt(Scanner::Location(params_ast->position(), position()), |
3088 "too_many_parameters"); | 3219 "too_many_parameters"); |
3089 *ok = false; | 3220 *ok = false; |
3090 return this->EmptyExpression(); | 3221 return this->EmptyExpression(); |
3091 } | 3222 } |
3092 | 3223 |
3093 Expect(Token::ARROW, CHECK_OK); | 3224 Expect(Token::ARROW, CHECK_OK); |
3094 | 3225 |
(...skipping 25 matching lines...) Expand all Loading... |
3120 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3251 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
3121 materialized_literal_count = function_state.materialized_literal_count(); | 3252 materialized_literal_count = function_state.materialized_literal_count(); |
3122 expected_property_count = function_state.expected_property_count(); | 3253 expected_property_count = function_state.expected_property_count(); |
3123 handler_count = function_state.handler_count(); | 3254 handler_count = function_state.handler_count(); |
3124 } | 3255 } |
3125 super_loc = function_state.super_call_location(); | 3256 super_loc = function_state.super_call_location(); |
3126 | 3257 |
3127 scope->set_start_position(start_pos); | 3258 scope->set_start_position(start_pos); |
3128 scope->set_end_position(scanner()->location().end_pos); | 3259 scope->set_end_position(scanner()->location().end_pos); |
3129 | 3260 |
3130 // Arrow function *parameter lists* are always checked as in strict mode. | 3261 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
3131 // TODO(arv): eval_args_loc and reserved_loc needs to be set by | 3262 // which is not the same as "parameters of a strict function"; it only means |
3132 // DeclareArrowParametersFromExpression. | 3263 // that duplicates are not allowed. Of course, the arrow function may |
3133 Scanner::Location eval_args_loc = Scanner::Location::invalid(); | 3264 // itself be strict as well. |
3134 Scanner::Location reserved_loc = Scanner::Location::invalid(); | |
3135 const bool use_strict_params = true; | 3265 const bool use_strict_params = true; |
3136 this->CheckFunctionParameterNames(language_mode(), use_strict_params, | 3266 this->CheckFunctionParameterNames(language_mode(), use_strict_params, |
3137 eval_args_loc, undefined_loc, dupe_loc, | 3267 error_locs, CHECK_OK); |
3138 reserved_loc, CHECK_OK); | |
3139 | 3268 |
3140 // Validate strict mode. | 3269 // Validate strict mode. |
3141 if (is_strict(language_mode())) { | 3270 if (is_strict(language_mode())) { |
3142 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos, | 3271 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos, |
3143 CHECK_OK); | 3272 CHECK_OK); |
3144 this->CheckConflictingVarDeclarations(scope, CHECK_OK); | 3273 this->CheckConflictingVarDeclarations(scope, CHECK_OK); |
3145 } | 3274 } |
3146 } | 3275 } |
3147 | 3276 |
3148 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3277 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3341 *ok = false; | 3470 *ok = false; |
3342 return; | 3471 return; |
3343 } | 3472 } |
3344 has_seen_constructor_ = true; | 3473 has_seen_constructor_ = true; |
3345 return; | 3474 return; |
3346 } | 3475 } |
3347 } | 3476 } |
3348 } } // v8::internal | 3477 } } // v8::internal |
3349 | 3478 |
3350 #endif // V8_PREPARSER_H | 3479 #endif // V8_PREPARSER_H |
OLD | NEW |