| 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" |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 void CheckFunctionParameterNames(LanguageMode language_mode, | 520 void CheckFunctionParameterNames(LanguageMode language_mode, |
| 521 bool strict_params, | 521 bool strict_params, |
| 522 const FormalParameterErrorLocations& locs, | 522 const FormalParameterErrorLocations& locs, |
| 523 bool* ok) { | 523 bool* ok) { |
| 524 if (is_sloppy(language_mode) && !strict_params) return; | 524 if (is_sloppy(language_mode) && !strict_params) return; |
| 525 if (is_strict(language_mode) && locs.eval_or_arguments.IsValid()) { | 525 if (is_strict(language_mode) && locs.eval_or_arguments.IsValid()) { |
| 526 Traits::ReportMessageAt(locs.eval_or_arguments, "strict_eval_arguments"); | 526 Traits::ReportMessageAt(locs.eval_or_arguments, "strict_eval_arguments"); |
| 527 *ok = false; | 527 *ok = false; |
| 528 return; | 528 return; |
| 529 } | 529 } |
| 530 if (is_strict(language_mode) && locs.reserved.IsValid()) { |
| 531 Traits::ReportMessageAt(locs.reserved, "unexpected_strict_reserved"); |
| 532 *ok = false; |
| 533 return; |
| 534 } |
| 530 if (is_strong(language_mode) && locs.undefined.IsValid()) { | 535 if (is_strong(language_mode) && locs.undefined.IsValid()) { |
| 531 Traits::ReportMessageAt(locs.undefined, "strong_undefined"); | 536 Traits::ReportMessageAt(locs.undefined, "strong_undefined"); |
| 532 *ok = false; | 537 *ok = false; |
| 533 return; | 538 return; |
| 534 } | 539 } |
| 535 // TODO(arv): When we add support for destructuring in setters we also need | 540 // TODO(arv): When we add support for destructuring in setters we also need |
| 536 // to check for duplicate names. | 541 // to check for duplicate names. |
| 537 if (locs.duplicate.IsValid()) { | 542 if (locs.duplicate.IsValid()) { |
| 538 Traits::ReportMessageAt(locs.duplicate, "strict_param_dupe"); | 543 Traits::ReportMessageAt(locs.duplicate, "strict_param_dupe"); |
| 539 *ok = false; | 544 *ok = false; |
| 540 return; | 545 return; |
| 541 } | 546 } |
| 542 if (locs.reserved.IsValid()) { | |
| 543 Traits::ReportMessageAt(locs.reserved, "unexpected_strict_reserved"); | |
| 544 *ok = false; | |
| 545 return; | |
| 546 } | |
| 547 } | 547 } |
| 548 | 548 |
| 549 // Determine precedence of given token. | 549 // Determine precedence of given token. |
| 550 static int Precedence(Token::Value token, bool accept_IN) { | 550 static int Precedence(Token::Value token, bool accept_IN) { |
| 551 if (token == Token::IN && !accept_IN) | 551 if (token == Token::IN && !accept_IN) |
| 552 return 0; // 0 precedence will terminate binary expression parsing | 552 return 0; // 0 precedence will terminate binary expression parsing |
| 553 return Token::Precedence(token); | 553 return Token::Precedence(token); |
| 554 } | 554 } |
| 555 | 555 |
| 556 typename Traits::Type::Factory* factory() { | 556 typename Traits::Type::Factory* factory() { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 ExpressionT ParseYieldExpression(bool* ok); | 614 ExpressionT ParseYieldExpression(bool* ok); |
| 615 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 615 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
| 616 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 616 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
| 617 ExpressionT ParseUnaryExpression(bool* ok); | 617 ExpressionT ParseUnaryExpression(bool* ok); |
| 618 ExpressionT ParsePostfixExpression(bool* ok); | 618 ExpressionT ParsePostfixExpression(bool* ok); |
| 619 ExpressionT ParseLeftHandSideExpression(bool* ok); | 619 ExpressionT ParseLeftHandSideExpression(bool* ok); |
| 620 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 620 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
| 621 ExpressionT ParseMemberExpression(bool* ok); | 621 ExpressionT ParseMemberExpression(bool* ok); |
| 622 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 622 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
| 623 bool* ok); | 623 bool* ok); |
| 624 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, | 624 ExpressionT ParseArrowFunctionLiteral( |
| 625 bool* ok); | 625 Scope* function_scope, const FormalParameterErrorLocations& error_locs, |
| 626 bool has_rest, bool* ok); |
| 626 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 627 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
| 627 void AddTemplateExpression(ExpressionT); | 628 void AddTemplateExpression(ExpressionT); |
| 628 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 629 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
| 629 | 630 |
| 630 void ParseFormalParameter(FormalParameterScopeT* scope, | 631 void ParseFormalParameter(FormalParameterScopeT* scope, |
| 631 FormalParameterErrorLocations* locs, bool is_rest, | 632 FormalParameterErrorLocations* locs, bool is_rest, |
| 632 bool* ok); | 633 bool* ok); |
| 633 int ParseFormalParameterList(FormalParameterScopeT* scope, | 634 int ParseFormalParameterList(FormalParameterScopeT* scope, |
| 634 FormalParameterErrorLocations* locs, | 635 FormalParameterErrorLocations* locs, |
| 635 bool* has_rest, bool* ok); | 636 bool* has_rest, bool* ok); |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 839 ValidArrowParam valid_arrow_param_list = | 840 ValidArrowParam valid_arrow_param_list = |
| 840 (op == Token::COMMA && !left.is_parenthesized() && | 841 (op == Token::COMMA && !left.is_parenthesized() && |
| 841 !right.is_parenthesized()) ? | 842 !right.is_parenthesized()) ? |
| 842 std::min(left.ValidateArrowParams(), right.ValidateArrowParams()) | 843 std::min(left.ValidateArrowParams(), right.ValidateArrowParams()) |
| 843 : kInvalidArrowParam; | 844 : kInvalidArrowParam; |
| 844 return PreParserExpression( | 845 return PreParserExpression( |
| 845 TypeField::encode(kBinaryOperationExpression) | | 846 TypeField::encode(kBinaryOperationExpression) | |
| 846 IsValidArrowParamListField::encode(valid_arrow_param_list)); | 847 IsValidArrowParamListField::encode(valid_arrow_param_list)); |
| 847 } | 848 } |
| 848 | 849 |
| 849 static PreParserExpression EmptyArrowParamList() { | |
| 850 // Any expression for which IsValidArrowParamList() returns true | |
| 851 // will work here. | |
| 852 return FromIdentifier(PreParserIdentifier::Default()); | |
| 853 } | |
| 854 | |
| 855 static PreParserExpression StringLiteral() { | 850 static PreParserExpression StringLiteral() { |
| 856 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); | 851 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); |
| 857 } | 852 } |
| 858 | 853 |
| 859 static PreParserExpression UseStrictStringLiteral() { | 854 static PreParserExpression UseStrictStringLiteral() { |
| 860 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | | 855 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | |
| 861 IsUseStrictField::encode(true)); | 856 IsUseStrictField::encode(true)); |
| 862 } | 857 } |
| 863 | 858 |
| 864 static PreParserExpression UseStrongStringLiteral() { | 859 static PreParserExpression UseStrongStringLiteral() { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 | 930 |
| 936 bool IsCall() const { | 931 bool IsCall() const { |
| 937 return TypeField::decode(code_) == kExpression && | 932 return TypeField::decode(code_) == kExpression && |
| 938 ExpressionTypeField::decode(code_) == kCallExpression; | 933 ExpressionTypeField::decode(code_) == kCallExpression; |
| 939 } | 934 } |
| 940 | 935 |
| 941 bool IsValidReferenceExpression() const { | 936 bool IsValidReferenceExpression() const { |
| 942 return IsIdentifier() || IsProperty(); | 937 return IsIdentifier() || IsProperty(); |
| 943 } | 938 } |
| 944 | 939 |
| 945 bool IsValidArrowParamList(FormalParameterErrorLocations* locs) const { | 940 bool IsValidArrowParamList(FormalParameterErrorLocations* locs, |
| 941 const Scanner::Location& params_loc) const { |
| 946 ValidArrowParam valid = ValidateArrowParams(); | 942 ValidArrowParam valid = ValidateArrowParams(); |
| 947 if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) { | 943 if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) { |
| 948 return false; | 944 return false; |
| 949 } | 945 } |
| 950 if (valid == kValidArrowParam) { | 946 switch (valid) { |
| 951 return true; | 947 case kInvalidArrowParam: |
| 952 } else if (valid == kInvalidStrongArrowParam) { | 948 return false; |
| 953 // Return true for now regardless of strong mode for compatibility with | 949 case kInvalidStrongArrowParam: |
| 954 // parser. | 950 locs->undefined = params_loc; |
| 955 locs->undefined = Scanner::Location(); | 951 return true; |
| 956 return true; | 952 case kInvalidStrictReservedArrowParam: |
| 957 } else { | 953 locs->reserved = params_loc; |
| 958 return false; | 954 return true; |
| 955 case kInvalidStrictEvalArgumentsArrowParam: |
| 956 locs->eval_or_arguments = params_loc; |
| 957 return true; |
| 958 default: |
| 959 DCHECK_EQ(valid, kValidArrowParam); |
| 960 return true; |
| 959 } | 961 } |
| 960 } | 962 } |
| 961 | 963 |
| 962 // At the moment PreParser doesn't track these expression types. | 964 // At the moment PreParser doesn't track these expression types. |
| 963 bool IsFunctionLiteral() const { return false; } | 965 bool IsFunctionLiteral() const { return false; } |
| 964 bool IsCallNew() const { return false; } | 966 bool IsCallNew() const { return false; } |
| 965 | 967 |
| 966 bool IsNoTemplateTag() const { | 968 bool IsNoTemplateTag() const { |
| 967 return TypeField::decode(code_) == kExpression && | 969 return TypeField::decode(code_) == kExpression && |
| 968 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; | 970 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1015 }; | 1017 }; |
| 1016 | 1018 |
| 1017 enum ExpressionType { | 1019 enum ExpressionType { |
| 1018 kThisExpression, | 1020 kThisExpression, |
| 1019 kThisPropertyExpression, | 1021 kThisPropertyExpression, |
| 1020 kPropertyExpression, | 1022 kPropertyExpression, |
| 1021 kCallExpression, | 1023 kCallExpression, |
| 1022 kNoTemplateTagExpression | 1024 kNoTemplateTagExpression |
| 1023 }; | 1025 }; |
| 1024 | 1026 |
| 1027 // These validity constraints are ordered such that a value of N implies lack |
| 1028 // of errors M < N. |
| 1025 enum ValidArrowParam { | 1029 enum ValidArrowParam { |
| 1026 kInvalidArrowParam, | 1030 kInvalidArrowParam, |
| 1031 kInvalidStrictEvalArgumentsArrowParam, |
| 1032 kInvalidStrictReservedArrowParam, |
| 1027 kInvalidStrongArrowParam, | 1033 kInvalidStrongArrowParam, |
| 1028 kValidArrowParam | 1034 kValidArrowParam |
| 1029 }; | 1035 }; |
| 1030 | 1036 |
| 1031 explicit PreParserExpression(uint32_t expression_code) | 1037 explicit PreParserExpression(uint32_t expression_code) |
| 1032 : code_(expression_code) {} | 1038 : code_(expression_code) {} |
| 1033 | 1039 |
| 1034 V8_INLINE ValidArrowParam ValidateArrowParams() const { | 1040 V8_INLINE ValidArrowParam ValidateArrowParams() const { |
| 1035 if (IsBinaryOperation()) { | 1041 if (IsBinaryOperation()) { |
| 1036 return IsValidArrowParamListField::decode(code_); | 1042 return IsValidArrowParamListField::decode(code_); |
| 1037 } | 1043 } |
| 1038 if (!IsIdentifier()) { | 1044 if (!IsIdentifier()) { |
| 1039 return kInvalidArrowParam; | 1045 return kInvalidArrowParam; |
| 1040 } | 1046 } |
| 1041 PreParserIdentifier ident = AsIdentifier(); | 1047 PreParserIdentifier ident = AsIdentifier(); |
| 1042 // A valid identifier can be an arrow function parameter | 1048 // In strict mode, eval and arguments are not valid formal parameter names. |
| 1043 // except for eval, arguments, yield, and reserved keywords. | 1049 if (ident.IsEval() || ident.IsArguments()) { |
| 1044 if (ident.IsEval() || ident.IsArguments() || | 1050 return kInvalidStrictEvalArgumentsArrowParam; |
| 1045 ident.IsFutureStrictReserved()) { | |
| 1046 return kInvalidArrowParam; | |
| 1047 } | 1051 } |
| 1048 // In strong mode, 'undefined' is similarly restricted. | 1052 // In strict mode, future reserved words are not valid either, and as they |
| 1053 // produce different errors we allot them their own error code. |
| 1054 if (ident.IsFutureStrictReserved()) { |
| 1055 return kInvalidStrictReservedArrowParam; |
| 1056 } |
| 1057 // In strong mode, 'undefined' isn't a valid formal parameter name either. |
| 1049 if (ident.IsUndefined()) { | 1058 if (ident.IsUndefined()) { |
| 1050 return kInvalidStrongArrowParam; | 1059 return kInvalidStrongArrowParam; |
| 1051 } | 1060 } |
| 1052 return kValidArrowParam; | 1061 return kValidArrowParam; |
| 1053 } | 1062 } |
| 1054 | 1063 |
| 1055 // The first five bits are for the Type and Parenthesization. | 1064 // The first five bits are for the Type and Parenthesization. |
| 1056 typedef BitField<Type, 0, 3> TypeField; | 1065 typedef BitField<Type, 0, 3> TypeField; |
| 1057 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; | 1066 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; |
| 1058 | 1067 |
| 1059 // The rest of the bits are interpreted depending on the value | 1068 // The rest of the bits are interpreted depending on the value |
| 1060 // of the Type field, so they can share the storage. | 1069 // of the Type field, so they can share the storage. |
| 1061 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> | 1070 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> |
| 1062 ExpressionTypeField; | 1071 ExpressionTypeField; |
| 1063 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; | 1072 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; |
| 1064 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 1073 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
| 1065 typedef BitField<ValidArrowParam, ParenthesizationField::kNext, 2> | 1074 typedef BitField<ValidArrowParam, ParenthesizationField::kNext, 3> |
| 1066 IsValidArrowParamListField; | 1075 IsValidArrowParamListField; |
| 1067 typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10> | 1076 typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10> |
| 1068 IdentifierTypeField; | 1077 IdentifierTypeField; |
| 1069 | 1078 |
| 1070 uint32_t code_; | 1079 uint32_t code_; |
| 1071 }; | 1080 }; |
| 1072 | 1081 |
| 1073 | 1082 |
| 1074 // The pre-parser doesn't need to build lists of expressions, identifiers, or | 1083 // The pre-parser doesn't need to build lists of expressions, identifiers, or |
| 1075 // the like. | 1084 // the like. |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1456 // "null" return type creators. | 1465 // "null" return type creators. |
| 1457 static PreParserIdentifier EmptyIdentifier() { | 1466 static PreParserIdentifier EmptyIdentifier() { |
| 1458 return PreParserIdentifier::Default(); | 1467 return PreParserIdentifier::Default(); |
| 1459 } | 1468 } |
| 1460 static PreParserIdentifier EmptyIdentifierString() { | 1469 static PreParserIdentifier EmptyIdentifierString() { |
| 1461 return PreParserIdentifier::Default(); | 1470 return PreParserIdentifier::Default(); |
| 1462 } | 1471 } |
| 1463 static PreParserExpression EmptyExpression() { | 1472 static PreParserExpression EmptyExpression() { |
| 1464 return PreParserExpression::Default(); | 1473 return PreParserExpression::Default(); |
| 1465 } | 1474 } |
| 1466 static PreParserExpression EmptyArrowParamList() { | |
| 1467 return PreParserExpression::EmptyArrowParamList(); | |
| 1468 } | |
| 1469 static PreParserExpression EmptyLiteral() { | 1475 static PreParserExpression EmptyLiteral() { |
| 1470 return PreParserExpression::Default(); | 1476 return PreParserExpression::Default(); |
| 1471 } | 1477 } |
| 1472 static PreParserExpression EmptyObjectLiteralProperty() { | 1478 static PreParserExpression EmptyObjectLiteralProperty() { |
| 1473 return PreParserExpression::Default(); | 1479 return PreParserExpression::Default(); |
| 1474 } | 1480 } |
| 1475 static PreParserExpression EmptyFunctionLiteral() { | 1481 static PreParserExpression EmptyFunctionLiteral() { |
| 1476 return PreParserExpression::Default(); | 1482 return PreParserExpression::Default(); |
| 1477 } | 1483 } |
| 1478 static PreParserExpressionList NullExpressionList() { | 1484 static PreParserExpressionList NullExpressionList() { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1546 int* materialized_literal_count, | 1552 int* materialized_literal_count, |
| 1547 int* expected_property_count, bool* ok) { | 1553 int* expected_property_count, bool* ok) { |
| 1548 UNREACHABLE(); | 1554 UNREACHABLE(); |
| 1549 } | 1555 } |
| 1550 | 1556 |
| 1551 V8_INLINE PreParserStatementList | 1557 V8_INLINE PreParserStatementList |
| 1552 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, | 1558 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
| 1553 Variable* fvar, Token::Value fvar_init_op, | 1559 Variable* fvar, Token::Value fvar_init_op, |
| 1554 FunctionKind kind, bool* ok); | 1560 FunctionKind kind, bool* ok); |
| 1555 | 1561 |
| 1556 // Utility functions | 1562 V8_INLINE void ParseArrowFunctionFormalParameters( |
| 1557 V8_INLINE int DeclareArrowParametersFromExpression( | 1563 Scope* scope, PreParserExpression expression, |
| 1558 PreParserExpression expression, Scope* scope, | 1564 const Scanner::Location& params_loc, |
| 1559 FormalParameterErrorLocations* locs, bool* ok) { | 1565 FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok); |
| 1560 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect eval or | |
| 1561 // arguments. Detect reserved words. | |
| 1562 *ok = expression.IsValidArrowParamList(locs); | |
| 1563 return 0; | |
| 1564 } | |
| 1565 | 1566 |
| 1566 struct TemplateLiteralState {}; | 1567 struct TemplateLiteralState {}; |
| 1567 | 1568 |
| 1568 TemplateLiteralState OpenTemplateLiteral(int pos) { | 1569 TemplateLiteralState OpenTemplateLiteral(int pos) { |
| 1569 return TemplateLiteralState(); | 1570 return TemplateLiteralState(); |
| 1570 } | 1571 } |
| 1571 void AddTemplateSpan(TemplateLiteralState*, bool) {} | 1572 void AddTemplateSpan(TemplateLiteralState*, bool) {} |
| 1572 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} | 1573 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} |
| 1573 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int, | 1574 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int, |
| 1574 PreParserExpression tag) { | 1575 PreParserExpression tag) { |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1779 } | 1780 } |
| 1780 | 1781 |
| 1781 | 1782 |
| 1782 bool PreParserTraits::DeclareFormalParameter( | 1783 bool PreParserTraits::DeclareFormalParameter( |
| 1783 DuplicateFinder* duplicate_finder, PreParserIdentifier current_identifier, | 1784 DuplicateFinder* duplicate_finder, PreParserIdentifier current_identifier, |
| 1784 bool is_rest) { | 1785 bool is_rest) { |
| 1785 return pre_parser_->scanner()->FindSymbol(duplicate_finder, 1) != 0; | 1786 return pre_parser_->scanner()->FindSymbol(duplicate_finder, 1) != 0; |
| 1786 } | 1787 } |
| 1787 | 1788 |
| 1788 | 1789 |
| 1790 void PreParserTraits::ParseArrowFunctionFormalParameters( |
| 1791 Scope* scope, PreParserExpression params, |
| 1792 const Scanner::Location& params_loc, |
| 1793 FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok) { |
| 1794 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter |
| 1795 // lists that are too long. |
| 1796 if (!params.IsValidArrowParamList(error_locs, params_loc)) { |
| 1797 *ok = false; |
| 1798 ReportMessageAt(params_loc, "malformed_arrow_function_parameter_list"); |
| 1799 return; |
| 1800 } |
| 1801 } |
| 1802 |
| 1803 |
| 1789 PreParserStatementList PreParser::ParseEagerFunctionBody( | 1804 PreParserStatementList PreParser::ParseEagerFunctionBody( |
| 1790 PreParserIdentifier function_name, int pos, Variable* fvar, | 1805 PreParserIdentifier function_name, int pos, Variable* fvar, |
| 1791 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { | 1806 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { |
| 1792 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1807 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 1793 | 1808 |
| 1794 ParseStatementList(Token::RBRACE, ok); | 1809 ParseStatementList(Token::RBRACE, ok); |
| 1795 if (!*ok) return PreParserStatementList(); | 1810 if (!*ok) return PreParserStatementList(); |
| 1796 | 1811 |
| 1797 Expect(Token::RBRACE, ok); | 1812 Expect(Token::RBRACE, ok); |
| 1798 return PreParserStatementList(); | 1813 return PreParserStatementList(); |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2074 case Token::LBRACK: | 2089 case Token::LBRACK: |
| 2075 result = this->ParseArrayLiteral(CHECK_OK); | 2090 result = this->ParseArrayLiteral(CHECK_OK); |
| 2076 break; | 2091 break; |
| 2077 | 2092 |
| 2078 case Token::LBRACE: | 2093 case Token::LBRACE: |
| 2079 result = this->ParseObjectLiteral(CHECK_OK); | 2094 result = this->ParseObjectLiteral(CHECK_OK); |
| 2080 break; | 2095 break; |
| 2081 | 2096 |
| 2082 case Token::LPAREN: | 2097 case Token::LPAREN: |
| 2083 Consume(Token::LPAREN); | 2098 Consume(Token::LPAREN); |
| 2084 if (allow_harmony_arrow_functions() && peek() == Token::RPAREN) { | 2099 if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) { |
| 2085 // Arrow functions are the only expression type constructions | 2100 // As a primary expression, the only thing that can follow "()" is "=>". |
| 2086 // for which an empty parameter list "()" is valid input. | 2101 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); |
| 2087 Consume(Token::RPAREN); | 2102 scope->set_start_position(beg_pos); |
| 2088 result = this->ParseArrowFunctionLiteral( | 2103 FormalParameterErrorLocations error_locs; |
| 2089 beg_pos, this->EmptyArrowParamList(), CHECK_OK); | 2104 bool has_rest = false; |
| 2105 result = this->ParseArrowFunctionLiteral(scope, error_locs, has_rest, |
| 2106 CHECK_OK); |
| 2090 } else { | 2107 } else { |
| 2091 // Heuristically try to detect immediately called functions before | 2108 // Heuristically try to detect immediately called functions before |
| 2092 // seeing the call parentheses. | 2109 // seeing the call parentheses. |
| 2093 parenthesized_function_ = (peek() == Token::FUNCTION); | 2110 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 2094 result = this->ParseExpression(true, CHECK_OK); | 2111 result = this->ParseExpression(true, CHECK_OK); |
| 2095 result->increase_parenthesization_level(); | 2112 result->increase_parenthesization_level(); |
| 2096 Expect(Token::RPAREN, CHECK_OK); | 2113 Expect(Token::RPAREN, CHECK_OK); |
| 2097 } | 2114 } |
| 2098 break; | 2115 break; |
| 2099 | 2116 |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2537 return this->ParseYieldExpression(ok); | 2554 return this->ParseYieldExpression(ok); |
| 2538 } | 2555 } |
| 2539 | 2556 |
| 2540 if (fni_ != NULL) fni_->Enter(); | 2557 if (fni_ != NULL) fni_->Enter(); |
| 2541 ParserBase<Traits>::Checkpoint checkpoint(this); | 2558 ParserBase<Traits>::Checkpoint checkpoint(this); |
| 2542 ExpressionT expression = | 2559 ExpressionT expression = |
| 2543 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 2560 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
| 2544 | 2561 |
| 2545 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { | 2562 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { |
| 2546 checkpoint.Restore(); | 2563 checkpoint.Restore(); |
| 2547 expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos, | 2564 FormalParameterErrorLocations error_locs; |
| 2548 expression, CHECK_OK); | 2565 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); |
| 2566 bool has_rest = false; |
| 2567 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); |
| 2568 scope->set_start_position(lhs_location.beg_pos); |
| 2569 this->ParseArrowFunctionFormalParameters(scope, expression, loc, |
| 2570 &error_locs, &has_rest, CHECK_OK); |
| 2571 expression = |
| 2572 this->ParseArrowFunctionLiteral(scope, error_locs, has_rest, CHECK_OK); |
| 2549 return expression; | 2573 return expression; |
| 2550 } | 2574 } |
| 2551 | 2575 |
| 2552 if (!Token::IsAssignmentOp(peek())) { | 2576 if (!Token::IsAssignmentOp(peek())) { |
| 2553 if (fni_ != NULL) fni_->Leave(); | 2577 if (fni_ != NULL) fni_->Leave(); |
| 2554 // Parsed conditional expression only (no assignment). | 2578 // Parsed conditional expression only (no assignment). |
| 2555 return expression; | 2579 return expression; |
| 2556 } | 2580 } |
| 2557 | 2581 |
| 2558 expression = this->CheckAndRewriteReferenceExpression( | 2582 expression = this->CheckAndRewriteReferenceExpression( |
| (...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3166 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), | 3190 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), |
| 3167 "bad_setter_arity"); | 3191 "bad_setter_arity"); |
| 3168 *ok = false; | 3192 *ok = false; |
| 3169 } | 3193 } |
| 3170 break; | 3194 break; |
| 3171 default: | 3195 default: |
| 3172 break; | 3196 break; |
| 3173 } | 3197 } |
| 3174 } | 3198 } |
| 3175 | 3199 |
| 3200 |
| 3176 template <class Traits> | 3201 template <class Traits> |
| 3177 typename ParserBase<Traits>::ExpressionT | 3202 typename ParserBase<Traits>::ExpressionT |
| 3178 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, | 3203 ParserBase<Traits>::ParseArrowFunctionLiteral( |
| 3179 ExpressionT params_ast, | 3204 Scope* scope, const FormalParameterErrorLocations& error_locs, |
| 3180 bool* ok) { | 3205 bool has_rest, bool* ok) { |
| 3181 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3206 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
| 3182 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3207 // ASI inserts `;` after arrow parameters if a line terminator is found. |
| 3183 // `=> ...` is never a valid expression, so report as syntax error. | 3208 // `=> ...` is never a valid expression, so report as syntax error. |
| 3184 // If next token is not `=>`, it's a syntax error anyways. | 3209 // If next token is not `=>`, it's a syntax error anyways. |
| 3185 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3210 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
| 3186 *ok = false; | 3211 *ok = false; |
| 3187 return this->EmptyExpression(); | 3212 return this->EmptyExpression(); |
| 3188 } | 3213 } |
| 3189 | 3214 |
| 3190 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); | |
| 3191 typename Traits::Type::StatementList body; | 3215 typename Traits::Type::StatementList body; |
| 3192 int num_parameters = -1; | 3216 int num_parameters = scope->num_parameters(); |
| 3193 int materialized_literal_count = -1; | 3217 int materialized_literal_count = -1; |
| 3194 int expected_property_count = -1; | 3218 int expected_property_count = -1; |
| 3195 int handler_count = 0; | 3219 int handler_count = 0; |
| 3196 Scanner::Location super_loc; | 3220 Scanner::Location super_loc; |
| 3197 | 3221 |
| 3198 { | 3222 { |
| 3199 typename Traits::Type::Factory function_factory(ast_value_factory()); | 3223 typename Traits::Type::Factory function_factory(ast_value_factory()); |
| 3200 FunctionState function_state(&function_state_, &scope_, scope, | 3224 FunctionState function_state(&function_state_, &scope_, scope, |
| 3201 kArrowFunction, &function_factory); | 3225 kArrowFunction, &function_factory); |
| 3202 FormalParameterErrorLocations error_locs; | |
| 3203 num_parameters = Traits::DeclareArrowParametersFromExpression( | |
| 3204 params_ast, scope_, &error_locs, ok); | |
| 3205 if (!*ok) { | |
| 3206 ReportMessageAt( | |
| 3207 Scanner::Location(start_pos, scanner()->location().beg_pos), | |
| 3208 "malformed_arrow_function_parameter_list"); | |
| 3209 return this->EmptyExpression(); | |
| 3210 } | |
| 3211 | |
| 3212 if (error_locs.undefined.IsValid()) { | |
| 3213 // Workaround for preparser not keeping track of positions. | |
| 3214 error_locs.undefined = | |
| 3215 Scanner::Location(start_pos, scanner()->location().end_pos); | |
| 3216 } | |
| 3217 if (num_parameters > Code::kMaxArguments) { | |
| 3218 ReportMessageAt(Scanner::Location(params_ast->position(), position()), | |
| 3219 "too_many_parameters"); | |
| 3220 *ok = false; | |
| 3221 return this->EmptyExpression(); | |
| 3222 } | |
| 3223 | 3226 |
| 3224 Expect(Token::ARROW, CHECK_OK); | 3227 Expect(Token::ARROW, CHECK_OK); |
| 3225 | 3228 |
| 3226 if (peek() == Token::LBRACE) { | 3229 if (peek() == Token::LBRACE) { |
| 3227 // Multiple statement body | 3230 // Multiple statement body |
| 3228 Consume(Token::LBRACE); | 3231 Consume(Token::LBRACE); |
| 3229 bool is_lazily_parsed = | 3232 bool is_lazily_parsed = |
| 3230 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); | 3233 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); |
| 3231 if (is_lazily_parsed) { | 3234 if (is_lazily_parsed) { |
| 3232 body = this->NewStatementList(0, zone()); | 3235 body = this->NewStatementList(0, zone()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3248 parenthesized_function_ = false; | 3251 parenthesized_function_ = false; |
| 3249 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); | 3252 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); |
| 3250 body = this->NewStatementList(1, zone()); | 3253 body = this->NewStatementList(1, zone()); |
| 3251 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3254 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
| 3252 materialized_literal_count = function_state.materialized_literal_count(); | 3255 materialized_literal_count = function_state.materialized_literal_count(); |
| 3253 expected_property_count = function_state.expected_property_count(); | 3256 expected_property_count = function_state.expected_property_count(); |
| 3254 handler_count = function_state.handler_count(); | 3257 handler_count = function_state.handler_count(); |
| 3255 } | 3258 } |
| 3256 super_loc = function_state.super_call_location(); | 3259 super_loc = function_state.super_call_location(); |
| 3257 | 3260 |
| 3258 scope->set_start_position(start_pos); | |
| 3259 scope->set_end_position(scanner()->location().end_pos); | 3261 scope->set_end_position(scanner()->location().end_pos); |
| 3260 | 3262 |
| 3261 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 3263 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
| 3262 // which is not the same as "parameters of a strict function"; it only means | 3264 // which is not the same as "parameters of a strict function"; it only means |
| 3263 // that duplicates are not allowed. Of course, the arrow function may | 3265 // that duplicates are not allowed. Of course, the arrow function may |
| 3264 // itself be strict as well. | 3266 // itself be strict as well. |
| 3265 const bool use_strict_params = true; | 3267 const bool use_strict_params = true; |
| 3266 this->CheckFunctionParameterNames(language_mode(), use_strict_params, | 3268 this->CheckFunctionParameterNames(language_mode(), use_strict_params, |
| 3267 error_locs, CHECK_OK); | 3269 error_locs, CHECK_OK); |
| 3268 | 3270 |
| 3269 // Validate strict mode. | 3271 // Validate strict mode. |
| 3270 if (is_strict(language_mode())) { | 3272 if (is_strict(language_mode())) { |
| 3271 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos, | 3273 CheckStrictOctalLiteral(scope->start_position(), |
| 3272 CHECK_OK); | 3274 scanner()->location().end_pos, CHECK_OK); |
| 3273 this->CheckConflictingVarDeclarations(scope, CHECK_OK); | 3275 this->CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 3274 } | 3276 } |
| 3275 } | 3277 } |
| 3276 | 3278 |
| 3277 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3279 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
| 3278 this->EmptyIdentifierString(), ast_value_factory(), scope, body, | 3280 this->EmptyIdentifierString(), ast_value_factory(), scope, body, |
| 3279 materialized_literal_count, expected_property_count, handler_count, | 3281 materialized_literal_count, expected_property_count, handler_count, |
| 3280 num_parameters, FunctionLiteral::kNoDuplicateParameters, | 3282 num_parameters, FunctionLiteral::kNoDuplicateParameters, |
| 3281 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, | 3283 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, |
| 3282 FunctionLiteral::kNotParenthesized, FunctionKind::kArrowFunction, | 3284 FunctionLiteral::kNotParenthesized, FunctionKind::kArrowFunction, |
| 3283 start_pos); | 3285 scope->start_position()); |
| 3284 | 3286 |
| 3285 function_literal->set_function_token_position(start_pos); | 3287 function_literal->set_function_token_position(scope->start_position()); |
| 3286 if (super_loc.IsValid()) function_state_->set_super_call_location(super_loc); | 3288 if (super_loc.IsValid()) function_state_->set_super_call_location(super_loc); |
| 3287 | 3289 |
| 3288 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); | 3290 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); |
| 3289 | 3291 |
| 3290 return function_literal; | 3292 return function_literal; |
| 3291 } | 3293 } |
| 3292 | 3294 |
| 3293 | 3295 |
| 3294 template <typename Traits> | 3296 template <typename Traits> |
| 3295 typename ParserBase<Traits>::ExpressionT | 3297 typename ParserBase<Traits>::ExpressionT |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3470 *ok = false; | 3472 *ok = false; |
| 3471 return; | 3473 return; |
| 3472 } | 3474 } |
| 3473 has_seen_constructor_ = true; | 3475 has_seen_constructor_ = true; |
| 3474 return; | 3476 return; |
| 3475 } | 3477 } |
| 3476 } | 3478 } |
| 3477 } } // v8::internal | 3479 } } // v8::internal |
| 3478 | 3480 |
| 3479 #endif // V8_PREPARSER_H | 3481 #endif // V8_PREPARSER_H |
| OLD | NEW |