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 | 520 |
521 typename Traits::Type::Factory* factory() { | 521 typename Traits::Type::Factory* factory() { |
522 return function_state_->factory(); | 522 return function_state_->factory(); |
523 } | 523 } |
524 | 524 |
525 LanguageMode language_mode() { return scope_->language_mode(); } | 525 LanguageMode language_mode() { return scope_->language_mode(); } |
526 bool is_generator() const { return function_state_->is_generator(); } | 526 bool is_generator() const { return function_state_->is_generator(); } |
527 | 527 |
528 // Report syntax errors. | 528 // Report syntax errors. |
529 void ReportMessage(const char* message, const char* arg = NULL, | 529 void ReportMessage(const char* message, const char* arg = NULL, |
530 bool is_reference_error = false) { | 530 ParseErrorType error_type = kSyntaxError) { |
531 Scanner::Location source_location = scanner()->location(); | 531 Scanner::Location source_location = scanner()->location(); |
532 Traits::ReportMessageAt(source_location, message, arg, is_reference_error); | 532 Traits::ReportMessageAt(source_location, message, arg, error_type); |
533 } | 533 } |
534 | 534 |
535 void ReportMessageAt(Scanner::Location location, const char* message, | 535 void ReportMessageAt(Scanner::Location location, const char* message, |
536 bool is_reference_error = false) { | 536 ParseErrorType error_type = kSyntaxError) { |
537 Traits::ReportMessageAt(location, message, | 537 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0), |
538 reinterpret_cast<const char*>(0), | 538 error_type); |
539 is_reference_error); | |
540 } | 539 } |
541 | 540 |
542 void ReportUnexpectedToken(Token::Value token); | 541 void ReportUnexpectedToken(Token::Value token); |
543 | 542 |
544 // Recursive descent functions: | 543 // Recursive descent functions: |
545 | 544 |
546 // Parses an identifier that is valid for the current scope, in particular it | 545 // Parses an identifier that is valid for the current scope, in particular it |
547 // fails on strict mode future reserved keywords in a strict scope. If | 546 // fails on strict mode future reserved keywords in a strict scope. If |
548 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or | 547 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or |
549 // "arguments" as identifier even in strict mode (this is needed in cases like | 548 // "arguments" as identifier even in strict mode (this is needed in cases like |
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1338 PreParserExpression NewThrowSyntaxError( | 1337 PreParserExpression NewThrowSyntaxError( |
1339 const char* type, Handle<Object> arg, int pos) { | 1338 const char* type, Handle<Object> arg, int pos) { |
1340 return PreParserExpression::Default(); | 1339 return PreParserExpression::Default(); |
1341 } | 1340 } |
1342 PreParserExpression NewThrowTypeError( | 1341 PreParserExpression NewThrowTypeError( |
1343 const char* type, Handle<Object> arg, int pos) { | 1342 const char* type, Handle<Object> arg, int pos) { |
1344 return PreParserExpression::Default(); | 1343 return PreParserExpression::Default(); |
1345 } | 1344 } |
1346 | 1345 |
1347 // Reporting errors. | 1346 // Reporting errors. |
1348 void ReportMessageAt(Scanner::Location location, | 1347 void ReportMessageAt(Scanner::Location location, const char* message, |
1349 const char* message, | |
1350 const char* arg = NULL, | 1348 const char* arg = NULL, |
1351 bool is_reference_error = false); | 1349 ParseErrorType error_type = kSyntaxError); |
1352 void ReportMessageAt(int start_pos, | 1350 void ReportMessageAt(int start_pos, int end_pos, const char* message, |
1353 int end_pos, | |
1354 const char* message, | |
1355 const char* arg = NULL, | 1351 const char* arg = NULL, |
1356 bool is_reference_error = false); | 1352 ParseErrorType error_type = kSyntaxError); |
1357 | 1353 |
1358 // "null" return type creators. | 1354 // "null" return type creators. |
1359 static PreParserIdentifier EmptyIdentifier() { | 1355 static PreParserIdentifier EmptyIdentifier() { |
1360 return PreParserIdentifier::Default(); | 1356 return PreParserIdentifier::Default(); |
1361 } | 1357 } |
1362 static PreParserIdentifier EmptyIdentifierString() { | 1358 static PreParserIdentifier EmptyIdentifierString() { |
1363 return PreParserIdentifier::Default(); | 1359 return PreParserIdentifier::Default(); |
1364 } | 1360 } |
1365 static PreParserExpression EmptyExpression() { | 1361 static PreParserExpression EmptyExpression() { |
1366 return PreParserExpression::Default(); | 1362 return PreParserExpression::Default(); |
(...skipping 1614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2981 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); | 2977 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); |
2982 next = peek(); | 2978 next = peek(); |
2983 if (next == Token::EOS) { | 2979 if (next == Token::EOS) { |
2984 ReportMessageAt(Scanner::Location(start, peek_position()), | 2980 ReportMessageAt(Scanner::Location(start, peek_position()), |
2985 "unterminated_template"); | 2981 "unterminated_template"); |
2986 *ok = false; | 2982 *ok = false; |
2987 return Traits::EmptyExpression(); | 2983 return Traits::EmptyExpression(); |
2988 } else if (next == Token::ILLEGAL) { | 2984 } else if (next == Token::ILLEGAL) { |
2989 Traits::ReportMessageAt( | 2985 Traits::ReportMessageAt( |
2990 Scanner::Location(position() + 1, peek_position()), | 2986 Scanner::Location(position() + 1, peek_position()), |
2991 "unexpected_token", "ILLEGAL", false); | 2987 "unexpected_token", "ILLEGAL", kSyntaxError); |
2992 *ok = false; | 2988 *ok = false; |
2993 return Traits::EmptyExpression(); | 2989 return Traits::EmptyExpression(); |
2994 } | 2990 } |
2995 | 2991 |
2996 int expr_pos = peek_position(); | 2992 int expr_pos = peek_position(); |
2997 ExpressionT expression = this->ParseExpression(true, CHECK_OK); | 2993 ExpressionT expression = this->ParseExpression(true, CHECK_OK); |
2998 Traits::AddTemplateExpression(&ts, expression); | 2994 Traits::AddTemplateExpression(&ts, expression); |
2999 | 2995 |
3000 if (peek() != Token::RBRACE) { | 2996 if (peek() != Token::RBRACE) { |
3001 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), | 2997 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), |
3002 "unterminated_template_expr"); | 2998 "unterminated_template_expr"); |
3003 *ok = false; | 2999 *ok = false; |
3004 return Traits::EmptyExpression(); | 3000 return Traits::EmptyExpression(); |
3005 } | 3001 } |
3006 | 3002 |
3007 // If we didn't die parsing that expression, our next token should be a | 3003 // If we didn't die parsing that expression, our next token should be a |
3008 // TEMPLATE_SPAN or TEMPLATE_TAIL. | 3004 // TEMPLATE_SPAN or TEMPLATE_TAIL. |
3009 next = scanner()->ScanTemplateContinuation(); | 3005 next = scanner()->ScanTemplateContinuation(); |
3010 Next(); | 3006 Next(); |
3011 pos = position(); | 3007 pos = position(); |
3012 | 3008 |
3013 if (next == Token::EOS) { | 3009 if (next == Token::EOS) { |
3014 ReportMessageAt(Scanner::Location(start, pos), "unterminated_template"); | 3010 ReportMessageAt(Scanner::Location(start, pos), "unterminated_template"); |
3015 *ok = false; | 3011 *ok = false; |
3016 return Traits::EmptyExpression(); | 3012 return Traits::EmptyExpression(); |
3017 } else if (next == Token::ILLEGAL) { | 3013 } else if (next == Token::ILLEGAL) { |
3018 Traits::ReportMessageAt( | 3014 Traits::ReportMessageAt( |
3019 Scanner::Location(position() + 1, peek_position()), | 3015 Scanner::Location(position() + 1, peek_position()), |
3020 "unexpected_token", "ILLEGAL", false); | 3016 "unexpected_token", "ILLEGAL", kSyntaxError); |
3021 *ok = false; | 3017 *ok = false; |
3022 return Traits::EmptyExpression(); | 3018 return Traits::EmptyExpression(); |
3023 } | 3019 } |
3024 | 3020 |
3025 Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL); | 3021 Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL); |
3026 } while (next == Token::TEMPLATE_SPAN); | 3022 } while (next == Token::TEMPLATE_SPAN); |
3027 | 3023 |
3028 DCHECK_EQ(next, Token::TEMPLATE_TAIL); | 3024 DCHECK_EQ(next, Token::TEMPLATE_TAIL); |
3029 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); | 3025 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); |
3030 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. | 3026 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. |
3031 return Traits::CloseTemplateLiteral(&ts, start, tag); | 3027 return Traits::CloseTemplateLiteral(&ts, start, tag); |
3032 } | 3028 } |
3033 | 3029 |
3034 | 3030 |
3035 template <typename Traits> | 3031 template <typename Traits> |
3036 typename ParserBase<Traits>::ExpressionT ParserBase< | 3032 typename ParserBase<Traits>::ExpressionT ParserBase< |
3037 Traits>::CheckAndRewriteReferenceExpression(ExpressionT expression, | 3033 Traits>::CheckAndRewriteReferenceExpression(ExpressionT expression, |
3038 Scanner::Location location, | 3034 Scanner::Location location, |
3039 const char* message, bool* ok) { | 3035 const char* message, bool* ok) { |
3040 if (is_strict(language_mode()) && this->IsIdentifier(expression) && | 3036 if (is_strict(language_mode()) && this->IsIdentifier(expression) && |
3041 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 3037 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
3042 this->ReportMessageAt(location, "strict_eval_arguments", false); | 3038 this->ReportMessageAt(location, "strict_eval_arguments", kSyntaxError); |
3043 *ok = false; | 3039 *ok = false; |
3044 return this->EmptyExpression(); | 3040 return this->EmptyExpression(); |
3045 } else if (expression->IsValidReferenceExpression()) { | 3041 } else if (expression->IsValidReferenceExpression()) { |
3046 return expression; | 3042 return expression; |
3047 } else if (expression->IsCall()) { | 3043 } else if (expression->IsCall()) { |
3048 // If it is a call, make it a runtime error for legacy web compatibility. | 3044 // If it is a call, make it a runtime error for legacy web compatibility. |
3049 // Rewrite `expr' to `expr[throw ReferenceError]'. | 3045 // Rewrite `expr' to `expr[throw ReferenceError]'. |
3050 int pos = location.beg_pos; | 3046 int pos = location.beg_pos; |
3051 ExpressionT error = this->NewThrowReferenceError(message, pos); | 3047 ExpressionT error = this->NewThrowReferenceError(message, pos); |
3052 return factory()->NewProperty(expression, error, pos); | 3048 return factory()->NewProperty(expression, error, pos); |
3053 } else { | 3049 } else { |
3054 this->ReportMessageAt(location, message, true); | 3050 this->ReportMessageAt(location, message, kReferenceError); |
3055 *ok = false; | 3051 *ok = false; |
3056 return this->EmptyExpression(); | 3052 return this->EmptyExpression(); |
3057 } | 3053 } |
3058 } | 3054 } |
3059 | 3055 |
3060 | 3056 |
3061 #undef CHECK_OK | 3057 #undef CHECK_OK |
3062 #undef CHECK_OK_CUSTOM | 3058 #undef CHECK_OK_CUSTOM |
3063 | 3059 |
3064 | 3060 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3108 *ok = false; | 3104 *ok = false; |
3109 return; | 3105 return; |
3110 } | 3106 } |
3111 has_seen_constructor_ = true; | 3107 has_seen_constructor_ = true; |
3112 return; | 3108 return; |
3113 } | 3109 } |
3114 } | 3110 } |
3115 } } // v8::internal | 3111 } } // v8::internal |
3116 | 3112 |
3117 #endif // V8_PREPARSER_H | 3113 #endif // V8_PREPARSER_H |
OLD | NEW |