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