| 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
|
|
|