Index: src/scanner.h |
diff --git a/src/scanner.h b/src/scanner.h |
index 46e6d32212a19e822a9ad18ab4eae35b9be90bb1..2dd16879f4f6169f9455dcea6b80a3f527e8d326 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) { |
@@ -491,6 +497,7 @@ class Scanner { |
Token::Value token; |
Location location; |
LiteralBuffer* literal_chars; |
+ LiteralBuffer* raw_literal_chars; |
}; |
static const int kCharacterLookaheadBufferSize = 1; |
@@ -505,6 +512,7 @@ class Scanner { |
Advance(); |
// Initialize current_ to not refer to a literal. |
current_.literal_chars = NULL; |
+ current_.raw_literal_chars = NULL; |
} |
// Literal buffer support |
@@ -515,20 +523,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() { |
@@ -538,6 +564,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(); |
@@ -550,6 +579,7 @@ class Scanner { |
} |
void PushBack(uc32 ch) { |
+ DCHECK(ch < 0 || !capturing_raw_literal_); |
caitp (gmail)
2014/12/02 21:37:35
I feel like PushBack() is okay --- it's more just
|
if (ch > static_cast<uc32>(unibrow::Utf16::kMaxNonSurrogateCharCode)) { |
source_->PushBack(unibrow::Utf16::TrailSurrogate(c0_)); |
source_->PushBack(unibrow::Utf16::LeadSurrogate(c0_)); |
@@ -576,8 +606,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() { |
@@ -610,10 +641,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); |
@@ -658,6 +698,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) |