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 | |
rossberg
2015/04/10 14:02:56
Accidental line deletion?
conradw
2015/04/10 14:20:49
Done.
| |
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() && |
rossberg
2015/04/10 14:02:56
Nit: use ?: to avoid the imperative var initialisa
conradw
2015/04/10 14:20:49
Done.
| |
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) |
rossberg
2015/04/10 14:02:56
Is the scope parameter used at all?
conradw
2015/04/10 14:20:49
Done.
| |
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 // Return true for now regardless of strong mode for compatibility with | |
926 // parser. | |
927 *undefined_loc = Scanner::Location(); | |
928 return true; | |
929 } else { | |
930 return false; | |
931 } | |
922 } | 932 } |
923 | 933 |
924 // At the moment PreParser doesn't track these expression types. | 934 // At the moment PreParser doesn't track these expression types. |
925 bool IsFunctionLiteral() const { return false; } | 935 bool IsFunctionLiteral() const { return false; } |
926 bool IsCallNew() const { return false; } | 936 bool IsCallNew() const { return false; } |
927 | 937 |
928 bool IsNoTemplateTag() const { | 938 bool IsNoTemplateTag() const { |
929 return TypeField::decode(code_) == kExpression && | 939 return TypeField::decode(code_) == kExpression && |
930 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; | 940 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; |
931 } | 941 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
977 }; | 987 }; |
978 | 988 |
979 enum ExpressionType { | 989 enum ExpressionType { |
980 kThisExpression, | 990 kThisExpression, |
981 kThisPropertyExpression, | 991 kThisPropertyExpression, |
982 kPropertyExpression, | 992 kPropertyExpression, |
983 kCallExpression, | 993 kCallExpression, |
984 kNoTemplateTagExpression | 994 kNoTemplateTagExpression |
985 }; | 995 }; |
986 | 996 |
997 enum ValidArrowParam { | |
998 kInvalidArrowParam, | |
999 kInvalidStrongArrowParam, | |
1000 kValidArrowParam | |
1001 }; | |
1002 | |
987 explicit PreParserExpression(uint32_t expression_code) | 1003 explicit PreParserExpression(uint32_t expression_code) |
988 : code_(expression_code) {} | 1004 : code_(expression_code) {} |
989 | 1005 |
990 V8_INLINE bool IsValidArrowParams() const { | 1006 V8_INLINE ValidArrowParam IsValidArrowParams() const { |
rossberg
2015/04/10 14:02:56
A function named Is* is expected to return a bool,
conradw
2015/04/10 14:20:49
Done.
| |
991 return IsBinaryOperation() | 1007 if (IsBinaryOperation()) { |
992 ? IsValidArrowParamListField::decode(code_) | 1008 return IsValidArrowParamListField::decode(code_); |
993 : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); | 1009 } |
1010 if (!IsIdentifier()) { | |
1011 return kInvalidArrowParam; | |
1012 } | |
1013 PreParserIdentifier ident = AsIdentifier(); | |
1014 // A valid identifier can be an arrow function parameter | |
1015 // except for eval, arguments, yield, and reserved keywords. | |
1016 if (ident.IsEval() || ident.IsArguments() || | |
1017 ident.IsFutureStrictReserved()) { | |
1018 return kInvalidArrowParam; | |
1019 } | |
1020 // In strong mode, 'undefined' is similarly restricted. | |
1021 if (ident.IsUndefined()) { | |
1022 return kInvalidStrongArrowParam; | |
1023 } | |
1024 return kValidArrowParam; | |
994 } | 1025 } |
995 | 1026 |
996 // The first five bits are for the Type and Parenthesization. | 1027 // The first five bits are for the Type and Parenthesization. |
997 typedef BitField<Type, 0, 3> TypeField; | 1028 typedef BitField<Type, 0, 3> TypeField; |
998 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; | 1029 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; |
999 | 1030 |
1000 // The rest of the bits are interpreted depending on the value | 1031 // The rest of the bits are interpreted depending on the value |
1001 // of the Type field, so they can share the storage. | 1032 // of the Type field, so they can share the storage. |
1002 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> | 1033 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> |
1003 ExpressionTypeField; | 1034 ExpressionTypeField; |
1004 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; | 1035 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; |
1005 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 1036 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
1006 typedef BitField<bool, ParenthesizationField::kNext, 1> | 1037 typedef BitField<ValidArrowParam, ParenthesizationField::kNext, 2> |
1007 IsValidArrowParamListField; | 1038 IsValidArrowParamListField; |
1008 typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10> | 1039 typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10> |
1009 IdentifierTypeField; | 1040 IdentifierTypeField; |
1010 | 1041 |
1011 uint32_t code_; | 1042 uint32_t code_; |
1012 }; | 1043 }; |
1013 | 1044 |
1014 | 1045 |
1015 // PreParserExpressionList doesn't actually store the expressions because | 1046 // PreParserExpressionList doesn't actually store the expressions because |
1016 // PreParser doesn't need to. | 1047 // PreParser doesn't need to. |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1484 } | 1515 } |
1485 | 1516 |
1486 V8_INLINE PreParserStatementList | 1517 V8_INLINE PreParserStatementList |
1487 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, | 1518 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
1488 Variable* fvar, Token::Value fvar_init_op, | 1519 Variable* fvar, Token::Value fvar_init_op, |
1489 FunctionKind kind, bool* ok); | 1520 FunctionKind kind, bool* ok); |
1490 | 1521 |
1491 // Utility functions | 1522 // Utility functions |
1492 int DeclareArrowParametersFromExpression(PreParserExpression expression, | 1523 int DeclareArrowParametersFromExpression(PreParserExpression expression, |
1493 Scope* scope, | 1524 Scope* scope, |
1525 Scanner::Location* undefined_loc, | |
1494 Scanner::Location* dupe_loc, | 1526 Scanner::Location* dupe_loc, |
1495 bool* ok) { | 1527 bool* ok) { |
1496 // TODO(aperez): Detect duplicated identifiers in paramlists. | 1528 // TODO(aperez): Detect duplicated identifiers in paramlists. |
1497 *ok = expression.IsValidArrowParamList(); | 1529 *ok = expression.IsValidArrowParamList(scope, undefined_loc); |
1498 return 0; | 1530 return 0; |
1499 } | 1531 } |
1500 | 1532 |
1501 struct TemplateLiteralState {}; | 1533 struct TemplateLiteralState {}; |
1502 | 1534 |
1503 TemplateLiteralState OpenTemplateLiteral(int pos) { | 1535 TemplateLiteralState OpenTemplateLiteral(int pos) { |
1504 return TemplateLiteralState(); | 1536 return TemplateLiteralState(); |
1505 } | 1537 } |
1506 void AddTemplateSpan(TemplateLiteralState*, bool) {} | 1538 void AddTemplateSpan(TemplateLiteralState*, bool) {} |
1507 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} | 1539 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} |
(...skipping 1494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3002 ExpressionT params_ast, | 3034 ExpressionT params_ast, |
3003 bool* ok) { | 3035 bool* ok) { |
3004 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3036 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
3005 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3037 // ASI inserts `;` after arrow parameters if a line terminator is found. |
3006 // `=> ...` is never a valid expression, so report as syntax error. | 3038 // `=> ...` is never a valid expression, so report as syntax error. |
3007 // If next token is not `=>`, it's a syntax error anyways. | 3039 // If next token is not `=>`, it's a syntax error anyways. |
3008 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3040 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
3009 *ok = false; | 3041 *ok = false; |
3010 return this->EmptyExpression(); | 3042 return this->EmptyExpression(); |
3011 } | 3043 } |
3012 | |
rossberg
2015/04/10 14:02:56
Accidental line deletion?
conradw
2015/04/10 14:20:49
Done.
| |
3013 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); | 3044 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); |
3014 typename Traits::Type::StatementList body; | 3045 typename Traits::Type::StatementList body; |
3015 int num_parameters = -1; | 3046 int num_parameters = -1; |
3016 int materialized_literal_count = -1; | 3047 int materialized_literal_count = -1; |
3017 int expected_property_count = -1; | 3048 int expected_property_count = -1; |
3018 int handler_count = 0; | 3049 int handler_count = 0; |
3019 Scanner::Location super_loc; | 3050 Scanner::Location super_loc; |
3020 | 3051 |
3021 { | 3052 { |
3022 typename Traits::Type::Factory function_factory(ast_value_factory()); | 3053 typename Traits::Type::Factory function_factory(ast_value_factory()); |
3023 FunctionState function_state(&function_state_, &scope_, scope, | 3054 FunctionState function_state(&function_state_, &scope_, scope, |
3024 kArrowFunction, &function_factory); | 3055 kArrowFunction, &function_factory); |
3025 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | 3056 Scanner::Location undefined_loc = Scanner::Location::invalid(); |
3026 // TODO(arv): Pass in eval_args_error_loc and reserved_loc here. | 3057 Scanner::Location dupe_loc = Scanner::Location::invalid(); |
3058 // TODO(arv): Pass in eval_args_loc and reserved_loc here. | |
3027 num_parameters = Traits::DeclareArrowParametersFromExpression( | 3059 num_parameters = Traits::DeclareArrowParametersFromExpression( |
3028 params_ast, scope_, &dupe_error_loc, ok); | 3060 params_ast, scope_, &undefined_loc, &dupe_loc, ok); |
3029 if (!*ok) { | 3061 if (!*ok) { |
3030 ReportMessageAt( | 3062 ReportMessageAt( |
3031 Scanner::Location(start_pos, scanner()->location().beg_pos), | 3063 Scanner::Location(start_pos, scanner()->location().beg_pos), |
3032 "malformed_arrow_function_parameter_list"); | 3064 "malformed_arrow_function_parameter_list"); |
3033 return this->EmptyExpression(); | 3065 return this->EmptyExpression(); |
3034 } | 3066 } |
3035 | 3067 |
3068 if (undefined_loc.IsValid()) { | |
3069 // Workaround for preparser not keeping track of positions. | |
3070 undefined_loc = Scanner::Location(start_pos, | |
3071 scanner()->location().end_pos); | |
3072 } | |
3036 if (num_parameters > Code::kMaxArguments) { | 3073 if (num_parameters > Code::kMaxArguments) { |
3037 ReportMessageAt(Scanner::Location(params_ast->position(), position()), | 3074 ReportMessageAt(Scanner::Location(params_ast->position(), position()), |
3038 "too_many_parameters"); | 3075 "too_many_parameters"); |
3039 *ok = false; | 3076 *ok = false; |
3040 return this->EmptyExpression(); | 3077 return this->EmptyExpression(); |
3041 } | 3078 } |
3042 | 3079 |
3043 Expect(Token::ARROW, CHECK_OK); | 3080 Expect(Token::ARROW, CHECK_OK); |
3044 | 3081 |
3045 if (peek() == Token::LBRACE) { | 3082 if (peek() == Token::LBRACE) { |
3046 // Multiple statemente body | 3083 // Multiple statement body |
3047 Consume(Token::LBRACE); | 3084 Consume(Token::LBRACE); |
3048 bool is_lazily_parsed = | 3085 bool is_lazily_parsed = |
3049 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); | 3086 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); |
3050 if (is_lazily_parsed) { | 3087 if (is_lazily_parsed) { |
3051 body = this->NewStatementList(0, zone()); | 3088 body = this->NewStatementList(0, zone()); |
3052 this->SkipLazyFunctionBody(this->EmptyIdentifier(), | 3089 this->SkipLazyFunctionBody(this->EmptyIdentifier(), |
3053 &materialized_literal_count, | 3090 &materialized_literal_count, |
3054 &expected_property_count, CHECK_OK); | 3091 &expected_property_count, CHECK_OK); |
3055 } else { | 3092 } else { |
3056 body = this->ParseEagerFunctionBody( | 3093 body = this->ParseEagerFunctionBody( |
(...skipping 14 matching lines...) Expand all Loading... | |
3071 materialized_literal_count = function_state.materialized_literal_count(); | 3108 materialized_literal_count = function_state.materialized_literal_count(); |
3072 expected_property_count = function_state.expected_property_count(); | 3109 expected_property_count = function_state.expected_property_count(); |
3073 handler_count = function_state.handler_count(); | 3110 handler_count = function_state.handler_count(); |
3074 } | 3111 } |
3075 super_loc = function_state.super_call_location(); | 3112 super_loc = function_state.super_call_location(); |
3076 | 3113 |
3077 scope->set_start_position(start_pos); | 3114 scope->set_start_position(start_pos); |
3078 scope->set_end_position(scanner()->location().end_pos); | 3115 scope->set_end_position(scanner()->location().end_pos); |
3079 | 3116 |
3080 // Arrow function *parameter lists* are always checked as in strict mode. | 3117 // Arrow function *parameter lists* are always checked as in strict mode. |
3081 // TODO(arv): eval_args_error_loc, undefined_error_loc, and reserved_loc | 3118 // TODO(arv): eval_args_loc and reserved_loc needs to be set by |
3082 // needs to be set by DeclareArrowParametersFromExpression. | 3119 // DeclareArrowParametersFromExpression. |
3083 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); | 3120 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(); | 3121 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
3086 const bool use_strict_params = true; | 3122 const bool use_strict_params = true; |
3087 this->CheckFunctionParameterNames(language_mode(), use_strict_params, | 3123 this->CheckFunctionParameterNames(language_mode(), use_strict_params, |
3088 eval_args_error_loc, undefined_error_loc, | 3124 eval_args_loc, undefined_loc, dupe_loc, |
3089 dupe_error_loc, reserved_loc, CHECK_OK); | 3125 reserved_loc, CHECK_OK); |
3090 | 3126 |
3091 // Validate strict mode. | 3127 // Validate strict mode. |
3092 if (is_strict(language_mode())) { | 3128 if (is_strict(language_mode())) { |
3093 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos, | 3129 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos, |
3094 CHECK_OK); | 3130 CHECK_OK); |
3095 this->CheckConflictingVarDeclarations(scope, CHECK_OK); | 3131 this->CheckConflictingVarDeclarations(scope, CHECK_OK); |
3096 } | 3132 } |
3097 } | 3133 } |
3098 | 3134 |
3099 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3135 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3292 *ok = false; | 3328 *ok = false; |
3293 return; | 3329 return; |
3294 } | 3330 } |
3295 has_seen_constructor_ = true; | 3331 has_seen_constructor_ = true; |
3296 return; | 3332 return; |
3297 } | 3333 } |
3298 } | 3334 } |
3299 } } // v8::internal | 3335 } } // v8::internal |
3300 | 3336 |
3301 #endif // V8_PREPARSER_H | 3337 #endif // V8_PREPARSER_H |
OLD | NEW |