| Index: src/preparser-api.cc
|
| diff --git a/src/preparser-api.cc b/src/preparser-api.cc
|
| index f096e941b704ab29f3516176ea1aa000ed766bd7..df2cf2b4ebe8be31d369dd4a21ee7eccc0045d73 100644
|
| --- a/src/preparser-api.cc
|
| +++ b/src/preparser-api.cc
|
| @@ -39,39 +39,82 @@ namespace v8 {
|
| namespace internal {
|
|
|
| // UTF16Buffer based on a v8::UnicodeInputStream.
|
| -class InputStreamUTF16Buffer : public UTF16Buffer {
|
| +class InputStreamUTF16Buffer : public UC16CharacterStream {
|
| public:
|
| - explicit InputStreamUTF16Buffer(UnicodeInputStream* stream)
|
| - : UTF16Buffer(),
|
| - stream_(stream) { }
|
| + explicit InputStreamUTF16Buffer(v8::UnicodeInputStream* stream)
|
| + : UC16CharacterStream(),
|
| + stream_(stream),
|
| + pushback_active_(false) {
|
| + buffer_cursor_ = buffer_end_ = buffer_ + kPushBackSize;
|
| + }
|
|
|
| virtual ~InputStreamUTF16Buffer() { }
|
|
|
| - virtual void PushBack(uc32 ch) {
|
| + virtual void PushBack(uc16 ch) {
|
| + ASSERT(pos_ > 0);
|
| + if (buffer_cursor_ > buffer_) {
|
| + // While we can stay within the buffer, just do so.
|
| + *--buffer_cursor_ = ch;
|
| + pos_--;
|
| + return;
|
| + }
|
| + if (!pushback_active_) {
|
| + // Push back the entire buffer to the stream and let the
|
| + // stream handle pushbacks from now.
|
| + // We leave buffer_cursor_ == buffer_end_, so the next read
|
| + // will fill the buffer from the current position.
|
| + // This should happen exceedingly rarely.
|
| + while (buffer_end_ > buffer_) {
|
| + stream_->PushBack(*--buffer_end_);
|
| + }
|
| + buffer_cursor_ = buffer_end_;
|
| + pushback_active_ = true;
|
| + }
|
| stream_->PushBack(ch);
|
| pos_--;
|
| }
|
|
|
| - virtual uc32 Advance() {
|
| - uc32 result = stream_->Next();
|
| - if (result >= 0) pos_++;
|
| - return result;
|
| + protected:
|
| + virtual bool ReadBlock() {
|
| + // Copy the top of the buffer into the pushback area.
|
| + pushback_active_ = false;
|
| + int32_t value;
|
| + uc16* buffer_start = buffer_ + kPushBackSize;
|
| + buffer_cursor_ = buffer_end_ = buffer_start;
|
| + while ((value = stream_->Next()) >= 0) {
|
| + if (value > static_cast<int32_t>(unibrow::Utf8::kMaxThreeByteChar)) {
|
| + value = unibrow::Utf8::kBadChar;
|
| + }
|
| + // buffer_end_ is a const pointer, but buffer_ is writable.
|
| + buffer_start[buffer_end_++ - buffer_start] = static_cast<uc16>(value);
|
| + if (buffer_end_ == buffer_ + kPushBackSize + kBufferSize) break;
|
| + }
|
| + return buffer_end_ > buffer_start;
|
| }
|
|
|
| - virtual void SeekForward(int pos) {
|
| + virtual unsigned SlowSeekForward(unsigned pos) {
|
| // Seeking in the input is not used by preparsing.
|
| // It's only used by the real parser based on preparser data.
|
| UNIMPLEMENTED();
|
| + return 0;
|
| }
|
|
|
| private:
|
| + static const unsigned kBufferSize = 512;
|
| + static const unsigned kPushBackSize = 16;
|
| v8::UnicodeInputStream* const stream_;
|
| + // Buffer holding first kPushBackSize characters of pushback buffer,
|
| + // then kBufferSize chars of read-ahead.
|
| + // The pushback buffer is only used if pushing back characters past
|
| + // the start of a block.
|
| + uc16 buffer_[kBufferSize + kPushBackSize];
|
| + bool pushback_active_;
|
| };
|
|
|
|
|
| class StandAloneJavaScriptScanner : public JavaScriptScanner {
|
| public:
|
| - void Initialize(UTF16Buffer* source) {
|
| + void Initialize(UC16CharacterStream* source) {
|
| source_ = source;
|
| literal_flags_ = kLiteralString | kLiteralIdentifier;
|
| Init();
|
|
|