| 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;
|
| }
|
|
|
|
|