Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Unified Diff: src/parsing/parser-base.h

Issue 2665513002: [parser] Lift template literal invalid escape restriction (Closed)
Patch Set: reintroduce DCHECK_EQ Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parsing/parser-base.h
diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
index 5e6922206748b5f4976672461b314a244d67ea03..b90344e82820989ef8bf1efed3ba099ad27d8022 100644
--- a/src/parsing/parser-base.h
+++ b/src/parsing/parser-base.h
@@ -226,7 +226,8 @@ class ParserBase {
allow_harmony_class_fields_(false),
allow_harmony_object_rest_spread_(false),
allow_harmony_dynamic_import_(false),
- allow_harmony_async_iteration_(false) {}
+ allow_harmony_async_iteration_(false),
+ allow_harmony_template_escapes_(false) {}
#define ALLOW_ACCESSORS(name) \
bool allow_##name() const { return allow_##name##_; } \
@@ -242,6 +243,7 @@ class ParserBase {
ALLOW_ACCESSORS(harmony_object_rest_spread);
ALLOW_ACCESSORS(harmony_dynamic_import);
ALLOW_ACCESSORS(harmony_async_iteration);
+ ALLOW_ACCESSORS(harmony_template_escapes);
#undef ALLOW_ACCESSORS
@@ -816,14 +818,12 @@ class ParserBase {
}
// Checks whether an octal literal was last seen between beg_pos and end_pos.
- // If so, reports an error. Only called for strict mode and template strings.
- void CheckOctalLiteral(int beg_pos, int end_pos, bool is_template, bool* ok) {
+ // Only called for strict mode strings.
+ void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
Scanner::Location octal = scanner()->octal_position();
if (octal.IsValid() && beg_pos <= octal.beg_pos &&
octal.end_pos <= end_pos) {
- MessageTemplate::Template message =
- is_template ? MessageTemplate::kTemplateOctalLiteral
- : scanner()->octal_message();
+ MessageTemplate::Template message = scanner()->octal_message();
DCHECK_NE(message, MessageTemplate::kNone);
impl()->ReportMessageAt(octal, message);
scanner()->clear_octal_position();
@@ -834,12 +834,23 @@ class ParserBase {
}
}
- inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
- CheckOctalLiteral(beg_pos, end_pos, false, ok);
- }
+ // Checks if an octal literal or an invalid hex or unicode escape sequence
+ // appears in a template literal. In the presence of such, either
+ // returns false or reports an error, depending on should_throw. Otherwise
+ // returns true.
+ inline bool CheckTemplateEscapes(bool should_throw, bool* ok) {
+ if (!scanner()->has_invalid_template_escape()) {
+ return true;
+ }
- inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) {
- CheckOctalLiteral(beg_pos, end_pos, true, ok);
+ // Handle error case(s)
+ if (should_throw) {
+ impl()->ReportMessageAt(scanner()->invalid_template_escape_location(),
+ scanner()->invalid_template_escape_message());
+ *ok = false;
+ }
+ scanner()->clear_invalid_template_escape();
+ return false;
}
void CheckDestructuringElement(ExpressionT element, int beg_pos, int end_pos);
@@ -1138,7 +1149,8 @@ class ParserBase {
Scanner::Location class_name_location,
bool name_is_strict_reserved,
int class_token_pos, bool* ok);
- ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
+ ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool tagged,
+ bool* ok);
ExpressionT ParseSuperExpression(bool is_new, bool* ok);
ExpressionT ParseDynamicImportExpression(bool* ok);
ExpressionT ParseNewTargetExpression(bool* ok);
@@ -1449,6 +1461,7 @@ class ParserBase {
bool allow_harmony_object_rest_spread_;
bool allow_harmony_dynamic_import_;
bool allow_harmony_async_iteration_;
+ bool allow_harmony_template_escapes_;
friend class DiscardableZoneScope;
};
@@ -1817,7 +1830,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression(
case Token::TEMPLATE_SPAN:
case Token::TEMPLATE_TAIL:
BindingPatternUnexpectedToken();
- return ParseTemplateLiteral(impl()->NoTemplateTag(), beg_pos, ok);
+ return ParseTemplateLiteral(impl()->NoTemplateTag(), beg_pos, false, ok);
case Token::MOD:
if (allow_natives() || extension_ != NULL) {
@@ -3215,7 +3228,7 @@ ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) {
impl()->RewriteNonPattern(CHECK_OK);
BindingPatternUnexpectedToken();
ArrowFormalParametersUnexpectedToken();
- result = ParseTemplateLiteral(result, position(), CHECK_OK);
+ result = ParseTemplateLiteral(result, position(), true, CHECK_OK);
break;
}
@@ -3495,7 +3508,7 @@ ParserBase<Impl>::ParseMemberExpressionContinuation(ExpressionT expression,
expression->AsFunctionLiteral()->SetShouldEagerCompile();
}
}
- expression = ParseTemplateLiteral(expression, pos, CHECK_OK);
+ expression = ParseTemplateLiteral(expression, pos, true, CHECK_OK);
break;
}
case Token::ILLEGAL: {
@@ -4376,7 +4389,7 @@ ParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
- ExpressionT tag, int start, bool* ok) {
+ ExpressionT tag, int start, bool tagged, bool* ok) {
// A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
// text followed by a substitution expression), finalized by a single
// TEMPLATE_TAIL.
@@ -4389,22 +4402,25 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
// TEMPLATE_SPAN, or a TEMPLATE_TAIL.
CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
+ bool forbid_illegal_escapes = !allow_harmony_template_escapes() || !tagged;
+
// If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
// In this case we may simply consume the token and build a template with a
// single TEMPLATE_SPAN and no expressions.
if (peek() == Token::TEMPLATE_TAIL) {
Consume(Token::TEMPLATE_TAIL);
int pos = position();
- CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos);
- impl()->AddTemplateSpan(&ts, true);
+ bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes, CHECK_OK);
+ impl()->AddTemplateSpan(&ts, is_valid, true);
return impl()->CloseTemplateLiteral(&ts, start, tag);
}
Consume(Token::TEMPLATE_SPAN);
int pos = position();
typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos);
- impl()->AddTemplateSpan(&ts, false);
+ bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes, CHECK_OK);
+ impl()->AddTemplateSpan(&ts, is_valid, false);
Token::Value next;
// If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
@@ -4412,7 +4428,6 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
// case, representing a TemplateMiddle).
do {
- CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
next = peek();
if (next == Token::EOS) {
impl()->ReportMessageAt(Scanner::Location(start, peek_position()),
@@ -4458,11 +4473,11 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
return impl()->EmptyExpression();
}
- impl()->AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL);
+ bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes, CHECK_OK);
+ impl()->AddTemplateSpan(&ts, is_valid, next == Token::TEMPLATE_TAIL);
} while (next == Token::TEMPLATE_SPAN);
DCHECK_EQ(next, Token::TEMPLATE_TAIL);
- CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
// Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
return impl()->CloseTemplateLiteral(&ts, start, tag);
}
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698