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

Unified Diff: src/parsing/scanner.cc

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/scanner.h ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parsing/scanner.cc
diff --git a/src/parsing/scanner.cc b/src/parsing/scanner.cc
index 86aadcff9fae2e74e7e6d11172ab2aac91d4f62a..c1580bbeae7dd23d69d0e02c13b0090474cb1773 100644
--- a/src/parsing/scanner.cc
+++ b/src/parsing/scanner.cc
@@ -19,6 +19,46 @@
namespace v8 {
namespace internal {
+// Scoped helper for saving & restoring scanner error state.
+// This is used for tagged template literals, in which normally forbidden
+// escape sequences are allowed.
+class ErrorState {
+ public:
+ ErrorState(MessageTemplate::Template* message_stack,
+ Scanner::Location* location_stack)
+ : message_stack_(message_stack),
+ old_message_(*message_stack),
+ location_stack_(location_stack),
+ old_location_(*location_stack) {
+ *message_stack_ = MessageTemplate::kNone;
+ *location_stack_ = Scanner::Location::invalid();
+ }
+
+ ~ErrorState() {
+ *message_stack_ = old_message_;
+ *location_stack_ = old_location_;
+ }
+
+ void MoveErrorTo(MessageTemplate::Template* message_dest,
+ Scanner::Location* location_dest) {
+ if (*message_stack_ == MessageTemplate::kNone) {
+ return;
+ }
+ if (*message_dest == MessageTemplate::kNone) {
+ *message_dest = *message_stack_;
+ *location_dest = *location_stack_;
+ }
+ *message_stack_ = MessageTemplate::kNone;
+ *location_stack_ = Scanner::Location::invalid();
+ }
+
+ private:
+ MessageTemplate::Template* const message_stack_;
+ MessageTemplate::Template const old_message_;
+ Scanner::Location* const location_stack_;
+ Scanner::Location const old_location_;
+};
+
Handle<String> Scanner::LiteralBuffer::Internalize(Isolate* isolate) const {
if (is_one_byte()) {
return isolate->factory()->InternalizeOneByteString(one_byte_literal());
@@ -948,16 +988,12 @@ bool Scanner::ScanEscape() {
break;
}
- // According to ECMA-262, section 7.8.4, characters not covered by the
- // above cases should be illegal, but they are commonly handled as
- // non-escaped characters by JS VMs.
+ // Other escaped characters are interpreted as their non-escaped version.
AddLiteralChar(c);
return true;
}
-// Octal escapes of the forms '\0xx' and '\xxx' are not a part of
-// ECMA-262. Other JS VMs support them.
template <bool capture_raw>
uc32 Scanner::ScanOctalEscape(uc32 c, int length) {
uc32 x = c - '0';
@@ -1039,6 +1075,12 @@ Token::Value Scanner::ScanTemplateSpan() {
// TEMPLATE_TAIL terminates a TemplateLiteral and does not need to be
// followed by an Expression.
+ // These scoped helpers save and restore the original error state, so that we
+ // can specially treat invalid escape sequences in templates (which are
+ // handled by the parser).
+ ErrorState scanner_error_state(&scanner_error_, &scanner_error_location_);
+ ErrorState octal_error_state(&octal_message_, &octal_pos_);
+
Token::Value result = Token::TEMPLATE_SPAN;
LiteralScope literal(this);
StartRawLiteral();
@@ -1069,8 +1111,16 @@ Token::Value Scanner::ScanTemplateSpan() {
AddRawLiteralChar('\n');
}
}
- } else if (!ScanEscape<capture_raw, in_template_literal>()) {
- return Token::ILLEGAL;
+ } else {
+ bool success = ScanEscape<capture_raw, in_template_literal>();
+ USE(success);
+ DCHECK_EQ(!success, has_error());
+ // For templates, invalid escape sequence checking is handled in the
+ // parser.
+ scanner_error_state.MoveErrorTo(&invalid_template_escape_message_,
+ &invalid_template_escape_location_);
+ octal_error_state.MoveErrorTo(&invalid_template_escape_message_,
+ &invalid_template_escape_location_);
}
} else if (c < 0) {
// Unterminated template literal
@@ -1095,6 +1145,7 @@ Token::Value Scanner::ScanTemplateSpan() {
literal.Complete();
next_.location.end_pos = source_pos();
next_.token = result;
+
return result;
}
« no previous file with comments | « src/parsing/scanner.h ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698