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 #include "src/parsing/scanner-character-streams.h" | 5 #include "src/parsing/scanner-character-streams.h" |
6 | 6 |
7 #include "include/v8.h" | 7 #include "include/v8.h" |
8 #include "src/globals.h" | 8 #include "src/globals.h" |
9 #include "src/handles.h" | 9 #include "src/handles.h" |
10 #include "src/objects-inl.h" | 10 #include "src/objects-inl.h" |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 | 342 |
343 void Utf8ExternalStreamingStream::SearchPosition(size_t position) { | 343 void Utf8ExternalStreamingStream::SearchPosition(size_t position) { |
344 // If current_ already points to the right position, we're done. | 344 // If current_ already points to the right position, we're done. |
345 // | 345 // |
346 // This is expected to be the common case, since we typically call | 346 // This is expected to be the common case, since we typically call |
347 // FillBuffer right after the current buffer. | 347 // FillBuffer right after the current buffer. |
348 if (current_.pos.chars == position) return; | 348 if (current_.pos.chars == position) return; |
349 | 349 |
350 // No chunks. Fetch at least one, so we can assume !chunks_.empty() below. | 350 // No chunks. Fetch at least one, so we can assume !chunks_.empty() below. |
351 if (chunks_.empty()) { | 351 if (chunks_.empty()) { |
352 DCHECK_EQ(current_.chunk_no, 0); | 352 DCHECK_EQ(current_.chunk_no, 0u); |
353 DCHECK_EQ(current_.pos.bytes, 0); | 353 DCHECK_EQ(current_.pos.bytes, 0u); |
354 DCHECK_EQ(current_.pos.chars, 0); | 354 DCHECK_EQ(current_.pos.chars, 0u); |
355 FetchChunk(); | 355 FetchChunk(); |
356 } | 356 } |
357 | 357 |
358 // Search for the last chunk whose start position is less or equal to | 358 // Search for the last chunk whose start position is less or equal to |
359 // position. | 359 // position. |
360 size_t chunk_no = chunks_.size() - 1; | 360 size_t chunk_no = chunks_.size() - 1; |
361 while (chunk_no > 0 && chunks_[chunk_no].start.chars > position) { | 361 while (chunk_no > 0 && chunks_[chunk_no].start.chars > position) { |
362 chunk_no--; | 362 chunk_no--; |
363 } | 363 } |
364 | 364 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 // (The embedder might give us 1-byte blocks within a utf-8 char, so we | 431 // (The embedder might give us 1-byte blocks within a utf-8 char, so we |
432 // can't guarantee progress with one chunk. Thus we iterate.) | 432 // can't guarantee progress with one chunk. Thus we iterate.) |
433 while (!out_of_data && buffer_cursor_ == buffer_end_) { | 433 while (!out_of_data && buffer_cursor_ == buffer_end_) { |
434 // At end of current data, but there might be more? Then fetch it. | 434 // At end of current data, but there might be more? Then fetch it. |
435 if (current_.chunk_no == chunks_.size()) { | 435 if (current_.chunk_no == chunks_.size()) { |
436 out_of_data = !FetchChunk(); | 436 out_of_data = !FetchChunk(); |
437 } | 437 } |
438 FillBufferFromCurrentChunk(); | 438 FillBufferFromCurrentChunk(); |
439 } | 439 } |
440 | 440 |
441 DCHECK_EQ(current_.pos.chars - position, buffer_end_ - buffer_cursor_); | 441 DCHECK_EQ(current_.pos.chars - position, |
| 442 static_cast<size_t>(buffer_end_ - buffer_cursor_)); |
442 return buffer_end_ - buffer_cursor_; | 443 return buffer_end_ - buffer_cursor_; |
443 } | 444 } |
444 | 445 |
445 // ---------------------------------------------------------------------------- | 446 // ---------------------------------------------------------------------------- |
446 // Chunks - helper for One- + TwoByteExternalStreamingStream | 447 // Chunks - helper for One- + TwoByteExternalStreamingStream |
447 namespace { | 448 namespace { |
448 | 449 |
449 struct Chunk { | 450 struct Chunk { |
450 const uint8_t* data; | 451 const uint8_t* data; |
451 size_t byte_length; | 452 size_t byte_length; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 // chunk to indicate the end of the stream. | 491 // chunk to indicate the end of the stream. |
491 if (position >= end_pos) { | 492 if (position >= end_pos) { |
492 DCHECK(out_of_data); | 493 DCHECK(out_of_data); |
493 return chunks.size() - 1; | 494 return chunks.size() - 1; |
494 } | 495 } |
495 | 496 |
496 // We almost always 'stream', meaning we want data from the last chunk, so | 497 // We almost always 'stream', meaning we want data from the last chunk, so |
497 // let's look at chunks back-to-front. | 498 // let's look at chunks back-to-front. |
498 size_t chunk_no = chunks.size() - 1; | 499 size_t chunk_no = chunks.size() - 1; |
499 while (chunks[chunk_no].byte_pos > position) { | 500 while (chunks[chunk_no].byte_pos > position) { |
500 DCHECK_NE(chunk_no, 0); | 501 DCHECK_NE(chunk_no, 0u); |
501 chunk_no--; | 502 chunk_no--; |
502 } | 503 } |
503 DCHECK_LE(chunks[chunk_no].byte_pos, position); | 504 DCHECK_LE(chunks[chunk_no].byte_pos, position); |
504 DCHECK_LT(position, chunks[chunk_no].byte_pos + chunks[chunk_no].byte_length); | 505 DCHECK_LT(position, chunks[chunk_no].byte_pos + chunks[chunk_no].byte_length); |
505 return chunk_no; | 506 return chunk_no; |
506 } | 507 } |
507 | 508 |
508 } // anonymous namespace | 509 } // anonymous namespace |
509 | 510 |
510 // ---------------------------------------------------------------------------- | 511 // ---------------------------------------------------------------------------- |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 } | 587 } |
587 | 588 |
588 Chunk& current = chunks_[chunk_no]; | 589 Chunk& current = chunks_[chunk_no]; |
589 | 590 |
590 // Annoying edge case: Chunks may not be 2-byte aligned, meaning that a | 591 // Annoying edge case: Chunks may not be 2-byte aligned, meaning that a |
591 // character may be split between the previous and the current chunk. | 592 // character may be split between the previous and the current chunk. |
592 // If we find such a lonely byte at the beginning of the chunk, we'll use | 593 // If we find such a lonely byte at the beginning of the chunk, we'll use |
593 // one_char_buffer_ to hold the full character. | 594 // one_char_buffer_ to hold the full character. |
594 bool lonely_byte = (chunks_[chunk_no].byte_pos == (2 * position + 1)); | 595 bool lonely_byte = (chunks_[chunk_no].byte_pos == (2 * position + 1)); |
595 if (lonely_byte) { | 596 if (lonely_byte) { |
596 DCHECK_NE(chunk_no, 0); | 597 DCHECK_NE(chunk_no, 0u); |
597 Chunk& previous_chunk = chunks_[chunk_no - 1]; | 598 Chunk& previous_chunk = chunks_[chunk_no - 1]; |
598 #ifdef V8_TARGET_BIG_ENDIAN | 599 #ifdef V8_TARGET_BIG_ENDIAN |
599 uc16 character = current.data[0] | | 600 uc16 character = current.data[0] | |
600 previous_chunk.data[previous_chunk.byte_length - 1] << 8; | 601 previous_chunk.data[previous_chunk.byte_length - 1] << 8; |
601 #else | 602 #else |
602 uc16 character = previous_chunk.data[previous_chunk.byte_length - 1] | | 603 uc16 character = previous_chunk.data[previous_chunk.byte_length - 1] | |
603 current.data[0] << 8; | 604 current.data[0] << 8; |
604 #endif | 605 #endif |
605 | 606 |
606 one_char_buffer_ = character; | 607 one_char_buffer_ = character; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 buffer_cursor_ = buffer_; | 709 buffer_cursor_ = buffer_; |
709 buffer_end_ = buffer_ + FillBuffer(position, chunk_no); | 710 buffer_end_ = buffer_ + FillBuffer(position, chunk_no); |
710 DCHECK_EQ(pos(), position); | 711 DCHECK_EQ(pos(), position); |
711 DCHECK_LE(buffer_end_, buffer_start_ + kBufferSize); | 712 DCHECK_LE(buffer_end_, buffer_start_ + kBufferSize); |
712 return buffer_cursor_ < buffer_end_; | 713 return buffer_cursor_ < buffer_end_; |
713 } | 714 } |
714 } | 715 } |
715 | 716 |
716 size_t TwoByteExternalBufferedStream::FillBuffer(size_t position, | 717 size_t TwoByteExternalBufferedStream::FillBuffer(size_t position, |
717 size_t chunk_no) { | 718 size_t chunk_no) { |
718 DCHECK_EQ(chunks_[chunk_no].byte_pos % 2, 1); | 719 DCHECK_EQ(chunks_[chunk_no].byte_pos % 2, 1u); |
719 bool odd_start = true; | 720 bool odd_start = true; |
720 // Align buffer_pos_ to the size of the buffer. | 721 // Align buffer_pos_ to the size of the buffer. |
721 { | 722 { |
722 size_t new_pos = position / kBufferSize * kBufferSize; | 723 size_t new_pos = position / kBufferSize * kBufferSize; |
723 if (new_pos != position) { | 724 if (new_pos != position) { |
724 chunk_no = FindChunk(chunks_, source_, 2 * new_pos + 1); | 725 chunk_no = FindChunk(chunks_, source_, 2 * new_pos + 1); |
725 buffer_pos_ = new_pos; | 726 buffer_pos_ = new_pos; |
726 buffer_cursor_ = buffer_start_ + (position - buffer_pos_); | 727 buffer_cursor_ = buffer_start_ + (position - buffer_pos_); |
727 position = new_pos; | 728 position = new_pos; |
728 odd_start = chunks_[chunk_no].byte_pos % 2; | 729 odd_start = chunks_[chunk_no].byte_pos % 2; |
729 } | 730 } |
730 } | 731 } |
731 | 732 |
732 Chunk* current = &chunks_[chunk_no]; | 733 Chunk* current = &chunks_[chunk_no]; |
733 | 734 |
734 // Annoying edge case: Chunks may not be 2-byte aligned, meaning that a | 735 // Annoying edge case: Chunks may not be 2-byte aligned, meaning that a |
735 // character may be split between the previous and the current chunk. | 736 // character may be split between the previous and the current chunk. |
736 // If we find such a lonely byte at the beginning of the chunk, we'll copy | 737 // If we find such a lonely byte at the beginning of the chunk, we'll copy |
737 // it to the first byte in buffer_. | 738 // it to the first byte in buffer_. |
738 size_t totalLength = 0; | 739 size_t totalLength = 0; |
739 bool lonely_byte = (current->byte_pos == (2 * position + 1)); | 740 bool lonely_byte = (current->byte_pos == (2 * position + 1)); |
740 if (lonely_byte) { | 741 if (lonely_byte) { |
741 DCHECK_NE(chunk_no, 0); | 742 DCHECK_NE(chunk_no, 0u); |
742 Chunk& previous_chunk = chunks_[chunk_no - 1]; | 743 Chunk& previous_chunk = chunks_[chunk_no - 1]; |
743 *reinterpret_cast<uint8_t*>(buffer_) = | 744 *reinterpret_cast<uint8_t*>(buffer_) = |
744 previous_chunk.data[previous_chunk.byte_length - 1]; | 745 previous_chunk.data[previous_chunk.byte_length - 1]; |
745 totalLength++; | 746 totalLength++; |
746 } | 747 } |
747 | 748 |
748 // Common case: character is in current chunk. | 749 // Common case: character is in current chunk. |
749 DCHECK_LE(current->byte_pos, 2 * position + odd_start); | 750 DCHECK_LE(current->byte_pos, 2 * position + odd_start); |
750 DCHECK_LT(2 * position + 1, current->byte_pos + current->byte_length); | 751 DCHECK_LT(2 * position + 1, current->byte_pos + current->byte_length); |
751 | 752 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 return new OneByteExternalStreamingStream(source_stream); | 836 return new OneByteExternalStreamingStream(source_stream); |
836 case v8::ScriptCompiler::StreamedSource::UTF8: | 837 case v8::ScriptCompiler::StreamedSource::UTF8: |
837 return new Utf8ExternalStreamingStream(source_stream); | 838 return new Utf8ExternalStreamingStream(source_stream); |
838 } | 839 } |
839 UNREACHABLE(); | 840 UNREACHABLE(); |
840 return nullptr; | 841 return nullptr; |
841 } | 842 } |
842 | 843 |
843 } // namespace internal | 844 } // namespace internal |
844 } // namespace v8 | 845 } // namespace v8 |
OLD | NEW |