Index: src/parsing/scanner.cc |
diff --git a/src/parsing/scanner.cc b/src/parsing/scanner.cc |
index 60695a0bba7ce5a243bf2eb530d593428ddac588..325edbcd34003466d072ff8b88e5861cbda8fd2b 100644 |
--- a/src/parsing/scanner.cc |
+++ b/src/parsing/scanner.cc |
@@ -26,21 +26,60 @@ Handle<String> Scanner::LiteralBuffer::Internalize(Isolate* isolate) const { |
return isolate->factory()->InternalizeTwoByteString(two_byte_literal()); |
} |
+// ---------------------------------------------------------------------------- |
+// Scanner::BookmarkScope |
+ |
+const size_t Scanner::BookmarkScope::kBookmarkAtFirstPos = |
+ std::numeric_limits<size_t>::max() - 2; |
+const size_t Scanner::BookmarkScope::kNoBookmark = |
+ std::numeric_limits<size_t>::max() - 1; |
+const size_t Scanner::BookmarkScope::kBookmarkWasApplied = |
+ std::numeric_limits<size_t>::max(); |
+ |
+void Scanner::BookmarkScope::Set() { |
+ DCHECK_EQ(bookmark_, kNoBookmark); |
+ DCHECK_EQ(scanner_->next_next_.token, Token::UNINITIALIZED); |
+ |
+ // The first token is a bit special, since current_ will still be |
+ // uninitialized. In this case, store kBookmarkAtFirstPos and special-case it |
+ // when |
+ // applying the bookmark. |
+ DCHECK_IMPLIES( |
+ scanner_->current_.token == Token::UNINITIALIZED, |
+ scanner_->current_.location.beg_pos == scanner_->next_.location.beg_pos); |
+ bookmark_ = (scanner_->current_.token == Token::UNINITIALIZED) |
+ ? kBookmarkAtFirstPos |
+ : scanner_->location().beg_pos; |
+} |
+ |
+void Scanner::BookmarkScope::Apply() { |
+ DCHECK(HasBeenSet()); // Caller hasn't called SetBookmark. |
+ if (bookmark_ == kBookmarkAtFirstPos) { |
+ scanner_->SeekNext(0); |
+ } else { |
+ scanner_->SeekNext(bookmark_); |
+ scanner_->Next(); |
+ DCHECK_EQ(scanner_->location().beg_pos, bookmark_); |
+ } |
+ bookmark_ = kBookmarkWasApplied; |
+} |
+ |
+bool Scanner::BookmarkScope::HasBeenSet() { |
+ return bookmark_ != kNoBookmark && bookmark_ != kBookmarkWasApplied; |
+} |
+ |
+bool Scanner::BookmarkScope::HasBeenApplied() { |
+ return bookmark_ == kBookmarkWasApplied; |
+} |
// ---------------------------------------------------------------------------- |
// Scanner |
Scanner::Scanner(UnicodeCache* unicode_cache) |
: unicode_cache_(unicode_cache), |
- bookmark_c0_(kNoBookmark), |
- bookmark_position_(0), |
octal_pos_(Location::invalid()), |
decimal_with_leading_zero_pos_(Location::invalid()), |
found_html_comment_(false) { |
- bookmark_current_.literal_chars = &bookmark_current_literal_; |
- bookmark_current_.raw_literal_chars = &bookmark_current_raw_literal_; |
- bookmark_next_.literal_chars = &bookmark_next_literal_; |
- bookmark_next_.raw_literal_chars = &bookmark_next_raw_literal_; |
} |
@@ -1581,56 +1620,24 @@ int Scanner::FindSymbol(DuplicateFinder* finder, int value) { |
return finder->AddTwoByteSymbol(literal_two_byte_string(), value); |
} |
-void Scanner::SetBookmark() { |
- DCHECK_EQ(bookmark_c0_, kNoBookmark); |
- DCHECK_EQ(next_next_.token, Token::UNINITIALIZED); |
- bookmark_c0_ = c0_; |
- bookmark_position_ = source_->pos(); |
- CopyTokenDesc(&bookmark_current_, ¤t_); |
- CopyTokenDesc(&bookmark_next_, &next_); |
-} |
- |
- |
-void Scanner::ResetToBookmark() { |
- DCHECK(BookmarkHasBeenSet()); // Caller hasn't called SetBookmark. |
- |
- source_->Seek(bookmark_position_); |
- c0_ = bookmark_c0_; |
- CopyToNextTokenDesc(&bookmark_current_); |
- current_ = next_; |
- CopyToNextTokenDesc(&bookmark_next_); |
- bookmark_c0_ = kBookmarkWasApplied; |
-} |
- |
-bool Scanner::BookmarkHasBeenSet() { |
- return bookmark_c0_ != kNoBookmark && bookmark_c0_ != kBookmarkWasApplied; |
-} |
- |
-bool Scanner::BookmarkHasBeenReset() { |
- return bookmark_c0_ == kBookmarkWasApplied; |
-} |
- |
- |
-void Scanner::DropBookmark() { bookmark_c0_ = kNoBookmark; } |
- |
-void Scanner::CopyToNextTokenDesc(TokenDesc* from) { |
- StartLiteral(); |
- StartRawLiteral(); |
- CopyTokenDesc(&next_, from); |
- if (next_.literal_chars->length() == 0) next_.literal_chars = nullptr; |
- if (next_.raw_literal_chars->length() == 0) next_.raw_literal_chars = nullptr; |
-} |
- |
-void Scanner::CopyTokenDesc(TokenDesc* to, TokenDesc* from) { |
- DCHECK_NOT_NULL(to); |
- DCHECK_NOT_NULL(from); |
- to->token = from->token; |
- to->location = from->location; |
- to->literal_chars->CopyFrom(from->literal_chars); |
- to->raw_literal_chars->CopyFrom(from->raw_literal_chars); |
+void Scanner::SeekNext(size_t position) { |
+ // Use with care: This cleanly resets most, but not all scanner state. |
+ // TODO(vogelheim): Fix this, or at least DCHECK the relevant conditions. |
+ |
+ // To re-scan from a given character position, we need to: |
+ // 1, Reset the current_, next_ and next_next_ tokens |
+ // (next_ + next_next_ will be overwrittem by Next(), |
+ // current_ will remain unchanged, so overwrite it fully.) |
+ current_ = {{0, 0}, nullptr, nullptr, 0, Token::UNINITIALIZED}; |
+ next_.token = Token::UNINITIALIZED; |
+ next_next_.token = Token::UNINITIALIZED; |
+ // 2, reset the source to the desired position, |
+ source_->Seek(position); |
+ // 3, re-scan, by scanning the look-ahead char + 1 token (next_). |
+ c0_ = source_->Advance(); |
+ Next(); |
+ DCHECK_EQ(next_.location.beg_pos, position); |
} |
- |
- |
} // namespace internal |
} // namespace v8 |