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_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
7 | 7 |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/hashmap.h" | 10 #include "src/hashmap.h" |
(...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
793 int formals_end_pos, bool* ok); | 793 int formals_end_pos, bool* ok); |
794 | 794 |
795 bool IsNextLetKeyword(); | 795 bool IsNextLetKeyword(); |
796 | 796 |
797 // Checks if the expression is a valid reference expression (e.g., on the | 797 // Checks if the expression is a valid reference expression (e.g., on the |
798 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 798 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
799 // we allow calls for web compatibility and rewrite them to a runtime throw. | 799 // we allow calls for web compatibility and rewrite them to a runtime throw. |
800 ExpressionT CheckAndRewriteReferenceExpression( | 800 ExpressionT CheckAndRewriteReferenceExpression( |
801 ExpressionT expression, int beg_pos, int end_pos, | 801 ExpressionT expression, int beg_pos, int end_pos, |
802 MessageTemplate::Template message, bool* ok); | 802 MessageTemplate::Template message, bool* ok); |
803 ExpressionT ClassifyAndRewriteReferenceExpression( | |
804 ExpressionClassifier* classifier, ExpressionT expression, int beg_pos, | |
805 int end_pos, MessageTemplate::Template message, | |
806 ParseErrorType type = kSyntaxError); | |
807 ExpressionT CheckAndRewriteReferenceExpression( | 803 ExpressionT CheckAndRewriteReferenceExpression( |
808 ExpressionT expression, int beg_pos, int end_pos, | 804 ExpressionT expression, int beg_pos, int end_pos, |
809 MessageTemplate::Template message, ParseErrorType type, bool* ok); | 805 MessageTemplate::Template message, ParseErrorType type, bool* ok); |
810 | 806 |
811 bool IsValidReferenceExpression(ExpressionT expression); | 807 bool IsValidReferenceExpression(ExpressionT expression); |
812 | 808 |
813 bool IsAssignableIdentifier(ExpressionT expression) { | 809 bool IsAssignableIdentifier(ExpressionT expression) { |
814 if (!Traits::IsIdentifier(expression)) return false; | 810 if (!Traits::IsIdentifier(expression)) return false; |
815 if (is_strict(language_mode()) && | 811 if (is_strict(language_mode()) && |
816 Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) { | 812 Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) { |
(...skipping 2166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2983 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos, | 2979 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos, |
2984 message, kReferenceError, ok); | 2980 message, kReferenceError, ok); |
2985 } | 2981 } |
2986 | 2982 |
2987 | 2983 |
2988 template <typename Traits> | 2984 template <typename Traits> |
2989 typename ParserBase<Traits>::ExpressionT | 2985 typename ParserBase<Traits>::ExpressionT |
2990 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | 2986 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
2991 ExpressionT expression, int beg_pos, int end_pos, | 2987 ExpressionT expression, int beg_pos, int end_pos, |
2992 MessageTemplate::Template message, ParseErrorType type, bool* ok) { | 2988 MessageTemplate::Template message, ParseErrorType type, bool* ok) { |
2993 ExpressionClassifier classifier(this); | 2989 if (this->IsIdentifier(expression) && is_strict(language_mode()) && |
2994 ExpressionT result = ClassifyAndRewriteReferenceExpression( | 2990 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
2995 &classifier, expression, beg_pos, end_pos, message, type); | 2991 ReportMessageAt(Scanner::Location(beg_pos, end_pos), |
2996 ValidateExpression(&classifier, ok); | 2992 MessageTemplate::kStrictEvalArguments, kSyntaxError); |
2997 if (!*ok) return this->EmptyExpression(); | 2993 *ok = false; |
2998 return result; | 2994 return this->EmptyExpression(); |
| 2995 } |
| 2996 if (expression->IsValidReferenceExpression()) { |
| 2997 return expression; |
| 2998 } |
| 2999 if (expression->IsCall()) { |
| 3000 // If it is a call, make it a runtime error for legacy web compatibility. |
| 3001 // Rewrite `expr' to `expr[throw ReferenceError]'. |
| 3002 ExpressionT error = this->NewThrowReferenceError(message, beg_pos); |
| 3003 return factory()->NewProperty(expression, error, beg_pos); |
| 3004 } |
| 3005 ReportMessageAt(Scanner::Location(beg_pos, end_pos), message, type); |
| 3006 *ok = false; |
| 3007 return this->EmptyExpression(); |
2999 } | 3008 } |
3000 | 3009 |
3001 | 3010 |
3002 template <typename Traits> | |
3003 typename ParserBase<Traits>::ExpressionT | |
3004 ParserBase<Traits>::ClassifyAndRewriteReferenceExpression( | |
3005 ExpressionClassifier* classifier, ExpressionT expression, int beg_pos, | |
3006 int end_pos, MessageTemplate::Template message, ParseErrorType type) { | |
3007 Scanner::Location location(beg_pos, end_pos); | |
3008 if (this->IsIdentifier(expression)) { | |
3009 if (is_strict(language_mode()) && | |
3010 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | |
3011 classifier->RecordExpressionError( | |
3012 location, MessageTemplate::kStrictEvalArguments, kSyntaxError); | |
3013 return expression; | |
3014 } | |
3015 } | |
3016 if (expression->IsValidReferenceExpression()) { | |
3017 return expression; | |
3018 } else if (expression->IsCall()) { | |
3019 // If it is a call, make it a runtime error for legacy web compatibility. | |
3020 // Rewrite `expr' to `expr[throw ReferenceError]'. | |
3021 int pos = location.beg_pos; | |
3022 ExpressionT error = this->NewThrowReferenceError(message, pos); | |
3023 return factory()->NewProperty(expression, error, pos); | |
3024 } else { | |
3025 classifier->RecordExpressionError(location, message, type); | |
3026 return expression; | |
3027 } | |
3028 } | |
3029 | |
3030 | |
3031 template <typename Traits> | 3011 template <typename Traits> |
3032 bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) { | 3012 bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) { |
3033 return this->IsAssignableIdentifier(expression) || expression->IsProperty(); | 3013 return this->IsAssignableIdentifier(expression) || expression->IsProperty(); |
3034 } | 3014 } |
3035 | 3015 |
3036 | 3016 |
3037 template <typename Traits> | 3017 template <typename Traits> |
3038 void ParserBase<Traits>::CheckDestructuringElement( | 3018 void ParserBase<Traits>::CheckDestructuringElement( |
3039 ExpressionT expression, ExpressionClassifier* classifier, int begin, | 3019 ExpressionT expression, ExpressionClassifier* classifier, int begin, |
3040 int end) { | 3020 int end) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3103 has_seen_constructor_ = true; | 3083 has_seen_constructor_ = true; |
3104 return; | 3084 return; |
3105 } | 3085 } |
3106 } | 3086 } |
3107 | 3087 |
3108 | 3088 |
3109 } // namespace internal | 3089 } // namespace internal |
3110 } // namespace v8 | 3090 } // namespace v8 |
3111 | 3091 |
3112 #endif // V8_PARSING_PARSER_BASE_H | 3092 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |