Chromium Code Reviews| 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 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 159 enum Mode { | 159 enum Mode { |
| 160 PARSE_LAZILY, | 160 PARSE_LAZILY, |
| 161 PARSE_EAGERLY | 161 PARSE_EAGERLY |
| 162 }; | 162 }; |
| 163 | 163 |
| 164 enum VariableDeclarationContext { | 164 enum VariableDeclarationContext { |
| 165 kStatementListItem, | 165 kStatementListItem, |
| 166 kStatement, | 166 kStatement, |
| 167 kForStatement | 167 kForStatement |
| 168 }; | 168 }; |
| 169 | |
| 170 class Checkpoint; | 169 class Checkpoint; |
| 171 class ObjectLiteralCheckerBase; | 170 class ObjectLiteralCheckerBase; |
| 172 | 171 |
| 173 // --------------------------------------------------------------------------- | 172 // --------------------------------------------------------------------------- |
| 174 // FunctionState and BlockState together implement the parser's scope stack. | 173 // FunctionState and BlockState together implement the parser's scope stack. |
| 175 // The parser's current scope is in scope_. BlockState and FunctionState | 174 // The parser's current scope is in scope_. BlockState and FunctionState |
| 176 // constructors push on the scope stack and the destructors pop. They are also | 175 // constructors push on the scope stack and the destructors pop. They are also |
| 177 // used to hold the parser's per-function and per-block state. | 176 // used to hold the parser's per-function and per-block state. |
| 178 class BlockState BASE_EMBEDDED { | 177 class BlockState BASE_EMBEDDED { |
| 179 public: | 178 public: |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 488 Traits::ReportMessageAt(function_name_loc, "strong_undefined"); | 487 Traits::ReportMessageAt(function_name_loc, "strong_undefined"); |
| 489 *ok = false; | 488 *ok = false; |
| 490 return; | 489 return; |
| 491 } | 490 } |
| 492 } | 491 } |
| 493 | 492 |
| 494 // Checking the parameter names of a function literal. This has to be done | 493 // 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. | 494 // after parsing the function, since the function can declare itself strict. |
| 496 void CheckFunctionParameterNames(LanguageMode language_mode, | 495 void CheckFunctionParameterNames(LanguageMode language_mode, |
| 497 bool strict_params, | 496 bool strict_params, |
| 498 const Scanner::Location& eval_args_error_loc, | 497 const Scanner::Location& eval_args_loc, |
| 499 const Scanner::Location& undefined_error_loc, | 498 const Scanner::Location& undefined_loc, |
| 500 const Scanner::Location& dupe_error_loc, | 499 const Scanner::Location& dupe_loc, |
| 501 const Scanner::Location& reserved_loc, | 500 const Scanner::Location& reserved_loc, |
| 502 bool* ok) { | 501 bool* ok) { |
| 503 if (is_sloppy(language_mode) && !strict_params) return; | 502 if (is_sloppy(language_mode) && !strict_params) return; |
| 504 | 503 if (is_strict(language_mode) && eval_args_loc.IsValid()) { |
| 505 if (is_strict(language_mode) && eval_args_error_loc.IsValid()) { | 504 Traits::ReportMessageAt(eval_args_loc, "strict_eval_arguments"); |
| 506 Traits::ReportMessageAt(eval_args_error_loc, "strict_eval_arguments"); | |
| 507 *ok = false; | 505 *ok = false; |
| 508 return; | 506 return; |
| 509 } | 507 } |
| 510 if (is_strong(language_mode) && undefined_error_loc.IsValid()) { | 508 if (is_strong(language_mode) && undefined_loc.IsValid()) { |
| 511 Traits::ReportMessageAt(eval_args_error_loc, "strong_undefined"); | 509 Traits::ReportMessageAt(undefined_loc, "strong_undefined"); |
| 512 *ok = false; | 510 *ok = false; |
| 513 return; | 511 return; |
| 514 } | 512 } |
| 515 // TODO(arv): When we add support for destructuring in setters we also need | 513 // TODO(arv): When we add support for destructuring in setters we also need |
| 516 // to check for duplicate names. | 514 // to check for duplicate names. |
| 517 if (dupe_error_loc.IsValid()) { | 515 if (dupe_loc.IsValid()) { |
| 518 Traits::ReportMessageAt(dupe_error_loc, "strict_param_dupe"); | 516 Traits::ReportMessageAt(dupe_loc, "strict_param_dupe"); |
| 519 *ok = false; | 517 *ok = false; |
| 520 return; | 518 return; |
| 521 } | 519 } |
| 522 if (reserved_loc.IsValid()) { | 520 if (reserved_loc.IsValid()) { |
| 523 Traits::ReportMessageAt(reserved_loc, "unexpected_strict_reserved"); | 521 Traits::ReportMessageAt(reserved_loc, "unexpected_strict_reserved"); |
| 524 *ok = false; | 522 *ok = false; |
| 525 return; | 523 return; |
| 526 } | 524 } |
| 527 } | 525 } |
| 528 | 526 |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 750 bool IsStatic() const { return type_ == kStaticIdentifier; } | 748 bool IsStatic() const { return type_ == kStaticIdentifier; } |
| 751 bool IsYield() const { return type_ == kYieldIdentifier; } | 749 bool IsYield() const { return type_ == kYieldIdentifier; } |
| 752 bool IsPrototype() const { return type_ == kPrototypeIdentifier; } | 750 bool IsPrototype() const { return type_ == kPrototypeIdentifier; } |
| 753 bool IsConstructor() const { return type_ == kConstructorIdentifier; } | 751 bool IsConstructor() const { return type_ == kConstructorIdentifier; } |
| 754 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; } | 752 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; } |
| 755 bool IsFutureStrictReserved() const { | 753 bool IsFutureStrictReserved() const { |
| 756 return type_ == kFutureStrictReservedIdentifier || | 754 return type_ == kFutureStrictReservedIdentifier || |
| 757 type_ == kLetIdentifier || type_ == kStaticIdentifier || | 755 type_ == kLetIdentifier || type_ == kStaticIdentifier || |
| 758 type_ == kYieldIdentifier; | 756 type_ == kYieldIdentifier; |
| 759 } | 757 } |
| 760 V8_INLINE bool IsValidArrowParam() const { | |
| 761 // A valid identifier can be an arrow function parameter | |
| 762 // except for eval, arguments, yield, and reserved keywords. | |
| 763 return !(IsEval() || IsArguments() || IsFutureStrictReserved()); | |
| 764 } | |
| 765 | 758 |
| 766 // Allow identifier->name()[->length()] to work. The preparser | 759 // Allow identifier->name()[->length()] to work. The preparser |
| 767 // does not need the actual positions/lengths of the identifiers. | 760 // does not need the actual positions/lengths of the identifiers. |
| 768 const PreParserIdentifier* operator->() const { return this; } | 761 const PreParserIdentifier* operator->() const { return this; } |
| 769 const PreParserIdentifier raw_name() const { return *this; } | 762 const PreParserIdentifier raw_name() const { return *this; } |
| 770 | 763 |
| 771 int position() const { return 0; } | 764 int position() const { return 0; } |
| 772 int length() const { return 0; } | 765 int length() const { return 0; } |
| 773 | 766 |
| 774 private: | 767 private: |
| 775 enum Type { | 768 enum Type { |
| 776 kUnknownIdentifier, | 769 kUnknownIdentifier, |
| 777 kFutureReservedIdentifier, | 770 kFutureReservedIdentifier, |
| 778 kFutureStrictReservedIdentifier, | 771 kFutureStrictReservedIdentifier, |
| 779 kLetIdentifier, | 772 kLetIdentifier, |
| 780 kStaticIdentifier, | 773 kStaticIdentifier, |
| 781 kYieldIdentifier, | 774 kYieldIdentifier, |
| 782 kEvalIdentifier, | 775 kEvalIdentifier, |
| 783 kArgumentsIdentifier, | 776 kArgumentsIdentifier, |
| 784 kUndefinedIdentifier, | 777 kUndefinedIdentifier, |
| 785 kPrototypeIdentifier, | 778 kPrototypeIdentifier, |
| 786 kConstructorIdentifier | 779 kConstructorIdentifier |
| 787 }; | 780 }; |
| 781 | |
| 788 explicit PreParserIdentifier(Type type) : type_(type) {} | 782 explicit PreParserIdentifier(Type type) : type_(type) {} |
| 789 Type type_; | 783 Type type_; |
| 790 | 784 |
| 791 friend class PreParserExpression; | 785 friend class PreParserExpression; |
| 792 }; | 786 }; |
| 793 | 787 |
| 794 | 788 |
| 795 class PreParserExpression { | 789 class PreParserExpression { |
| 796 public: | 790 public: |
| 797 static PreParserExpression Default() { | 791 static PreParserExpression Default() { |
| 798 return PreParserExpression(TypeField::encode(kExpression)); | 792 return PreParserExpression(TypeField::encode(kExpression)); |
| 799 } | 793 } |
| 800 | 794 |
| 801 static PreParserExpression Spread(PreParserExpression expression) { | 795 static PreParserExpression Spread(PreParserExpression expression) { |
| 802 return PreParserExpression(TypeField::encode(kSpreadExpression)); | 796 return PreParserExpression(TypeField::encode(kSpreadExpression)); |
| 803 } | 797 } |
| 804 | 798 |
| 805 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 799 static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
| 806 return PreParserExpression(TypeField::encode(kIdentifierExpression) | | 800 return PreParserExpression(TypeField::encode(kIdentifierExpression) | |
| 807 IdentifierTypeField::encode(id.type_)); | 801 IdentifierTypeField::encode(id.type_)); |
| 808 } | 802 } |
| 809 | 803 |
| 810 static PreParserExpression BinaryOperation(PreParserExpression left, | 804 static PreParserExpression BinaryOperation(PreParserExpression left, |
| 811 Token::Value op, | 805 Token::Value op, |
| 812 PreParserExpression right) { | 806 PreParserExpression right) { |
| 813 bool valid_arrow_param_list = | 807 ValidArrowParam valid_arrow_param_list; |
| 814 op == Token::COMMA && !left.is_parenthesized() && | 808 if (op == Token::COMMA && !left.is_parenthesized() && |
| 815 !right.is_parenthesized() && left.IsValidArrowParams() && | 809 !right.is_parenthesized()) { |
| 816 right.IsValidArrowParams(); | 810 valid_arrow_param_list = std::min(left.IsValidArrowParams(), |
| 811 right.IsValidArrowParams()); | |
| 812 } else { | |
| 813 valid_arrow_param_list = kInvalidArrowParam; | |
| 814 } | |
| 817 return PreParserExpression( | 815 return PreParserExpression( |
| 818 TypeField::encode(kBinaryOperationExpression) | | 816 TypeField::encode(kBinaryOperationExpression) | |
| 819 IsValidArrowParamListField::encode(valid_arrow_param_list)); | 817 IsValidArrowParamListField::encode(valid_arrow_param_list)); |
| 820 } | 818 } |
| 821 | 819 |
| 822 static PreParserExpression EmptyArrowParamList() { | 820 static PreParserExpression EmptyArrowParamList() { |
| 823 // Any expression for which IsValidArrowParamList() returns true | 821 // Any expression for which IsValidArrowParamList() returns true |
| 824 // will work here. | 822 // will work here. |
| 825 return FromIdentifier(PreParserIdentifier::Default()); | 823 return FromIdentifier(PreParserIdentifier::Default()); |
| 826 } | 824 } |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 908 | 906 |
| 909 bool IsCall() const { | 907 bool IsCall() const { |
| 910 return TypeField::decode(code_) == kExpression && | 908 return TypeField::decode(code_) == kExpression && |
| 911 ExpressionTypeField::decode(code_) == kCallExpression; | 909 ExpressionTypeField::decode(code_) == kCallExpression; |
| 912 } | 910 } |
| 913 | 911 |
| 914 bool IsValidReferenceExpression() const { | 912 bool IsValidReferenceExpression() const { |
| 915 return IsIdentifier() || IsProperty(); | 913 return IsIdentifier() || IsProperty(); |
| 916 } | 914 } |
| 917 | 915 |
| 918 bool IsValidArrowParamList() const { | 916 bool IsValidArrowParamList(Scope* scope, Scanner::Location* undefined_loc) |
| 919 return IsValidArrowParams() && | 917 const { |
| 920 ParenthesizationField::decode(code_) != | 918 ValidArrowParam valid = IsValidArrowParams(); |
| 921 kMultiParenthesizedExpression; | 919 if (ParenthesizationField::decode(code_) == kMultiParenthesizedExpression) { |
| 920 return false; | |
| 921 } | |
| 922 if (valid == kValidArrowParam) { | |
| 923 return true; | |
| 924 } else if (valid == kInvalidStrongArrowParam) { | |
| 925 *undefined_loc = Scanner::Location(); | |
| 926 return !is_strong(scope->language_mode()); | |
| 927 } else { | |
| 928 return false; | |
| 929 } | |
| 922 } | 930 } |
| 923 | 931 |
| 924 // At the moment PreParser doesn't track these expression types. | 932 // At the moment PreParser doesn't track these expression types. |
| 925 bool IsFunctionLiteral() const { return false; } | 933 bool IsFunctionLiteral() const { return false; } |
| 926 bool IsCallNew() const { return false; } | 934 bool IsCallNew() const { return false; } |
| 927 | 935 |
| 928 bool IsNoTemplateTag() const { | 936 bool IsNoTemplateTag() const { |
| 929 return TypeField::decode(code_) == kExpression && | 937 return TypeField::decode(code_) == kExpression && |
| 930 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; | 938 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; |
| 931 } | 939 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 977 }; | 985 }; |
| 978 | 986 |
| 979 enum ExpressionType { | 987 enum ExpressionType { |
| 980 kThisExpression, | 988 kThisExpression, |
| 981 kThisPropertyExpression, | 989 kThisPropertyExpression, |
| 982 kPropertyExpression, | 990 kPropertyExpression, |
| 983 kCallExpression, | 991 kCallExpression, |
| 984 kNoTemplateTagExpression | 992 kNoTemplateTagExpression |
| 985 }; | 993 }; |
| 986 | 994 |
| 995 enum ValidArrowParam { | |
| 996 kInvalidArrowParam, | |
| 997 kInvalidStrongArrowParam, | |
| 998 kValidArrowParam | |
| 999 }; | |
| 1000 | |
| 987 explicit PreParserExpression(uint32_t expression_code) | 1001 explicit PreParserExpression(uint32_t expression_code) |
| 988 : code_(expression_code) {} | 1002 : code_(expression_code) {} |
| 989 | 1003 |
| 990 V8_INLINE bool IsValidArrowParams() const { | 1004 V8_INLINE ValidArrowParam IsValidArrowParams() const { |
| 991 return IsBinaryOperation() | 1005 if (IsBinaryOperation()) { |
| 992 ? IsValidArrowParamListField::decode(code_) | 1006 return IsValidArrowParamListField::decode(code_); |
| 993 : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); | 1007 } |
| 1008 if (!IsIdentifier()) { | |
| 1009 return kInvalidArrowParam; | |
| 1010 } | |
| 1011 PreParserIdentifier ident = AsIdentifier(); | |
| 1012 // A valid identifier can be an arrow function parameter | |
| 1013 // except for eval, arguments, yield, and reserved keywords. | |
| 1014 if (ident.IsEval() || ident.IsArguments() || | |
| 1015 ident.IsFutureStrictReserved()) { | |
| 1016 return kInvalidArrowParam; | |
| 1017 } | |
| 1018 // In strong mode, 'undefined' is similarly restricted. | |
| 1019 if (ident.IsUndefined()) { | |
| 1020 return kInvalidStrongArrowParam; | |
| 1021 } | |
| 1022 return kValidArrowParam; | |
| 994 } | 1023 } |
| 995 | 1024 |
| 996 // The first five bits are for the Type and Parenthesization. | 1025 // The first five bits are for the Type and Parenthesization. |
| 997 typedef BitField<Type, 0, 3> TypeField; | 1026 typedef BitField<Type, 0, 3> TypeField; |
| 998 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; | 1027 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; |
| 999 | 1028 |
| 1000 // The rest of the bits are interpreted depending on the value | 1029 // The rest of the bits are interpreted depending on the value |
| 1001 // of the Type field, so they can share the storage. | 1030 // of the Type field, so they can share the storage. |
| 1002 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> | 1031 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> |
| 1003 ExpressionTypeField; | 1032 ExpressionTypeField; |
| 1004 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; | 1033 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; |
| 1005 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 1034 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
| 1006 typedef BitField<bool, ParenthesizationField::kNext, 1> | 1035 typedef BitField<ValidArrowParam, ParenthesizationField::kNext, 2> |
| 1007 IsValidArrowParamListField; | 1036 IsValidArrowParamListField; |
| 1008 typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10> | 1037 typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10> |
| 1009 IdentifierTypeField; | 1038 IdentifierTypeField; |
| 1010 | 1039 |
| 1011 uint32_t code_; | 1040 uint32_t code_; |
| 1012 }; | 1041 }; |
| 1013 | 1042 |
| 1014 | 1043 |
| 1015 // PreParserExpressionList doesn't actually store the expressions because | 1044 // PreParserExpressionList doesn't actually store the expressions because |
| 1016 // PreParser doesn't need to. | 1045 // PreParser doesn't need to. |
| (...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1484 } | 1513 } |
| 1485 | 1514 |
| 1486 V8_INLINE PreParserStatementList | 1515 V8_INLINE PreParserStatementList |
| 1487 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, | 1516 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
| 1488 Variable* fvar, Token::Value fvar_init_op, | 1517 Variable* fvar, Token::Value fvar_init_op, |
| 1489 FunctionKind kind, bool* ok); | 1518 FunctionKind kind, bool* ok); |
| 1490 | 1519 |
| 1491 // Utility functions | 1520 // Utility functions |
| 1492 int DeclareArrowParametersFromExpression(PreParserExpression expression, | 1521 int DeclareArrowParametersFromExpression(PreParserExpression expression, |
| 1493 Scope* scope, | 1522 Scope* scope, |
| 1523 Scanner::Location* undefined_loc, | |
| 1494 Scanner::Location* dupe_loc, | 1524 Scanner::Location* dupe_loc, |
| 1495 bool* ok) { | 1525 bool* ok) { |
| 1496 // TODO(aperez): Detect duplicated identifiers in paramlists. | 1526 // TODO(aperez): Detect duplicated identifiers in paramlists. |
| 1497 *ok = expression.IsValidArrowParamList(); | 1527 *ok = expression.IsValidArrowParamList(scope, undefined_loc); |
| 1498 return 0; | 1528 return 0; |
| 1499 } | 1529 } |
| 1500 | 1530 |
| 1501 struct TemplateLiteralState {}; | 1531 struct TemplateLiteralState {}; |
| 1502 | 1532 |
| 1503 TemplateLiteralState OpenTemplateLiteral(int pos) { | 1533 TemplateLiteralState OpenTemplateLiteral(int pos) { |
| 1504 return TemplateLiteralState(); | 1534 return TemplateLiteralState(); |
| 1505 } | 1535 } |
| 1506 void AddTemplateSpan(TemplateLiteralState*, bool) {} | 1536 void AddTemplateSpan(TemplateLiteralState*, bool) {} |
| 1507 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} | 1537 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} |
| (...skipping 1494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3002 ExpressionT params_ast, | 3032 ExpressionT params_ast, |
| 3003 bool* ok) { | 3033 bool* ok) { |
| 3004 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3034 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
| 3005 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3035 // ASI inserts `;` after arrow parameters if a line terminator is found. |
| 3006 // `=> ...` is never a valid expression, so report as syntax error. | 3036 // `=> ...` is never a valid expression, so report as syntax error. |
| 3007 // If next token is not `=>`, it's a syntax error anyways. | 3037 // If next token is not `=>`, it's a syntax error anyways. |
| 3008 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3038 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
| 3009 *ok = false; | 3039 *ok = false; |
| 3010 return this->EmptyExpression(); | 3040 return this->EmptyExpression(); |
| 3011 } | 3041 } |
| 3012 | |
| 3013 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); | 3042 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); |
| 3014 typename Traits::Type::StatementList body; | 3043 typename Traits::Type::StatementList body; |
| 3015 int num_parameters = -1; | 3044 int num_parameters = -1; |
| 3016 int materialized_literal_count = -1; | 3045 int materialized_literal_count = -1; |
| 3017 int expected_property_count = -1; | 3046 int expected_property_count = -1; |
| 3018 int handler_count = 0; | 3047 int handler_count = 0; |
| 3019 Scanner::Location super_loc; | 3048 Scanner::Location super_loc; |
| 3020 | 3049 |
| 3021 { | 3050 { |
| 3022 typename Traits::Type::Factory function_factory(ast_value_factory()); | 3051 typename Traits::Type::Factory function_factory(ast_value_factory()); |
| 3023 FunctionState function_state(&function_state_, &scope_, scope, | 3052 FunctionState function_state(&function_state_, &scope_, scope, |
| 3024 kArrowFunction, &function_factory); | 3053 kArrowFunction, &function_factory); |
| 3025 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | 3054 Scanner::Location undefined_loc = Scanner::Location::invalid(); |
| 3026 // TODO(arv): Pass in eval_args_error_loc and reserved_loc here. | 3055 Scanner::Location dupe_loc = Scanner::Location::invalid(); |
| 3056 // TODO(arv): Pass in eval_args_loc and reserved_loc here. | |
| 3027 num_parameters = Traits::DeclareArrowParametersFromExpression( | 3057 num_parameters = Traits::DeclareArrowParametersFromExpression( |
| 3028 params_ast, scope_, &dupe_error_loc, ok); | 3058 params_ast, scope_, &undefined_loc, &dupe_loc, ok); |
| 3029 if (!*ok) { | 3059 if (!*ok) { |
| 3030 ReportMessageAt( | 3060 ReportMessageAt( |
| 3031 Scanner::Location(start_pos, scanner()->location().beg_pos), | 3061 Scanner::Location(start_pos, scanner()->location().beg_pos), |
| 3032 "malformed_arrow_function_parameter_list"); | 3062 "malformed_arrow_function_parameter_list"); |
| 3033 return this->EmptyExpression(); | 3063 return this->EmptyExpression(); |
| 3034 } | 3064 } |
| 3035 | 3065 |
| 3066 if (undefined_loc.IsValid()) { | |
| 3067 // Workaround for preparser not keeping track of positions. | |
|
conradw
2015/04/10 12:27:45
Here's how the position of the error can be report
| |
| 3068 undefined_loc = Scanner::Location(start_pos, | |
| 3069 scanner()->location().end_pos); | |
| 3070 } | |
| 3036 if (num_parameters > Code::kMaxArguments) { | 3071 if (num_parameters > Code::kMaxArguments) { |
| 3037 ReportMessageAt(Scanner::Location(params_ast->position(), position()), | 3072 ReportMessageAt(Scanner::Location(params_ast->position(), position()), |
| 3038 "too_many_parameters"); | 3073 "too_many_parameters"); |
| 3039 *ok = false; | 3074 *ok = false; |
| 3040 return this->EmptyExpression(); | 3075 return this->EmptyExpression(); |
| 3041 } | 3076 } |
| 3042 | 3077 |
| 3043 Expect(Token::ARROW, CHECK_OK); | 3078 Expect(Token::ARROW, CHECK_OK); |
| 3044 | 3079 |
| 3045 if (peek() == Token::LBRACE) { | 3080 if (peek() == Token::LBRACE) { |
| 3046 // Multiple statemente body | 3081 // Multiple statement body |
| 3047 Consume(Token::LBRACE); | 3082 Consume(Token::LBRACE); |
| 3048 bool is_lazily_parsed = | 3083 bool is_lazily_parsed = |
| 3049 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); | 3084 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); |
| 3050 if (is_lazily_parsed) { | 3085 if (is_lazily_parsed) { |
| 3051 body = this->NewStatementList(0, zone()); | 3086 body = this->NewStatementList(0, zone()); |
| 3052 this->SkipLazyFunctionBody(this->EmptyIdentifier(), | 3087 this->SkipLazyFunctionBody(this->EmptyIdentifier(), |
| 3053 &materialized_literal_count, | 3088 &materialized_literal_count, |
| 3054 &expected_property_count, CHECK_OK); | 3089 &expected_property_count, CHECK_OK); |
| 3055 } else { | 3090 } else { |
| 3056 body = this->ParseEagerFunctionBody( | 3091 body = this->ParseEagerFunctionBody( |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 3071 materialized_literal_count = function_state.materialized_literal_count(); | 3106 materialized_literal_count = function_state.materialized_literal_count(); |
| 3072 expected_property_count = function_state.expected_property_count(); | 3107 expected_property_count = function_state.expected_property_count(); |
| 3073 handler_count = function_state.handler_count(); | 3108 handler_count = function_state.handler_count(); |
| 3074 } | 3109 } |
| 3075 super_loc = function_state.super_call_location(); | 3110 super_loc = function_state.super_call_location(); |
| 3076 | 3111 |
| 3077 scope->set_start_position(start_pos); | 3112 scope->set_start_position(start_pos); |
| 3078 scope->set_end_position(scanner()->location().end_pos); | 3113 scope->set_end_position(scanner()->location().end_pos); |
| 3079 | 3114 |
| 3080 // Arrow function *parameter lists* are always checked as in strict mode. | 3115 // Arrow function *parameter lists* are always checked as in strict mode. |
| 3081 // TODO(arv): eval_args_error_loc, undefined_error_loc, and reserved_loc | 3116 // TODO(arv): eval_args_loc and reserved_loc needs to be set by |
| 3082 // needs to be set by DeclareArrowParametersFromExpression. | 3117 // DeclareArrowParametersFromExpression. |
| 3083 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); | 3118 Scanner::Location eval_args_loc = Scanner::Location::invalid(); |
| 3084 Scanner::Location undefined_error_loc = Scanner::Location::invalid(); | |
| 3085 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 3119 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
| 3086 const bool use_strict_params = true; | 3120 const bool use_strict_params = true; |
| 3087 this->CheckFunctionParameterNames(language_mode(), use_strict_params, | 3121 this->CheckFunctionParameterNames(language_mode(), use_strict_params, |
| 3088 eval_args_error_loc, undefined_error_loc, | 3122 eval_args_loc, undefined_loc, dupe_loc, |
| 3089 dupe_error_loc, reserved_loc, CHECK_OK); | 3123 reserved_loc, CHECK_OK); |
| 3090 | 3124 |
| 3091 // Validate strict mode. | 3125 // Validate strict mode. |
| 3092 if (is_strict(language_mode())) { | 3126 if (is_strict(language_mode())) { |
| 3093 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos, | 3127 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos, |
| 3094 CHECK_OK); | 3128 CHECK_OK); |
| 3095 this->CheckConflictingVarDeclarations(scope, CHECK_OK); | 3129 this->CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 3096 } | 3130 } |
| 3097 } | 3131 } |
| 3098 | 3132 |
| 3099 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3133 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3292 *ok = false; | 3326 *ok = false; |
| 3293 return; | 3327 return; |
| 3294 } | 3328 } |
| 3295 has_seen_constructor_ = true; | 3329 has_seen_constructor_ = true; |
| 3296 return; | 3330 return; |
| 3297 } | 3331 } |
| 3298 } | 3332 } |
| 3299 } } // v8::internal | 3333 } } // v8::internal |
| 3300 | 3334 |
| 3301 #endif // V8_PREPARSER_H | 3335 #endif // V8_PREPARSER_H |
| OLD | NEW |