| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Features shared by parsing and pre-parsing scanners. | 5 // Features shared by parsing and pre-parsing scanners. |
| 6 | 6 |
| 7 #ifndef V8_PARSING_SCANNER_H_ | 7 #ifndef V8_PARSING_SCANNER_H_ |
| 8 #define V8_PARSING_SCANNER_H_ | 8 #define V8_PARSING_SCANNER_H_ |
| 9 | 9 |
| 10 #include "src/allocation.h" | 10 #include "src/allocation.h" |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 | 147 |
| 148 | 148 |
| 149 // ---------------------------------------------------------------------------- | 149 // ---------------------------------------------------------------------------- |
| 150 // JavaScript Scanner. | 150 // JavaScript Scanner. |
| 151 | 151 |
| 152 class Scanner { | 152 class Scanner { |
| 153 public: | 153 public: |
| 154 // Scoped helper for a re-settable bookmark. | 154 // Scoped helper for a re-settable bookmark. |
| 155 class BookmarkScope { | 155 class BookmarkScope { |
| 156 public: | 156 public: |
| 157 explicit BookmarkScope(Scanner* scanner) : scanner_(scanner) { | 157 explicit BookmarkScope(Scanner* scanner) |
| 158 : scanner_(scanner), bookmark_(kNoBookmark) { |
| 158 DCHECK_NOT_NULL(scanner_); | 159 DCHECK_NOT_NULL(scanner_); |
| 159 } | 160 } |
| 160 ~BookmarkScope() { scanner_->DropBookmark(); } | 161 ~BookmarkScope() {} |
| 161 | 162 |
| 162 void Set() { scanner_->SetBookmark(); } | 163 void Set(); |
| 163 void Reset() { scanner_->ResetToBookmark(); } | 164 void Apply(); |
| 164 bool HasBeenSet() { return scanner_->BookmarkHasBeenSet(); } | 165 bool HasBeenSet(); |
| 165 bool HasBeenReset() { return scanner_->BookmarkHasBeenReset(); } | 166 bool HasBeenApplied(); |
| 166 | 167 |
| 167 private: | 168 private: |
| 169 static const size_t kNoBookmark; |
| 170 static const size_t kBookmarkWasApplied; |
| 171 static const size_t kBookmarkAtFirstPos; |
| 172 |
| 168 Scanner* scanner_; | 173 Scanner* scanner_; |
| 174 size_t bookmark_; |
| 169 | 175 |
| 170 DISALLOW_COPY_AND_ASSIGN(BookmarkScope); | 176 DISALLOW_COPY_AND_ASSIGN(BookmarkScope); |
| 171 }; | 177 }; |
| 172 | 178 |
| 173 // Representation of an interval of source positions. | 179 // Representation of an interval of source positions. |
| 174 struct Location { | 180 struct Location { |
| 175 Location(int b, int e) : beg_pos(b), end_pos(e) { } | 181 Location(int b, int e) : beg_pos(b), end_pos(e) { } |
| 176 Location() : beg_pos(0), end_pos(0) { } | 182 Location() : beg_pos(0), end_pos(0) { } |
| 177 | 183 |
| 178 bool IsValid() const { | 184 bool IsValid() const { |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 position_ -= delta * (is_one_byte_ ? kOneByteSize : kUC16Size); | 417 position_ -= delta * (is_one_byte_ ? kOneByteSize : kUC16Size); |
| 412 } | 418 } |
| 413 | 419 |
| 414 void Reset() { | 420 void Reset() { |
| 415 position_ = 0; | 421 position_ = 0; |
| 416 is_one_byte_ = true; | 422 is_one_byte_ = true; |
| 417 } | 423 } |
| 418 | 424 |
| 419 Handle<String> Internalize(Isolate* isolate) const; | 425 Handle<String> Internalize(Isolate* isolate) const; |
| 420 | 426 |
| 421 void CopyFrom(const LiteralBuffer* other) { | |
| 422 if (other == nullptr) { | |
| 423 Reset(); | |
| 424 } else { | |
| 425 is_one_byte_ = other->is_one_byte_; | |
| 426 position_ = other->position_; | |
| 427 if (position_ < backing_store_.length()) { | |
| 428 std::copy(other->backing_store_.begin(), | |
| 429 other->backing_store_.begin() + position_, | |
| 430 backing_store_.begin()); | |
| 431 } else { | |
| 432 backing_store_.Dispose(); | |
| 433 backing_store_ = other->backing_store_.Clone(); | |
| 434 } | |
| 435 } | |
| 436 } | |
| 437 | |
| 438 private: | 427 private: |
| 439 static const int kInitialCapacity = 16; | 428 static const int kInitialCapacity = 16; |
| 440 static const int kGrowthFactory = 4; | 429 static const int kGrowthFactory = 4; |
| 441 static const int kMinConversionSlack = 256; | 430 static const int kMinConversionSlack = 256; |
| 442 static const int kMaxGrowth = 1 * MB; | 431 static const int kMaxGrowth = 1 * MB; |
| 443 | 432 |
| 444 inline bool IsValidAscii(char code_unit) { | 433 inline bool IsValidAscii(char code_unit) { |
| 445 // Control characters and printable characters span the range of | 434 // Control characters and printable characters span the range of |
| 446 // valid ASCII characters (0-127). Chars are unsigned on some | 435 // valid ASCII characters (0-127). Chars are unsigned on some |
| 447 // platforms which causes compiler warnings if the validity check | 436 // platforms which causes compiler warnings if the validity check |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 next_.token = Token::UNINITIALIZED; | 510 next_.token = Token::UNINITIALIZED; |
| 522 next_.literal_chars = NULL; | 511 next_.literal_chars = NULL; |
| 523 next_.raw_literal_chars = NULL; | 512 next_.raw_literal_chars = NULL; |
| 524 next_next_.token = Token::UNINITIALIZED; | 513 next_next_.token = Token::UNINITIALIZED; |
| 525 next_next_.literal_chars = NULL; | 514 next_next_.literal_chars = NULL; |
| 526 next_next_.raw_literal_chars = NULL; | 515 next_next_.raw_literal_chars = NULL; |
| 527 found_html_comment_ = false; | 516 found_html_comment_ = false; |
| 528 scanner_error_ = MessageTemplate::kNone; | 517 scanner_error_ = MessageTemplate::kNone; |
| 529 } | 518 } |
| 530 | 519 |
| 531 // Support BookmarkScope functionality. | |
| 532 void SetBookmark(); | |
| 533 void ResetToBookmark(); | |
| 534 bool BookmarkHasBeenSet(); | |
| 535 bool BookmarkHasBeenReset(); | |
| 536 void DropBookmark(); | |
| 537 void CopyToNextTokenDesc(TokenDesc* from); | |
| 538 static void CopyTokenDesc(TokenDesc* to, TokenDesc* from); | |
| 539 | |
| 540 void ReportScannerError(const Location& location, | 520 void ReportScannerError(const Location& location, |
| 541 MessageTemplate::Template error) { | 521 MessageTemplate::Template error) { |
| 542 if (has_error()) return; | 522 if (has_error()) return; |
| 543 scanner_error_ = error; | 523 scanner_error_ = error; |
| 544 scanner_error_location_ = location; | 524 scanner_error_location_ = location; |
| 545 } | 525 } |
| 546 | 526 |
| 547 void ReportScannerError(int pos, MessageTemplate::Template error) { | 527 void ReportScannerError(int pos, MessageTemplate::Template error) { |
| 548 if (has_error()) return; | 528 if (has_error()) return; |
| 549 scanner_error_ = error; | 529 scanner_error_ = error; |
| 550 scanner_error_location_ = Location(pos, pos + 1); | 530 scanner_error_location_ = Location(pos, pos + 1); |
| 551 } | 531 } |
| 552 | 532 |
| 533 // Seek to the next_ token at the given position. |
| 534 void SeekNext(size_t position); |
| 535 |
| 553 // Literal buffer support | 536 // Literal buffer support |
| 554 inline void StartLiteral() { | 537 inline void StartLiteral() { |
| 555 LiteralBuffer* free_buffer = | 538 LiteralBuffer* free_buffer = |
| 556 (current_.literal_chars == &literal_buffer0_) | 539 (current_.literal_chars == &literal_buffer0_) |
| 557 ? &literal_buffer1_ | 540 ? &literal_buffer1_ |
| 558 : (current_.literal_chars == &literal_buffer1_) ? &literal_buffer2_ | 541 : (current_.literal_chars == &literal_buffer1_) ? &literal_buffer2_ |
| 559 : &literal_buffer0_; | 542 : &literal_buffer0_; |
| 560 free_buffer->Reset(); | 543 free_buffer->Reset(); |
| 561 next_.literal_chars = free_buffer; | 544 next_.literal_chars = free_buffer; |
| 562 } | 545 } |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 | 765 |
| 783 // Buffer to store raw string values | 766 // Buffer to store raw string values |
| 784 LiteralBuffer raw_literal_buffer0_; | 767 LiteralBuffer raw_literal_buffer0_; |
| 785 LiteralBuffer raw_literal_buffer1_; | 768 LiteralBuffer raw_literal_buffer1_; |
| 786 LiteralBuffer raw_literal_buffer2_; | 769 LiteralBuffer raw_literal_buffer2_; |
| 787 | 770 |
| 788 TokenDesc current_; // desc for current token (as returned by Next()) | 771 TokenDesc current_; // desc for current token (as returned by Next()) |
| 789 TokenDesc next_; // desc for next token (one token look-ahead) | 772 TokenDesc next_; // desc for next token (one token look-ahead) |
| 790 TokenDesc next_next_; // desc for the token after next (after PeakAhead()) | 773 TokenDesc next_next_; // desc for the token after next (after PeakAhead()) |
| 791 | 774 |
| 792 // Variables for Scanner::BookmarkScope and the *Bookmark implementation. | |
| 793 // These variables contain the scanner state when a bookmark is set. | |
| 794 // | |
| 795 // We will use bookmark_c0_ as a 'control' variable, where: | |
| 796 // - bookmark_c0_ >= 0: A bookmark has been set and this contains c0_. | |
| 797 // - bookmark_c0_ == -1: No bookmark has been set. | |
| 798 // - bookmark_c0_ == -2: The bookmark has been applied (ResetToBookmark). | |
| 799 // | |
| 800 // Which state is being bookmarked? The parser state is distributed over | |
| 801 // several variables, roughly like this: | |
| 802 // ... 1234 + 5678 ..... [character stream] | |
| 803 // [current_] [next_] c0_ | [scanner state] | |
| 804 // So when the scanner is logically at the beginning of an expression | |
| 805 // like "1234 + 4567", then: | |
| 806 // - current_ contains "1234" | |
| 807 // - next_ contains "+" | |
| 808 // - c0_ contains ' ' (the space between "+" and "5678", | |
| 809 // - the source_ character stream points to the beginning of "5678". | |
| 810 // To be able to restore this state, we will keep copies of current_, next_, | |
| 811 // and c0_; we'll ask the stream to bookmark itself, and we'll copy the | |
| 812 // contents of current_'s and next_'s literal buffers to bookmark_*_literal_. | |
| 813 static const uc32 kNoBookmark = -2; | |
| 814 static const uc32 kBookmarkWasApplied = -3; | |
| 815 uc32 bookmark_c0_; | |
| 816 size_t bookmark_position_; | |
| 817 TokenDesc bookmark_current_; | |
| 818 TokenDesc bookmark_next_; | |
| 819 LiteralBuffer bookmark_current_literal_; | |
| 820 LiteralBuffer bookmark_current_raw_literal_; | |
| 821 LiteralBuffer bookmark_next_literal_; | |
| 822 LiteralBuffer bookmark_next_raw_literal_; | |
| 823 | |
| 824 // Input stream. Must be initialized to an Utf16CharacterStream. | 775 // Input stream. Must be initialized to an Utf16CharacterStream. |
| 825 Utf16CharacterStream* source_; | 776 Utf16CharacterStream* source_; |
| 826 | 777 |
| 827 // Last-seen positions of potentially problematic tokens. | 778 // Last-seen positions of potentially problematic tokens. |
| 828 Location octal_pos_; | 779 Location octal_pos_; |
| 829 Location decimal_with_leading_zero_pos_; | 780 Location decimal_with_leading_zero_pos_; |
| 830 | 781 |
| 831 // One Unicode character look-ahead; c0_ < 0 at the end of the input. | 782 // One Unicode character look-ahead; c0_ < 0 at the end of the input. |
| 832 uc32 c0_; | 783 uc32 c0_; |
| 833 | 784 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 844 bool found_html_comment_; | 795 bool found_html_comment_; |
| 845 | 796 |
| 846 MessageTemplate::Template scanner_error_; | 797 MessageTemplate::Template scanner_error_; |
| 847 Location scanner_error_location_; | 798 Location scanner_error_location_; |
| 848 }; | 799 }; |
| 849 | 800 |
| 850 } // namespace internal | 801 } // namespace internal |
| 851 } // namespace v8 | 802 } // namespace v8 |
| 852 | 803 |
| 853 #endif // V8_PARSING_SCANNER_H_ | 804 #endif // V8_PARSING_SCANNER_H_ |
| OLD | NEW |