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 |