| 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/v8.h" | 5 #include "src/v8.h" | 
| 6 | 6 | 
| 7 #include "src/scanner-character-streams.h" | 7 #include "src/scanner-character-streams.h" | 
| 8 | 8 | 
| 9 #include "include/v8.h" | 9 #include "include/v8.h" | 
| 10 #include "src/handles.h" | 10 #include "src/handles.h" | 
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 349 | 349 | 
| 350       // A caveat: a data chunk might end with bytes from an incomplete UTF-8 | 350       // A caveat: a data chunk might end with bytes from an incomplete UTF-8 | 
| 351       // character (the rest of the bytes will be in the next chunk). | 351       // character (the rest of the bytes will be in the next chunk). | 
| 352       if (encoding_ == ScriptCompiler::StreamedSource::UTF8) { | 352       if (encoding_ == ScriptCompiler::StreamedSource::UTF8) { | 
| 353         HandleUtf8SplitCharacters(&data_in_buffer); | 353         HandleUtf8SplitCharacters(&data_in_buffer); | 
| 354         if (!data_ends && current_data_offset_ == current_data_length_) { | 354         if (!data_ends && current_data_offset_ == current_data_length_) { | 
| 355           // The data stream didn't end, but we used all the data in the | 355           // The data stream didn't end, but we used all the data in the | 
| 356           // chunk. This will only happen when the chunk was really small. We | 356           // chunk. This will only happen when the chunk was really small. We | 
| 357           // don't handle the case where a UTF-8 character is split over several | 357           // don't handle the case where a UTF-8 character is split over several | 
| 358           // chunks; in that case V8 won't crash, but it will be a parse error. | 358           // chunks; in that case V8 won't crash, but it will be a parse error. | 
| 359           delete[] current_data_; | 359           FlushCurrent(); | 
| 360           current_data_ = NULL; |  | 
| 361           current_data_length_ = 0; |  | 
| 362           current_data_offset_ = 0; |  | 
| 363           continue;  // Request a new chunk. | 360           continue;  // Request a new chunk. | 
| 364         } | 361         } | 
| 365       } | 362       } | 
| 366 | 363 | 
| 367       // Did the data stream end? | 364       // Did the data stream end? | 
| 368       if (data_ends) { | 365       if (data_ends) { | 
| 369         DCHECK(utf8_split_char_buffer_length_ == 0); | 366         DCHECK(utf8_split_char_buffer_length_ == 0); | 
| 370         return data_in_buffer; | 367         return data_in_buffer; | 
| 371       } | 368       } | 
| 372     } | 369     } | 
| 373 | 370 | 
| 374     // Fill the buffer from current_data_. | 371     // Fill the buffer from current_data_. | 
| 375     size_t new_offset = 0; | 372     size_t new_offset = 0; | 
| 376     size_t new_chars_in_buffer = | 373     size_t new_chars_in_buffer = | 
| 377         CopyCharsHelper(buffer_ + data_in_buffer, kBufferSize - data_in_buffer, | 374         CopyCharsHelper(buffer_ + data_in_buffer, kBufferSize - data_in_buffer, | 
| 378                         current_data_ + current_data_offset_, &new_offset, | 375                         current_data_ + current_data_offset_, &new_offset, | 
| 379                         current_data_length_ - current_data_offset_, encoding_); | 376                         current_data_length_ - current_data_offset_, encoding_); | 
| 380     data_in_buffer += new_chars_in_buffer; | 377     data_in_buffer += new_chars_in_buffer; | 
| 381     current_data_offset_ += new_offset; | 378     current_data_offset_ += new_offset; | 
| 382     DCHECK(data_in_buffer <= kBufferSize); | 379     DCHECK(data_in_buffer <= kBufferSize); | 
| 383 | 380 | 
| 384     // Did we use all the data in the data chunk? | 381     // Did we use all the data in the data chunk? | 
| 385     if (current_data_offset_ == current_data_length_) { | 382     if (current_data_offset_ == current_data_length_) { | 
| 386       delete[] current_data_; | 383       FlushCurrent(); | 
| 387       current_data_ = NULL; |  | 
| 388       current_data_length_ = 0; |  | 
| 389       current_data_offset_ = 0; |  | 
| 390     } | 384     } | 
| 391   } | 385   } | 
| 392   return data_in_buffer; | 386   return data_in_buffer; | 
| 393 } | 387 } | 
| 394 | 388 | 
|  | 389 | 
|  | 390 bool ExternalStreamingStream::SetBookmark() { | 
|  | 391   DCHECK(utf8_split_char_buffer_length_ == 0);  // We can't be within a char. | 
|  | 392 | 
|  | 393   // Bookmarking for this stream is a bit more complex than expected, since | 
|  | 394   // the stream state is distributed over several places: | 
|  | 395   // - pos_ (inherited from Utf16CharacterStream) | 
|  | 396   // - buffer_cursor_ and buffer_end_ (also from Utf16CharacterStream) | 
|  | 397   // - buffer_ (from BufferedUtf16CharacterStream) | 
|  | 398   // - current_data_ (+ .._offset_ and .._length) (this class) | 
|  | 399   // | 
|  | 400   // The underlying source_stream_ instance likely could re-construct this | 
|  | 401   // local data for us, but with the given interfaces we have no way of | 
|  | 402   // accomplishing this. Thus, we'll have to save all data locally. | 
|  | 403   // | 
|  | 404   // What gets saved where: | 
|  | 405   // - pos_  =>  bookmark_ | 
|  | 406   // - buffer_[buffer_cursor_ .. buffer_end_]  =>  bookmark_buffer_ | 
|  | 407   // - current_data_[.._offset_ .. .._length_]  =>  bookmark_data_ | 
|  | 408 | 
|  | 409   bookmark_ = pos_; | 
|  | 410 | 
|  | 411   int buffer_length = static_cast<int>(buffer_end_ - buffer_cursor_); | 
|  | 412   bookmark_buffer_.Dispose(); | 
|  | 413   bookmark_buffer_ = Vector<uint16_t>::New(buffer_length); | 
|  | 414   std::copy(buffer_cursor_, buffer_end_, bookmark_buffer_.start()); | 
|  | 415 | 
|  | 416   int data_length = | 
|  | 417       static_cast<int>(current_data_length_ - current_data_offset_); | 
|  | 418   bookmark_data_.Dispose(); | 
|  | 419   bookmark_data_ = Vector<uint8_t>::New(data_length); | 
|  | 420   std::copy(current_data_ + current_data_offset_, | 
|  | 421             current_data_ + current_data_length_, bookmark_data_.start()); | 
|  | 422 | 
|  | 423   return source_stream_->SetBookmark(); | 
|  | 424 } | 
|  | 425 | 
|  | 426 | 
|  | 427 void ExternalStreamingStream::ResetToBookmark() { | 
|  | 428   source_stream_->ResetToBookmark(); | 
|  | 429   FlushCurrent(); | 
|  | 430 | 
|  | 431   pos_ = bookmark_; | 
|  | 432 | 
|  | 433   // current_data_ can point to bookmark_data_'s buffer. | 
|  | 434   current_data_ = bookmark_data_.start(); | 
|  | 435   current_data_offset_ = 0; | 
|  | 436   current_data_length_ = bookmark_data_.length(); | 
|  | 437 | 
|  | 438   // bookmark_buffer_ needs to be copied to buffer_. | 
|  | 439   std::copy(bookmark_buffer_.begin(), bookmark_buffer_.end(), buffer_); | 
|  | 440   buffer_cursor_ = buffer_; | 
|  | 441   buffer_end_ = buffer_ + bookmark_buffer_.length(); | 
|  | 442 } | 
|  | 443 | 
|  | 444 | 
|  | 445 void ExternalStreamingStream::FlushCurrent() { | 
|  | 446   delete[] current_data_; | 
|  | 447   current_data_ = NULL; | 
|  | 448   current_data_length_ = 0; | 
|  | 449   current_data_offset_ = 0; | 
|  | 450 } | 
|  | 451 | 
|  | 452 | 
| 395 void ExternalStreamingStream::HandleUtf8SplitCharacters( | 453 void ExternalStreamingStream::HandleUtf8SplitCharacters( | 
| 396     size_t* data_in_buffer) { | 454     size_t* data_in_buffer) { | 
| 397   // Note the following property of UTF-8 which makes this function possible: | 455   // Note the following property of UTF-8 which makes this function possible: | 
| 398   // Given any byte, we can always read its local environment (in both | 456   // Given any byte, we can always read its local environment (in both | 
| 399   // directions) to find out the (possibly multi-byte) character it belongs | 457   // directions) to find out the (possibly multi-byte) character it belongs | 
| 400   // to. Single byte characters are of the form 0b0XXXXXXX. The first byte of a | 458   // to. Single byte characters are of the form 0b0XXXXXXX. The first byte of a | 
| 401   // multi-byte character is of the form 0b110XXXXX, 0b1110XXXX or | 459   // multi-byte character is of the form 0b110XXXXX, 0b1110XXXX or | 
| 402   // 0b11110XXX. The continuation bytes are of the form 0b10XXXXXX. | 460   // 0b11110XXX. The continuation bytes are of the form 0b10XXXXXX. | 
| 403 | 461 | 
| 404   // First check if we have leftover data from the last chunk. | 462   // First check if we have leftover data from the last chunk. | 
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 480   return true; | 538   return true; | 
| 481 } | 539 } | 
| 482 | 540 | 
| 483 | 541 | 
| 484 void ExternalTwoByteStringUtf16CharacterStream::ResetToBookmark() { | 542 void ExternalTwoByteStringUtf16CharacterStream::ResetToBookmark() { | 
| 485   DCHECK(bookmark_ != kNoBookmark); | 543   DCHECK(bookmark_ != kNoBookmark); | 
| 486   pos_ = bookmark_; | 544   pos_ = bookmark_; | 
| 487   buffer_cursor_ = raw_data_ + bookmark_; | 545   buffer_cursor_ = raw_data_ + bookmark_; | 
| 488 } | 546 } | 
| 489 } }  // namespace v8::internal | 547 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|