| Index: src/scanner.h
|
| diff --git a/src/scanner.h b/src/scanner.h
|
| index 446355fce1207748da96eeddb7e68a06d3d594ca..590f3a88e4d6f4ec0361f6d2169eacdd978daf1d 100644
|
| --- a/src/scanner.h
|
| +++ b/src/scanner.h
|
| @@ -252,6 +252,10 @@ class LiteralBuffer {
|
| return is_one_byte_ ? position_ : (position_ >> 1);
|
| }
|
|
|
| + void ReduceLength(int delta) {
|
| + position_ -= delta * (is_one_byte_ ? kOneByteSize : kUC16Size);
|
| + }
|
| +
|
| void Reset() {
|
| position_ = 0;
|
| is_one_byte_ = true;
|
| @@ -318,9 +322,10 @@ class Scanner {
|
| // if aborting the scanning before it's complete.
|
| class LiteralScope {
|
| public:
|
| - explicit LiteralScope(Scanner* self)
|
| + explicit LiteralScope(Scanner* self, bool capture_raw = false)
|
| : scanner_(self), complete_(false) {
|
| scanner_->StartLiteral();
|
| + if (capture_raw) scanner_->StartRawLiteral();
|
| }
|
| ~LiteralScope() {
|
| if (!complete_) scanner_->DropLiteral();
|
| @@ -392,6 +397,7 @@ class Scanner {
|
|
|
| const AstRawString* CurrentSymbol(AstValueFactory* ast_value_factory);
|
| const AstRawString* NextSymbol(AstValueFactory* ast_value_factory);
|
| + const AstRawString* CurrentRawSymbol(AstValueFactory* ast_value_factory);
|
|
|
| double DoubleValue();
|
| bool LiteralMatches(const char* data, int length, bool allow_escapes = true) {
|
| @@ -493,6 +499,7 @@ class Scanner {
|
| Token::Value token;
|
| Location location;
|
| LiteralBuffer* literal_chars;
|
| + LiteralBuffer* raw_literal_chars;
|
| };
|
|
|
| static const int kCharacterLookaheadBufferSize = 1;
|
| @@ -507,6 +514,7 @@ class Scanner {
|
| Advance();
|
| // Initialize current_ to not refer to a literal.
|
| current_.literal_chars = NULL;
|
| + current_.raw_literal_chars = NULL;
|
| }
|
|
|
| // Literal buffer support
|
| @@ -517,20 +525,38 @@ class Scanner {
|
| next_.literal_chars = free_buffer;
|
| }
|
|
|
| + inline void StartRawLiteral() {
|
| + raw_literal_buffer_.Reset();
|
| + next_.raw_literal_chars = &raw_literal_buffer_;
|
| + capturing_raw_literal_ = true;
|
| + }
|
| +
|
| INLINE(void AddLiteralChar(uc32 c)) {
|
| DCHECK_NOT_NULL(next_.literal_chars);
|
| next_.literal_chars->AddChar(c);
|
| }
|
|
|
| - // Complete scanning of a literal.
|
| - inline void TerminateLiteral() {
|
| - // Does nothing in the current implementation.
|
| + INLINE(void AddRawLiteralChar(uc32 c)) {
|
| + DCHECK(capturing_raw_literal_);
|
| + DCHECK_NOT_NULL(next_.raw_literal_chars);
|
| + next_.raw_literal_chars->AddChar(c);
|
| }
|
|
|
| + INLINE(void ReduceRawLiteralLength(int delta)) {
|
| + DCHECK(capturing_raw_literal_);
|
| + DCHECK_NOT_NULL(next_.raw_literal_chars);
|
| + next_.raw_literal_chars->ReduceLength(delta);
|
| + }
|
| +
|
| + // Complete scanning of a literal.
|
| + inline void TerminateLiteral() { capturing_raw_literal_ = false; }
|
| +
|
| // Stops scanning of a literal and drop the collected characters,
|
| // e.g., due to an encountered error.
|
| inline void DropLiteral() {
|
| next_.literal_chars = NULL;
|
| + next_.raw_literal_chars = NULL;
|
| + capturing_raw_literal_ = false;
|
| }
|
|
|
| inline void AddLiteralCharAdvance() {
|
| @@ -540,6 +566,9 @@ class Scanner {
|
|
|
| // Low-level scanning support.
|
| void Advance() {
|
| + if (capturing_raw_literal_) {
|
| + AddRawLiteralChar(c0_);
|
| + }
|
| c0_ = source_->Advance();
|
| if (unibrow::Utf16::IsLeadSurrogate(c0_)) {
|
| uc32 c1 = source_->Advance();
|
| @@ -555,8 +584,10 @@ class Scanner {
|
| if (ch > static_cast<uc32>(unibrow::Utf16::kMaxNonSurrogateCharCode)) {
|
| source_->PushBack(unibrow::Utf16::TrailSurrogate(c0_));
|
| source_->PushBack(unibrow::Utf16::LeadSurrogate(c0_));
|
| + if (capturing_raw_literal_) ReduceRawLiteralLength(2);
|
| } else {
|
| source_->PushBack(c0_);
|
| + if (capturing_raw_literal_) ReduceRawLiteralLength(1);
|
| }
|
| c0_ = ch;
|
| }
|
| @@ -578,8 +609,9 @@ class Scanner {
|
|
|
| // Returns the literal string, if any, for the current token (the
|
| // token last returned by Next()). The string is 0-terminated.
|
| - // Literal strings are collected for identifiers, strings, and
|
| - // numbers.
|
| + // Literal strings are collected for identifiers, strings, numbers as well
|
| + // as for template literals. For template literals we also collect the raw
|
| + // form.
|
| // These functions only give the correct result if the literal
|
| // was scanned between calls to StartLiteral() and TerminateLiteral().
|
| Vector<const uint8_t> literal_one_byte_string() {
|
| @@ -612,10 +644,19 @@ class Scanner {
|
| DCHECK_NOT_NULL(next_.literal_chars);
|
| return next_.literal_chars->is_one_byte();
|
| }
|
| - int next_literal_length() const {
|
| - DCHECK_NOT_NULL(next_.literal_chars);
|
| - return next_.literal_chars->length();
|
| + Vector<const uint8_t> raw_literal_one_byte_string() {
|
| + DCHECK_NOT_NULL(current_.raw_literal_chars);
|
| + return current_.raw_literal_chars->one_byte_literal();
|
| + }
|
| + Vector<const uint16_t> raw_literal_two_byte_string() {
|
| + DCHECK_NOT_NULL(current_.raw_literal_chars);
|
| + return current_.raw_literal_chars->two_byte_literal();
|
| }
|
| + bool is_raw_literal_one_byte() {
|
| + DCHECK_NOT_NULL(current_.raw_literal_chars);
|
| + return current_.raw_literal_chars->is_one_byte();
|
| + }
|
| +
|
|
|
| uc32 ScanHexNumber(int expected_length);
|
| // Scan a number of any length but not bigger than max_value. For example, the
|
| @@ -666,6 +707,13 @@ class Scanner {
|
| LiteralBuffer source_url_;
|
| LiteralBuffer source_mapping_url_;
|
|
|
| + // Buffer to store raw string values
|
| + LiteralBuffer raw_literal_buffer_;
|
| +
|
| + // We only need to capture the raw literal when we are scanning template
|
| + // literal spans.
|
| + bool capturing_raw_literal_;
|
| +
|
| TokenDesc current_; // desc for current token (as returned by Next())
|
| TokenDesc next_; // desc for next token (one token look-ahead)
|
|
|
|
|