Index: src/scanner.cc |
=================================================================== |
--- src/scanner.cc (revision 3995) |
+++ src/scanner.cc (working copy) |
@@ -28,6 +28,7 @@ |
#include "v8.h" |
#include "ast.h" |
+#include "handles.h" |
#include "scanner.h" |
namespace v8 { |
@@ -86,24 +87,23 @@ |
UTF16Buffer::UTF16Buffer() |
- : pos_(0), size_(0) { } |
+ : pos_(0), end_(Scanner::kNoEndPosition) { } |
-Handle<String> UTF16Buffer::SubString(int start, int end) { |
- return internal::SubString(data_, start, end); |
-} |
- |
- |
// CharacterStreamUTF16Buffer |
CharacterStreamUTF16Buffer::CharacterStreamUTF16Buffer() |
: pushback_buffer_(0), last_(0), stream_(NULL) { } |
void CharacterStreamUTF16Buffer::Initialize(Handle<String> data, |
- unibrow::CharacterStream* input) { |
- data_ = data; |
- pos_ = 0; |
+ unibrow::CharacterStream* input, |
+ int start_position, |
+ int end_position) { |
stream_ = input; |
+ if (start_position > 0) { |
+ SeekForward(start_position); |
+ } |
+ end_ = end_position != Scanner::kNoEndPosition ? end_position : kMaxInt; |
} |
@@ -115,6 +115,8 @@ |
uc32 CharacterStreamUTF16Buffer::Advance() { |
+ ASSERT(end_ != Scanner::kNoEndPosition); |
+ ASSERT(end_ >= 0); |
// NOTE: It is of importance to Persian / Farsi resources that we do |
// *not* strip format control characters in the scanner; see |
// |
@@ -126,7 +128,7 @@ |
if (!pushback_buffer()->is_empty()) { |
pos_++; |
return last_ = pushback_buffer()->RemoveLast(); |
- } else if (stream_->has_more()) { |
+ } else if (stream_->has_more() && pos_ < end_) { |
pos_++; |
uc32 next = stream_->GetNext(); |
return last_ = next; |
@@ -146,25 +148,32 @@ |
} |
-// TwoByteStringUTF16Buffer |
-TwoByteStringUTF16Buffer::TwoByteStringUTF16Buffer() |
+// ExternalStringUTF16Buffer |
+template <typename StringType, typename CharType> |
+ExternalStringUTF16Buffer<StringType, CharType>::ExternalStringUTF16Buffer() |
: raw_data_(NULL) { } |
-void TwoByteStringUTF16Buffer::Initialize( |
- Handle<ExternalTwoByteString> data) { |
+template <typename StringType, typename CharType> |
+void ExternalStringUTF16Buffer<StringType, CharType>::Initialize( |
+ Handle<StringType> data, |
+ int start_position, |
+ int end_position) { |
ASSERT(!data.is_null()); |
+ raw_data_ = data->resource()->data(); |
- data_ = data; |
- pos_ = 0; |
- |
- raw_data_ = data->resource()->data(); |
- size_ = data->length(); |
+ ASSERT(end_position <= data->length()); |
+ if (start_position > 0) { |
+ SeekForward(start_position); |
+ } |
+ end_ = |
+ end_position != Scanner::kNoEndPosition ? end_position : data->length(); |
} |
-uc32 TwoByteStringUTF16Buffer::Advance() { |
- if (pos_ < size_) { |
+template <typename StringType, typename CharType> |
+uc32 ExternalStringUTF16Buffer<StringType, CharType>::Advance() { |
+ if (pos_ < end_) { |
return raw_data_[pos_++]; |
} else { |
// note: currently the following increment is necessary to avoid a |
@@ -175,14 +184,16 @@ |
} |
-void TwoByteStringUTF16Buffer::PushBack(uc32 ch) { |
+template <typename StringType, typename CharType> |
+void ExternalStringUTF16Buffer<StringType, CharType>::PushBack(uc32 ch) { |
pos_--; |
ASSERT(pos_ >= Scanner::kCharacterLookaheadBufferSize); |
ASSERT(raw_data_[pos_ - Scanner::kCharacterLookaheadBufferSize] == ch); |
} |
-void TwoByteStringUTF16Buffer::SeekForward(int pos) { |
+template <typename StringType, typename CharType> |
+void ExternalStringUTF16Buffer<StringType, CharType>::SeekForward(int pos) { |
pos_ = pos; |
} |
@@ -327,21 +338,56 @@ |
: stack_overflow_(false), is_pre_parsing_(pre == PREPARSE) { } |
+void Scanner::Initialize(Handle<String> source, |
+ ParserLanguage language) { |
+ safe_string_input_buffer_.Reset(source.location()); |
+ Init(source, &safe_string_input_buffer_, 0, source->length(), language); |
+} |
+ |
+ |
+void Scanner::Initialize(Handle<String> source, |
+ unibrow::CharacterStream* stream, |
+ ParserLanguage language) { |
+ Init(source, stream, 0, kNoEndPosition, language); |
+} |
+ |
+ |
+void Scanner::Initialize(Handle<String> source, |
+ int start_position, |
+ int end_position, |
+ ParserLanguage language) { |
+ safe_string_input_buffer_.Reset(source.location()); |
+ Init(source, &safe_string_input_buffer_, |
+ start_position, end_position, language); |
+} |
+ |
+ |
void Scanner::Init(Handle<String> source, |
unibrow::CharacterStream* stream, |
- int position, |
+ int start_position, |
+ int end_position, |
ParserLanguage language) { |
// Initialize the source buffer. |
if (!source.is_null() && StringShape(*source).IsExternalTwoByte()) { |
two_byte_string_buffer_.Initialize( |
- Handle<ExternalTwoByteString>::cast(source)); |
+ Handle<ExternalTwoByteString>::cast(source), |
+ start_position, |
+ end_position); |
source_ = &two_byte_string_buffer_; |
+ } else if (!source.is_null() && StringShape(*source).IsExternalAscii()) { |
+ ascii_string_buffer_.Initialize( |
+ Handle<ExternalAsciiString>::cast(source), |
+ start_position, |
+ end_position); |
+ source_ = &ascii_string_buffer_; |
} else { |
- char_stream_buffer_.Initialize(source, stream); |
+ char_stream_buffer_.Initialize(source, |
+ stream, |
+ start_position, |
+ end_position); |
source_ = &char_stream_buffer_; |
} |
- position_ = position; |
is_parsing_json_ = (language == JSON); |
// Set c0_ (one character ahead) |
@@ -358,11 +404,6 @@ |
} |
-Handle<String> Scanner::SubString(int start, int end) { |
- return source_->SubString(start - position_, end - position_); |
-} |
- |
- |
Token::Value Scanner::Next() { |
// BUG 1215673: Find a thread safe way to set a stack limit in |
// pre-parse mode. Otherwise, we cannot safely pre-parse from other |