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/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 function_literal_id_(0), | 219 function_literal_id_(0), |
220 allow_natives_(false), | 220 allow_natives_(false), |
221 allow_tailcalls_(false), | 221 allow_tailcalls_(false), |
222 allow_harmony_do_expressions_(false), | 222 allow_harmony_do_expressions_(false), |
223 allow_harmony_function_sent_(false), | 223 allow_harmony_function_sent_(false), |
224 allow_harmony_restrictive_generators_(false), | 224 allow_harmony_restrictive_generators_(false), |
225 allow_harmony_trailing_commas_(false), | 225 allow_harmony_trailing_commas_(false), |
226 allow_harmony_class_fields_(false), | 226 allow_harmony_class_fields_(false), |
227 allow_harmony_object_rest_spread_(false), | 227 allow_harmony_object_rest_spread_(false), |
228 allow_harmony_dynamic_import_(false), | 228 allow_harmony_dynamic_import_(false), |
229 allow_harmony_async_iteration_(false) {} | 229 allow_harmony_async_iteration_(false), |
| 230 allow_harmony_template_escapes_(false) {} |
230 | 231 |
231 #define ALLOW_ACCESSORS(name) \ | 232 #define ALLOW_ACCESSORS(name) \ |
232 bool allow_##name() const { return allow_##name##_; } \ | 233 bool allow_##name() const { return allow_##name##_; } \ |
233 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 234 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
234 | 235 |
235 ALLOW_ACCESSORS(natives); | 236 ALLOW_ACCESSORS(natives); |
236 ALLOW_ACCESSORS(tailcalls); | 237 ALLOW_ACCESSORS(tailcalls); |
237 ALLOW_ACCESSORS(harmony_do_expressions); | 238 ALLOW_ACCESSORS(harmony_do_expressions); |
238 ALLOW_ACCESSORS(harmony_function_sent); | 239 ALLOW_ACCESSORS(harmony_function_sent); |
239 ALLOW_ACCESSORS(harmony_restrictive_generators); | 240 ALLOW_ACCESSORS(harmony_restrictive_generators); |
240 ALLOW_ACCESSORS(harmony_trailing_commas); | 241 ALLOW_ACCESSORS(harmony_trailing_commas); |
241 ALLOW_ACCESSORS(harmony_class_fields); | 242 ALLOW_ACCESSORS(harmony_class_fields); |
242 ALLOW_ACCESSORS(harmony_object_rest_spread); | 243 ALLOW_ACCESSORS(harmony_object_rest_spread); |
243 ALLOW_ACCESSORS(harmony_dynamic_import); | 244 ALLOW_ACCESSORS(harmony_dynamic_import); |
244 ALLOW_ACCESSORS(harmony_async_iteration); | 245 ALLOW_ACCESSORS(harmony_async_iteration); |
| 246 ALLOW_ACCESSORS(harmony_template_escapes); |
245 | 247 |
246 #undef ALLOW_ACCESSORS | 248 #undef ALLOW_ACCESSORS |
247 | 249 |
248 uintptr_t stack_limit() const { return stack_limit_; } | 250 uintptr_t stack_limit() const { return stack_limit_; } |
249 | 251 |
250 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } | 252 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } |
251 | 253 |
252 void set_default_eager_compile_hint( | 254 void set_default_eager_compile_hint( |
253 FunctionLiteral::EagerCompileHint eager_compile_hint) { | 255 FunctionLiteral::EagerCompileHint eager_compile_hint) { |
254 default_eager_compile_hint_ = eager_compile_hint; | 256 default_eager_compile_hint_ = eager_compile_hint; |
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 return true; | 811 return true; |
810 } | 812 } |
811 return false; | 813 return false; |
812 } | 814 } |
813 | 815 |
814 bool PeekInOrOf() { | 816 bool PeekInOrOf() { |
815 return peek() == Token::IN || PeekContextualKeyword(CStrVector("of")); | 817 return peek() == Token::IN || PeekContextualKeyword(CStrVector("of")); |
816 } | 818 } |
817 | 819 |
818 // Checks whether an octal literal was last seen between beg_pos and end_pos. | 820 // Checks whether an octal literal was last seen between beg_pos and end_pos. |
819 // If so, reports an error. Only called for strict mode and template strings. | 821 // Only called for strict mode strings. |
820 void CheckOctalLiteral(int beg_pos, int end_pos, bool is_template, bool* ok) { | 822 void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
821 Scanner::Location octal = scanner()->octal_position(); | 823 Scanner::Location octal = scanner()->octal_position(); |
822 if (octal.IsValid() && beg_pos <= octal.beg_pos && | 824 if (octal.IsValid() && beg_pos <= octal.beg_pos && |
823 octal.end_pos <= end_pos) { | 825 octal.end_pos <= end_pos) { |
824 MessageTemplate::Template message = | 826 MessageTemplate::Template message = scanner()->octal_message(); |
825 is_template ? MessageTemplate::kTemplateOctalLiteral | |
826 : scanner()->octal_message(); | |
827 DCHECK_NE(message, MessageTemplate::kNone); | 827 DCHECK_NE(message, MessageTemplate::kNone); |
828 impl()->ReportMessageAt(octal, message); | 828 impl()->ReportMessageAt(octal, message); |
829 scanner()->clear_octal_position(); | 829 scanner()->clear_octal_position(); |
830 if (message == MessageTemplate::kStrictDecimalWithLeadingZero) { | 830 if (message == MessageTemplate::kStrictDecimalWithLeadingZero) { |
831 impl()->CountUsage(v8::Isolate::kDecimalWithLeadingZeroInStrictMode); | 831 impl()->CountUsage(v8::Isolate::kDecimalWithLeadingZeroInStrictMode); |
832 } | 832 } |
833 *ok = false; | 833 *ok = false; |
834 } | 834 } |
835 } | 835 } |
836 | 836 |
837 inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 837 // Checks if an octal literal or an invalid hex or unicode escape sequence |
838 CheckOctalLiteral(beg_pos, end_pos, false, ok); | 838 // appears in a template literal. In the presence of such, either |
839 } | 839 // returns false or reports an error, depending on should_throw. Otherwise |
| 840 // returns true. |
| 841 inline bool CheckTemplateEscapes(bool should_throw, bool* ok) { |
| 842 if (!scanner()->has_invalid_template_escape()) { |
| 843 return true; |
| 844 } |
840 | 845 |
841 inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 846 // Handle error case(s) |
842 CheckOctalLiteral(beg_pos, end_pos, true, ok); | 847 if (should_throw) { |
| 848 impl()->ReportMessageAt(scanner()->invalid_template_escape_location(), |
| 849 scanner()->invalid_template_escape_message()); |
| 850 *ok = false; |
| 851 } |
| 852 scanner()->clear_invalid_template_escape(); |
| 853 return false; |
843 } | 854 } |
844 | 855 |
845 void CheckDestructuringElement(ExpressionT element, int beg_pos, int end_pos); | 856 void CheckDestructuringElement(ExpressionT element, int beg_pos, int end_pos); |
846 | 857 |
847 // Checking the name of a function literal. This has to be done after parsing | 858 // Checking the name of a function literal. This has to be done after parsing |
848 // the function, since the function can declare itself strict. | 859 // the function, since the function can declare itself strict. |
849 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name, | 860 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name, |
850 FunctionNameValidity function_name_validity, | 861 FunctionNameValidity function_name_validity, |
851 const Scanner::Location& function_name_loc, bool* ok) { | 862 const Scanner::Location& function_name_loc, bool* ok) { |
852 if (function_name_validity == kSkipFunctionNameCheck) return; | 863 if (function_name_validity == kSkipFunctionNameCheck) return; |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1131 const FormalParametersT& parameters, | 1142 const FormalParametersT& parameters, |
1132 bool* ok); | 1143 bool* ok); |
1133 void ParseAsyncFunctionBody(Scope* scope, StatementListT body, | 1144 void ParseAsyncFunctionBody(Scope* scope, StatementListT body, |
1134 FunctionKind kind, FunctionBodyType type, | 1145 FunctionKind kind, FunctionBodyType type, |
1135 bool accept_IN, int pos, bool* ok); | 1146 bool accept_IN, int pos, bool* ok); |
1136 ExpressionT ParseAsyncFunctionLiteral(bool* ok); | 1147 ExpressionT ParseAsyncFunctionLiteral(bool* ok); |
1137 ExpressionT ParseClassLiteral(IdentifierT name, | 1148 ExpressionT ParseClassLiteral(IdentifierT name, |
1138 Scanner::Location class_name_location, | 1149 Scanner::Location class_name_location, |
1139 bool name_is_strict_reserved, | 1150 bool name_is_strict_reserved, |
1140 int class_token_pos, bool* ok); | 1151 int class_token_pos, bool* ok); |
1141 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 1152 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool tagged, |
| 1153 bool* ok); |
1142 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 1154 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
1143 ExpressionT ParseDynamicImportExpression(bool* ok); | 1155 ExpressionT ParseDynamicImportExpression(bool* ok); |
1144 ExpressionT ParseNewTargetExpression(bool* ok); | 1156 ExpressionT ParseNewTargetExpression(bool* ok); |
1145 | 1157 |
1146 void ParseFormalParameter(FormalParametersT* parameters, bool* ok); | 1158 void ParseFormalParameter(FormalParametersT* parameters, bool* ok); |
1147 void ParseFormalParameterList(FormalParametersT* parameters, bool* ok); | 1159 void ParseFormalParameterList(FormalParametersT* parameters, bool* ok); |
1148 void CheckArityRestrictions(int param_count, FunctionKind function_type, | 1160 void CheckArityRestrictions(int param_count, FunctionKind function_type, |
1149 bool has_rest, int formals_start_pos, | 1161 bool has_rest, int formals_start_pos, |
1150 int formals_end_pos, bool* ok); | 1162 int formals_end_pos, bool* ok); |
1151 | 1163 |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1442 bool allow_natives_; | 1454 bool allow_natives_; |
1443 bool allow_tailcalls_; | 1455 bool allow_tailcalls_; |
1444 bool allow_harmony_do_expressions_; | 1456 bool allow_harmony_do_expressions_; |
1445 bool allow_harmony_function_sent_; | 1457 bool allow_harmony_function_sent_; |
1446 bool allow_harmony_restrictive_generators_; | 1458 bool allow_harmony_restrictive_generators_; |
1447 bool allow_harmony_trailing_commas_; | 1459 bool allow_harmony_trailing_commas_; |
1448 bool allow_harmony_class_fields_; | 1460 bool allow_harmony_class_fields_; |
1449 bool allow_harmony_object_rest_spread_; | 1461 bool allow_harmony_object_rest_spread_; |
1450 bool allow_harmony_dynamic_import_; | 1462 bool allow_harmony_dynamic_import_; |
1451 bool allow_harmony_async_iteration_; | 1463 bool allow_harmony_async_iteration_; |
| 1464 bool allow_harmony_template_escapes_; |
1452 | 1465 |
1453 friend class DiscardableZoneScope; | 1466 friend class DiscardableZoneScope; |
1454 }; | 1467 }; |
1455 | 1468 |
1456 template <typename Impl> | 1469 template <typename Impl> |
1457 ParserBase<Impl>::FunctionState::FunctionState( | 1470 ParserBase<Impl>::FunctionState::FunctionState( |
1458 FunctionState** function_state_stack, Scope** scope_stack, | 1471 FunctionState** function_state_stack, Scope** scope_stack, |
1459 DeclarationScope* scope) | 1472 DeclarationScope* scope) |
1460 : BlockState(scope_stack, scope), | 1473 : BlockState(scope_stack, scope), |
1461 next_materialized_literal_index_(0), | 1474 next_materialized_literal_index_(0), |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1810 CHECK_OK); | 1823 CHECK_OK); |
1811 class_name_location = scanner()->location(); | 1824 class_name_location = scanner()->location(); |
1812 } | 1825 } |
1813 return ParseClassLiteral(name, class_name_location, | 1826 return ParseClassLiteral(name, class_name_location, |
1814 is_strict_reserved_name, class_token_pos, ok); | 1827 is_strict_reserved_name, class_token_pos, ok); |
1815 } | 1828 } |
1816 | 1829 |
1817 case Token::TEMPLATE_SPAN: | 1830 case Token::TEMPLATE_SPAN: |
1818 case Token::TEMPLATE_TAIL: | 1831 case Token::TEMPLATE_TAIL: |
1819 BindingPatternUnexpectedToken(); | 1832 BindingPatternUnexpectedToken(); |
1820 return ParseTemplateLiteral(impl()->NoTemplateTag(), beg_pos, ok); | 1833 return ParseTemplateLiteral(impl()->NoTemplateTag(), beg_pos, false, ok); |
1821 | 1834 |
1822 case Token::MOD: | 1835 case Token::MOD: |
1823 if (allow_natives() || extension_ != NULL) { | 1836 if (allow_natives() || extension_ != NULL) { |
1824 BindingPatternUnexpectedToken(); | 1837 BindingPatternUnexpectedToken(); |
1825 return ParseV8Intrinsic(ok); | 1838 return ParseV8Intrinsic(ok); |
1826 } | 1839 } |
1827 break; | 1840 break; |
1828 | 1841 |
1829 case Token::DO: | 1842 case Token::DO: |
1830 if (allow_harmony_do_expressions()) { | 1843 if (allow_harmony_do_expressions()) { |
(...skipping 1377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3208 result, factory()->NewStringLiteral(name, pos), pos); | 3221 result, factory()->NewStringLiteral(name, pos), pos); |
3209 impl()->PushLiteralName(name); | 3222 impl()->PushLiteralName(name); |
3210 break; | 3223 break; |
3211 } | 3224 } |
3212 | 3225 |
3213 case Token::TEMPLATE_SPAN: | 3226 case Token::TEMPLATE_SPAN: |
3214 case Token::TEMPLATE_TAIL: { | 3227 case Token::TEMPLATE_TAIL: { |
3215 impl()->RewriteNonPattern(CHECK_OK); | 3228 impl()->RewriteNonPattern(CHECK_OK); |
3216 BindingPatternUnexpectedToken(); | 3229 BindingPatternUnexpectedToken(); |
3217 ArrowFormalParametersUnexpectedToken(); | 3230 ArrowFormalParametersUnexpectedToken(); |
3218 result = ParseTemplateLiteral(result, position(), CHECK_OK); | 3231 result = ParseTemplateLiteral(result, position(), true, CHECK_OK); |
3219 break; | 3232 break; |
3220 } | 3233 } |
3221 | 3234 |
3222 default: | 3235 default: |
3223 return result; | 3236 return result; |
3224 } | 3237 } |
3225 } | 3238 } |
3226 } | 3239 } |
3227 | 3240 |
3228 template <typename Impl> | 3241 template <typename Impl> |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3488 if (scanner()->current_token() == Token::IDENTIFIER) { | 3501 if (scanner()->current_token() == Token::IDENTIFIER) { |
3489 pos = position(); | 3502 pos = position(); |
3490 } else { | 3503 } else { |
3491 pos = peek_position(); | 3504 pos = peek_position(); |
3492 if (expression->IsFunctionLiteral()) { | 3505 if (expression->IsFunctionLiteral()) { |
3493 // If the tag function looks like an IIFE, set_parenthesized() to | 3506 // If the tag function looks like an IIFE, set_parenthesized() to |
3494 // force eager compilation. | 3507 // force eager compilation. |
3495 expression->AsFunctionLiteral()->SetShouldEagerCompile(); | 3508 expression->AsFunctionLiteral()->SetShouldEagerCompile(); |
3496 } | 3509 } |
3497 } | 3510 } |
3498 expression = ParseTemplateLiteral(expression, pos, CHECK_OK); | 3511 expression = ParseTemplateLiteral(expression, pos, true, CHECK_OK); |
3499 break; | 3512 break; |
3500 } | 3513 } |
3501 case Token::ILLEGAL: { | 3514 case Token::ILLEGAL: { |
3502 ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL); | 3515 ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL); |
3503 *ok = false; | 3516 *ok = false; |
3504 return impl()->EmptyExpression(); | 3517 return impl()->EmptyExpression(); |
3505 } | 3518 } |
3506 default: | 3519 default: |
3507 return expression; | 3520 return expression; |
3508 } | 3521 } |
(...skipping 860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4369 } | 4382 } |
4370 return impl()->ParseFunctionLiteral( | 4383 return impl()->ParseFunctionLiteral( |
4371 name, scanner()->location(), | 4384 name, scanner()->location(), |
4372 is_strict_reserved ? kFunctionNameIsStrictReserved | 4385 is_strict_reserved ? kFunctionNameIsStrictReserved |
4373 : kFunctionNameValidityUnknown, | 4386 : kFunctionNameValidityUnknown, |
4374 FunctionKind::kAsyncFunction, pos, type, language_mode(), CHECK_OK); | 4387 FunctionKind::kAsyncFunction, pos, type, language_mode(), CHECK_OK); |
4375 } | 4388 } |
4376 | 4389 |
4377 template <typename Impl> | 4390 template <typename Impl> |
4378 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral( | 4391 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral( |
4379 ExpressionT tag, int start, bool* ok) { | 4392 ExpressionT tag, int start, bool tagged, bool* ok) { |
4380 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal | 4393 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal |
4381 // text followed by a substitution expression), finalized by a single | 4394 // text followed by a substitution expression), finalized by a single |
4382 // TEMPLATE_TAIL. | 4395 // TEMPLATE_TAIL. |
4383 // | 4396 // |
4384 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or | 4397 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or |
4385 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or | 4398 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or |
4386 // NoSubstitutionTemplate. | 4399 // NoSubstitutionTemplate. |
4387 // | 4400 // |
4388 // When parsing a TemplateLiteral, we must have scanned either an initial | 4401 // When parsing a TemplateLiteral, we must have scanned either an initial |
4389 // TEMPLATE_SPAN, or a TEMPLATE_TAIL. | 4402 // TEMPLATE_SPAN, or a TEMPLATE_TAIL. |
4390 CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL); | 4403 CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL); |
4391 | 4404 |
| 4405 bool forbid_illegal_escapes = !allow_harmony_template_escapes() || !tagged; |
| 4406 |
4392 // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate. | 4407 // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate. |
4393 // In this case we may simply consume the token and build a template with a | 4408 // In this case we may simply consume the token and build a template with a |
4394 // single TEMPLATE_SPAN and no expressions. | 4409 // single TEMPLATE_SPAN and no expressions. |
4395 if (peek() == Token::TEMPLATE_TAIL) { | 4410 if (peek() == Token::TEMPLATE_TAIL) { |
4396 Consume(Token::TEMPLATE_TAIL); | 4411 Consume(Token::TEMPLATE_TAIL); |
4397 int pos = position(); | 4412 int pos = position(); |
4398 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); | |
4399 typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos); | 4413 typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos); |
4400 impl()->AddTemplateSpan(&ts, true); | 4414 bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes, CHECK_OK); |
| 4415 impl()->AddTemplateSpan(&ts, is_valid, true); |
4401 return impl()->CloseTemplateLiteral(&ts, start, tag); | 4416 return impl()->CloseTemplateLiteral(&ts, start, tag); |
4402 } | 4417 } |
4403 | 4418 |
4404 Consume(Token::TEMPLATE_SPAN); | 4419 Consume(Token::TEMPLATE_SPAN); |
4405 int pos = position(); | 4420 int pos = position(); |
4406 typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos); | 4421 typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos); |
4407 impl()->AddTemplateSpan(&ts, false); | 4422 bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes, CHECK_OK); |
| 4423 impl()->AddTemplateSpan(&ts, is_valid, false); |
4408 Token::Value next; | 4424 Token::Value next; |
4409 | 4425 |
4410 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression, | 4426 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression, |
4411 // and repeat if the following token is a TEMPLATE_SPAN as well (in this | 4427 // and repeat if the following token is a TEMPLATE_SPAN as well (in this |
4412 // case, representing a TemplateMiddle). | 4428 // case, representing a TemplateMiddle). |
4413 | 4429 |
4414 do { | 4430 do { |
4415 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); | |
4416 next = peek(); | 4431 next = peek(); |
4417 if (next == Token::EOS) { | 4432 if (next == Token::EOS) { |
4418 impl()->ReportMessageAt(Scanner::Location(start, peek_position()), | 4433 impl()->ReportMessageAt(Scanner::Location(start, peek_position()), |
4419 MessageTemplate::kUnterminatedTemplate); | 4434 MessageTemplate::kUnterminatedTemplate); |
4420 *ok = false; | 4435 *ok = false; |
4421 return impl()->EmptyExpression(); | 4436 return impl()->EmptyExpression(); |
4422 } else if (next == Token::ILLEGAL) { | 4437 } else if (next == Token::ILLEGAL) { |
4423 impl()->ReportMessageAt( | 4438 impl()->ReportMessageAt( |
4424 Scanner::Location(position() + 1, peek_position()), | 4439 Scanner::Location(position() + 1, peek_position()), |
4425 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); | 4440 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); |
(...skipping 25 matching lines...) Expand all Loading... |
4451 *ok = false; | 4466 *ok = false; |
4452 return impl()->EmptyExpression(); | 4467 return impl()->EmptyExpression(); |
4453 } else if (next == Token::ILLEGAL) { | 4468 } else if (next == Token::ILLEGAL) { |
4454 impl()->ReportMessageAt( | 4469 impl()->ReportMessageAt( |
4455 Scanner::Location(position() + 1, peek_position()), | 4470 Scanner::Location(position() + 1, peek_position()), |
4456 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); | 4471 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); |
4457 *ok = false; | 4472 *ok = false; |
4458 return impl()->EmptyExpression(); | 4473 return impl()->EmptyExpression(); |
4459 } | 4474 } |
4460 | 4475 |
4461 impl()->AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL); | 4476 bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes, CHECK_OK); |
| 4477 impl()->AddTemplateSpan(&ts, is_valid, next == Token::TEMPLATE_TAIL); |
4462 } while (next == Token::TEMPLATE_SPAN); | 4478 } while (next == Token::TEMPLATE_SPAN); |
4463 | 4479 |
4464 DCHECK_EQ(next, Token::TEMPLATE_TAIL); | 4480 DCHECK_EQ(next, Token::TEMPLATE_TAIL); |
4465 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); | |
4466 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. | 4481 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. |
4467 return impl()->CloseTemplateLiteral(&ts, start, tag); | 4482 return impl()->CloseTemplateLiteral(&ts, start, tag); |
4468 } | 4483 } |
4469 | 4484 |
4470 template <typename Impl> | 4485 template <typename Impl> |
4471 typename ParserBase<Impl>::ExpressionT | 4486 typename ParserBase<Impl>::ExpressionT |
4472 ParserBase<Impl>::CheckAndRewriteReferenceExpression( | 4487 ParserBase<Impl>::CheckAndRewriteReferenceExpression( |
4473 ExpressionT expression, int beg_pos, int end_pos, | 4488 ExpressionT expression, int beg_pos, int end_pos, |
4474 MessageTemplate::Template message, bool* ok) { | 4489 MessageTemplate::Template message, bool* ok) { |
4475 return CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos, | 4490 return CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos, |
(...skipping 1360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5836 } | 5851 } |
5837 | 5852 |
5838 #undef CHECK_OK | 5853 #undef CHECK_OK |
5839 #undef CHECK_OK_CUSTOM | 5854 #undef CHECK_OK_CUSTOM |
5840 #undef CHECK_OK_VOID | 5855 #undef CHECK_OK_VOID |
5841 | 5856 |
5842 } // namespace internal | 5857 } // namespace internal |
5843 } // namespace v8 | 5858 } // namespace v8 |
5844 | 5859 |
5845 #endif // V8_PARSING_PARSER_BASE_H | 5860 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |