Index: src/scanner.h |
diff --git a/src/scanner.h b/src/scanner.h |
index ef5f01baec03a228c9517ae8b862024f9e10832b..f387d84133f984ff5183b6b802d65cf5cb3293bb 100644 |
--- a/src/scanner.h |
+++ b/src/scanner.h |
@@ -89,6 +89,9 @@ class Utf16CharacterStream { |
// Must not be used right after calling SeekForward. |
virtual void PushBack(int32_t code_unit) = 0; |
+ virtual bool SetBookmark(); |
+ virtual void ResetToBookmark(); |
+ |
protected: |
static const uc32 kEndOfInput = -1; |
@@ -268,6 +271,17 @@ class LiteralBuffer { |
Handle<String> Internalize(Isolate* isolate) const; |
+ void CopyFrom(const LiteralBuffer* other) { |
+ if (other == nullptr) { |
+ Reset(); |
+ } else { |
+ is_one_byte_ = other->is_one_byte_; |
+ position_ = other->position_; |
+ backing_store_.Dispose(); |
+ backing_store_ = other->backing_store_.Clone(); |
+ } |
+ } |
+ |
private: |
static const int kInitialCapacity = 16; |
static const int kGrowthFactory = 4; |
@@ -342,6 +356,25 @@ class Scanner { |
bool complete_; |
}; |
+ // Scoped helper for a re-settable bookmark. |
+ class BookmarkScope { |
+ public: |
+ explicit BookmarkScope(Scanner* scanner) : scanner_(scanner) { |
+ DCHECK_NOT_NULL(scanner_); |
+ } |
+ ~BookmarkScope() { scanner_->DropBookmark(); } |
+ |
+ bool Set() { return scanner_->SetBookmark(); } |
+ void Reset() { scanner_->ResetToBookmark(); } |
+ bool HasBeenSet() { return scanner_->BookmarkHasBeenSet(); } |
+ bool HasBeenReset() { return scanner_->BookmarkHasBeenReset(); } |
+ |
+ private: |
+ Scanner* scanner_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(BookmarkScope); |
+ }; |
+ |
// Representation of an interval of source positions. |
struct Location { |
Location(int b, int e) : beg_pos(b), end_pos(e) { } |
@@ -510,6 +543,14 @@ class Scanner { |
current_.raw_literal_chars = NULL; |
} |
+ // Support BookmarkScope functionality. |
+ bool SetBookmark(); |
+ void ResetToBookmark(); |
+ bool BookmarkHasBeenSet(); |
+ bool BookmarkHasBeenReset(); |
+ void DropBookmark(); |
+ static void CopyTokenDesc(TokenDesc* to, TokenDesc* from); |
+ |
// Literal buffer support |
inline void StartLiteral() { |
LiteralBuffer* free_buffer = (current_.literal_chars == &literal_buffer1_) ? |
@@ -712,6 +753,37 @@ class Scanner { |
TokenDesc current_; // desc for current token (as returned by Next()) |
TokenDesc next_; // desc for next token (one token look-ahead) |
+ // Variables for Scanner::BookmarkScope and the *Bookmark implementation. |
+ // These variables contain the scanner state when a bookmark is set. |
+ // |
+ // We will use bookmark_c0_ as a 'control' variable, where: |
+ // - bookmark_c0_ >= 0: A bookmark has been set and this contains c0_. |
+ // - bookmark_c0_ == -1: No bookmark has been set. |
+ // - bookmark_c0_ == -2: The bookmark has been applied (ResetToBookmark). |
+ // |
+ // Which state is being bookmarked? The parser state is distributed over |
+ // several variables, roughly like this: |
+ // ... 1234 + 5678 ..... [character stream] |
+ // [current_] [next_] c0_ | [scanner state] |
+ // So when the scanner is logically at the beginning of an expression |
+ // like "1234 + 4567", then: |
+ // - current_ contains "1234" |
+ // - next_ contains "+" |
+ // - c0_ contains ' ' (the space between "+" and "5678", |
+ // - the source_ character stream points to the beginning of "5678". |
+ // To be able to restore this state, we will keep copies of current_, next_, |
+ // and c0_; we'll ask the stream to bookmark itself, and we'll copy the |
+ // contents of current_'s and next_'s literal buffers to bookmark_*_literal_. |
+ static const uc32 kNoBookmark = -1; |
+ static const uc32 kBookmarkWasApplied = -2; |
+ uc32 bookmark_c0_; |
+ TokenDesc bookmark_current_; |
+ TokenDesc bookmark_next_; |
+ LiteralBuffer bookmark_current_literal_; |
+ LiteralBuffer bookmark_current_raw_literal_; |
+ LiteralBuffer bookmark_next_literal_; |
+ LiteralBuffer bookmark_next_raw_literal_; |
+ |
// Input stream. Must be initialized to an Utf16CharacterStream. |
Utf16CharacterStream* source_; |