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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 #endif // DEBUG | 103 #endif // DEBUG |
104 } | 104 } |
105 void PushBack2(int32_t code_unit_back_1, int32_t code_unit_back_2) { | 105 void PushBack2(int32_t code_unit_back_1, int32_t code_unit_back_2) { |
106 Back2(); | 106 Back2(); |
107 #ifdef DEBUG | 107 #ifdef DEBUG |
108 DCHECK_EQ(Advance(), code_unit_back_2); | 108 DCHECK_EQ(Advance(), code_unit_back_2); |
109 DCHECK_EQ(Advance(), code_unit_back_1); | 109 DCHECK_EQ(Advance(), code_unit_back_1); |
110 Back2(); | 110 Back2(); |
111 #endif // DEBUG | 111 #endif // DEBUG |
112 } | 112 } |
113 bool SetBookmark() { | |
114 bookmark_ = pos(); | |
115 return true; | |
116 } | |
117 void ResetToBookmark() { | |
118 DCHECK_NE(bookmark_, kNoBookmark); | |
119 Seek(bookmark_); | |
120 } | |
121 | 113 |
122 protected: | 114 protected: |
123 static const size_t kNoBookmark; | |
124 | |
125 Utf16CharacterStream(const uint16_t* buffer_start, | 115 Utf16CharacterStream(const uint16_t* buffer_start, |
126 const uint16_t* buffer_cursor, | 116 const uint16_t* buffer_cursor, |
127 const uint16_t* buffer_end, size_t buffer_pos) | 117 const uint16_t* buffer_end, size_t buffer_pos) |
128 : buffer_start_(buffer_start), | 118 : buffer_start_(buffer_start), |
129 buffer_cursor_(buffer_cursor), | 119 buffer_cursor_(buffer_cursor), |
130 buffer_end_(buffer_end), | 120 buffer_end_(buffer_end), |
131 buffer_pos_(buffer_pos), | 121 buffer_pos_(buffer_pos) {} |
132 bookmark_(kNoBookmark) {} | |
133 Utf16CharacterStream() : Utf16CharacterStream(nullptr, nullptr, nullptr, 0) {} | 122 Utf16CharacterStream() : Utf16CharacterStream(nullptr, nullptr, nullptr, 0) {} |
134 | 123 |
135 void ReadBlockAt(size_t new_pos) { | 124 void ReadBlockAt(size_t new_pos) { |
136 // The callers of this method (Back/Back2/Seek) should handle the easy | 125 // The callers of this method (Back/Back2/Seek) should handle the easy |
137 // case (seeking within the current buffer), and we should only get here | 126 // case (seeking within the current buffer), and we should only get here |
138 // if we actually require new data. | 127 // if we actually require new data. |
139 // (This is really an efficiency check, not a correctness invariant.) | 128 // (This is really an efficiency check, not a correctness invariant.) |
140 DCHECK(new_pos < buffer_pos_ || | 129 DCHECK(new_pos < buffer_pos_ || |
141 new_pos >= buffer_pos_ + (buffer_end_ - buffer_start_)); | 130 new_pos >= buffer_pos_ + (buffer_end_ - buffer_start_)); |
142 | 131 |
(...skipping 23 matching lines...) Expand all Loading... |
166 // - a stream with existing buffer chunks would set buffer_start_ and | 155 // - a stream with existing buffer chunks would set buffer_start_ and |
167 // buffer_end_ to cover the full chunk, and then buffer_cursor_ would | 156 // buffer_end_ to cover the full chunk, and then buffer_cursor_ would |
168 // point into the middle of the buffer, while buffer_pos_ would describe | 157 // point into the middle of the buffer, while buffer_pos_ would describe |
169 // the start of the buffer. | 158 // the start of the buffer. |
170 virtual bool ReadBlock() = 0; | 159 virtual bool ReadBlock() = 0; |
171 | 160 |
172 const uint16_t* buffer_start_; | 161 const uint16_t* buffer_start_; |
173 const uint16_t* buffer_cursor_; | 162 const uint16_t* buffer_cursor_; |
174 const uint16_t* buffer_end_; | 163 const uint16_t* buffer_end_; |
175 size_t buffer_pos_; | 164 size_t buffer_pos_; |
176 size_t bookmark_; | |
177 }; | 165 }; |
178 | 166 |
179 | 167 |
180 // ---------------------------------------------------------------------------- | 168 // ---------------------------------------------------------------------------- |
181 // JavaScript Scanner. | 169 // JavaScript Scanner. |
182 | 170 |
183 class Scanner { | 171 class Scanner { |
184 public: | 172 public: |
185 // Scoped helper for a re-settable bookmark. | 173 // Scoped helper for a re-settable bookmark. |
186 class BookmarkScope { | 174 class BookmarkScope { |
187 public: | 175 public: |
188 explicit BookmarkScope(Scanner* scanner) : scanner_(scanner) { | 176 explicit BookmarkScope(Scanner* scanner) |
| 177 : scanner_(scanner), bookmark_(kNoBookmark) { |
189 DCHECK_NOT_NULL(scanner_); | 178 DCHECK_NOT_NULL(scanner_); |
190 } | 179 } |
191 ~BookmarkScope() { scanner_->DropBookmark(); } | 180 ~BookmarkScope() {} |
192 | 181 |
193 bool Set() { return scanner_->SetBookmark(); } | 182 void Set(); |
194 void Reset() { scanner_->ResetToBookmark(); } | 183 void Reset(); |
195 bool HasBeenSet() { return scanner_->BookmarkHasBeenSet(); } | 184 bool HasBeenSet(); |
196 bool HasBeenReset() { return scanner_->BookmarkHasBeenReset(); } | 185 bool HasBeenReset(); |
197 | 186 |
198 private: | 187 private: |
| 188 static const size_t kNoBookmark; |
| 189 static const size_t kBookmarkWasApplied; |
| 190 |
199 Scanner* scanner_; | 191 Scanner* scanner_; |
| 192 size_t bookmark_; |
200 | 193 |
201 DISALLOW_COPY_AND_ASSIGN(BookmarkScope); | 194 DISALLOW_COPY_AND_ASSIGN(BookmarkScope); |
202 }; | 195 }; |
203 | 196 |
204 // Representation of an interval of source positions. | 197 // Representation of an interval of source positions. |
205 struct Location { | 198 struct Location { |
206 Location(int b, int e) : beg_pos(b), end_pos(e) { } | 199 Location(int b, int e) : beg_pos(b), end_pos(e) { } |
207 Location() : beg_pos(0), end_pos(0) { } | 200 Location() : beg_pos(0), end_pos(0) { } |
208 | 201 |
209 bool IsValid() const { | 202 bool IsValid() const { |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 position_ -= delta * (is_one_byte_ ? kOneByteSize : kUC16Size); | 435 position_ -= delta * (is_one_byte_ ? kOneByteSize : kUC16Size); |
443 } | 436 } |
444 | 437 |
445 void Reset() { | 438 void Reset() { |
446 position_ = 0; | 439 position_ = 0; |
447 is_one_byte_ = true; | 440 is_one_byte_ = true; |
448 } | 441 } |
449 | 442 |
450 Handle<String> Internalize(Isolate* isolate) const; | 443 Handle<String> Internalize(Isolate* isolate) const; |
451 | 444 |
452 void CopyFrom(const LiteralBuffer* other) { | |
453 if (other == nullptr) { | |
454 Reset(); | |
455 } else { | |
456 is_one_byte_ = other->is_one_byte_; | |
457 position_ = other->position_; | |
458 if (position_ < backing_store_.length()) { | |
459 std::copy(other->backing_store_.begin(), | |
460 other->backing_store_.begin() + position_, | |
461 backing_store_.begin()); | |
462 } else { | |
463 backing_store_.Dispose(); | |
464 backing_store_ = other->backing_store_.Clone(); | |
465 } | |
466 } | |
467 } | |
468 | |
469 private: | 445 private: |
470 static const int kInitialCapacity = 16; | 446 static const int kInitialCapacity = 16; |
471 static const int kGrowthFactory = 4; | 447 static const int kGrowthFactory = 4; |
472 static const int kMinConversionSlack = 256; | 448 static const int kMinConversionSlack = 256; |
473 static const int kMaxGrowth = 1 * MB; | 449 static const int kMaxGrowth = 1 * MB; |
474 | 450 |
475 inline bool IsValidAscii(char code_unit) { | 451 inline bool IsValidAscii(char code_unit) { |
476 // Control characters and printable characters span the range of | 452 // Control characters and printable characters span the range of |
477 // valid ASCII characters (0-127). Chars are unsigned on some | 453 // valid ASCII characters (0-127). Chars are unsigned on some |
478 // platforms which causes compiler warnings if the validity check | 454 // platforms which causes compiler warnings if the validity check |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 next_.token = Token::UNINITIALIZED; | 528 next_.token = Token::UNINITIALIZED; |
553 next_.literal_chars = NULL; | 529 next_.literal_chars = NULL; |
554 next_.raw_literal_chars = NULL; | 530 next_.raw_literal_chars = NULL; |
555 next_next_.token = Token::UNINITIALIZED; | 531 next_next_.token = Token::UNINITIALIZED; |
556 next_next_.literal_chars = NULL; | 532 next_next_.literal_chars = NULL; |
557 next_next_.raw_literal_chars = NULL; | 533 next_next_.raw_literal_chars = NULL; |
558 found_html_comment_ = false; | 534 found_html_comment_ = false; |
559 scanner_error_ = MessageTemplate::kNone; | 535 scanner_error_ = MessageTemplate::kNone; |
560 } | 536 } |
561 | 537 |
562 // Support BookmarkScope functionality. | |
563 bool SetBookmark(); | |
564 void ResetToBookmark(); | |
565 bool BookmarkHasBeenSet(); | |
566 bool BookmarkHasBeenReset(); | |
567 void DropBookmark(); | |
568 void CopyToNextTokenDesc(TokenDesc* from); | |
569 static void CopyTokenDesc(TokenDesc* to, TokenDesc* from); | |
570 | |
571 void ReportScannerError(const Location& location, | 538 void ReportScannerError(const Location& location, |
572 MessageTemplate::Template error) { | 539 MessageTemplate::Template error) { |
573 if (has_error()) return; | 540 if (has_error()) return; |
574 scanner_error_ = error; | 541 scanner_error_ = error; |
575 scanner_error_location_ = location; | 542 scanner_error_location_ = location; |
576 } | 543 } |
577 | 544 |
578 void ReportScannerError(int pos, MessageTemplate::Template error) { | 545 void ReportScannerError(int pos, MessageTemplate::Template error) { |
579 if (has_error()) return; | 546 if (has_error()) return; |
580 scanner_error_ = error; | 547 scanner_error_ = error; |
581 scanner_error_location_ = Location(pos, pos + 1); | 548 scanner_error_location_ = Location(pos, pos + 1); |
582 } | 549 } |
583 | 550 |
| 551 void Seek(size_t position); |
| 552 |
584 // Literal buffer support | 553 // Literal buffer support |
585 inline void StartLiteral() { | 554 inline void StartLiteral() { |
586 LiteralBuffer* free_buffer = | 555 LiteralBuffer* free_buffer = |
587 (current_.literal_chars == &literal_buffer0_) | 556 (current_.literal_chars == &literal_buffer0_) |
588 ? &literal_buffer1_ | 557 ? &literal_buffer1_ |
589 : (current_.literal_chars == &literal_buffer1_) ? &literal_buffer2_ | 558 : (current_.literal_chars == &literal_buffer1_) ? &literal_buffer2_ |
590 : &literal_buffer0_; | 559 : &literal_buffer0_; |
591 free_buffer->Reset(); | 560 free_buffer->Reset(); |
592 next_.literal_chars = free_buffer; | 561 next_.literal_chars = free_buffer; |
593 } | 562 } |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
814 | 783 |
815 // Buffer to store raw string values | 784 // Buffer to store raw string values |
816 LiteralBuffer raw_literal_buffer0_; | 785 LiteralBuffer raw_literal_buffer0_; |
817 LiteralBuffer raw_literal_buffer1_; | 786 LiteralBuffer raw_literal_buffer1_; |
818 LiteralBuffer raw_literal_buffer2_; | 787 LiteralBuffer raw_literal_buffer2_; |
819 | 788 |
820 TokenDesc current_; // desc for current token (as returned by Next()) | 789 TokenDesc current_; // desc for current token (as returned by Next()) |
821 TokenDesc next_; // desc for next token (one token look-ahead) | 790 TokenDesc next_; // desc for next token (one token look-ahead) |
822 TokenDesc next_next_; // desc for the token after next (after PeakAhead()) | 791 TokenDesc next_next_; // desc for the token after next (after PeakAhead()) |
823 | 792 |
824 // Variables for Scanner::BookmarkScope and the *Bookmark implementation. | |
825 // These variables contain the scanner state when a bookmark is set. | |
826 // | |
827 // We will use bookmark_c0_ as a 'control' variable, where: | |
828 // - bookmark_c0_ >= 0: A bookmark has been set and this contains c0_. | |
829 // - bookmark_c0_ == -1: No bookmark has been set. | |
830 // - bookmark_c0_ == -2: The bookmark has been applied (ResetToBookmark). | |
831 // | |
832 // Which state is being bookmarked? The parser state is distributed over | |
833 // several variables, roughly like this: | |
834 // ... 1234 + 5678 ..... [character stream] | |
835 // [current_] [next_] c0_ | [scanner state] | |
836 // So when the scanner is logically at the beginning of an expression | |
837 // like "1234 + 4567", then: | |
838 // - current_ contains "1234" | |
839 // - next_ contains "+" | |
840 // - c0_ contains ' ' (the space between "+" and "5678", | |
841 // - the source_ character stream points to the beginning of "5678". | |
842 // To be able to restore this state, we will keep copies of current_, next_, | |
843 // and c0_; we'll ask the stream to bookmark itself, and we'll copy the | |
844 // contents of current_'s and next_'s literal buffers to bookmark_*_literal_. | |
845 static const uc32 kNoBookmark = -1; | |
846 static const uc32 kBookmarkWasApplied = -2; | |
847 uc32 bookmark_c0_; | |
848 TokenDesc bookmark_current_; | |
849 TokenDesc bookmark_next_; | |
850 LiteralBuffer bookmark_current_literal_; | |
851 LiteralBuffer bookmark_current_raw_literal_; | |
852 LiteralBuffer bookmark_next_literal_; | |
853 LiteralBuffer bookmark_next_raw_literal_; | |
854 | |
855 // Input stream. Must be initialized to an Utf16CharacterStream. | 793 // Input stream. Must be initialized to an Utf16CharacterStream. |
856 Utf16CharacterStream* source_; | 794 Utf16CharacterStream* source_; |
857 | 795 |
858 // Last-seen positions of potentially problematic tokens. | 796 // Last-seen positions of potentially problematic tokens. |
859 Location octal_pos_; | 797 Location octal_pos_; |
860 Location decimal_with_leading_zero_pos_; | 798 Location decimal_with_leading_zero_pos_; |
861 | 799 |
862 // One Unicode character look-ahead; c0_ < 0 at the end of the input. | 800 // One Unicode character look-ahead; c0_ < 0 at the end of the input. |
863 uc32 c0_; | 801 uc32 c0_; |
864 | 802 |
(...skipping 10 matching lines...) Expand all Loading... |
875 bool found_html_comment_; | 813 bool found_html_comment_; |
876 | 814 |
877 MessageTemplate::Template scanner_error_; | 815 MessageTemplate::Template scanner_error_; |
878 Location scanner_error_location_; | 816 Location scanner_error_location_; |
879 }; | 817 }; |
880 | 818 |
881 } // namespace internal | 819 } // namespace internal |
882 } // namespace v8 | 820 } // namespace v8 |
883 | 821 |
884 #endif // V8_PARSING_SCANNER_H_ | 822 #endif // V8_PARSING_SCANNER_H_ |
OLD | NEW |