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 // Features shared by parsing and pre-parsing scanners. | 5 // Features shared by parsing and pre-parsing scanners. |
6 | 6 |
7 #ifndef V8_PARSING_SCANNER_H_ | 7 #ifndef V8_PARSING_SCANNER_H_ |
8 #define V8_PARSING_SCANNER_H_ | 8 #define V8_PARSING_SCANNER_H_ |
9 | 9 |
10 #include "src/allocation.h" | 10 #include "src/allocation.h" |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 }; | 346 }; |
347 | 347 |
348 // LiteralBuffer - Collector of chars of literals. | 348 // LiteralBuffer - Collector of chars of literals. |
349 class LiteralBuffer { | 349 class LiteralBuffer { |
350 public: | 350 public: |
351 LiteralBuffer() : is_one_byte_(true), position_(0), backing_store_() {} | 351 LiteralBuffer() : is_one_byte_(true), position_(0), backing_store_() {} |
352 | 352 |
353 ~LiteralBuffer() { backing_store_.Dispose(); } | 353 ~LiteralBuffer() { backing_store_.Dispose(); } |
354 | 354 |
355 INLINE(void AddChar(char code_unit)) { | 355 INLINE(void AddChar(char code_unit)) { |
356 if (position_ >= backing_store_.length()) ExpandBuffer(); | |
357 DCHECK(is_one_byte_); | |
358 DCHECK(IsValidAscii(code_unit)); | 356 DCHECK(IsValidAscii(code_unit)); |
359 backing_store_[position_] = static_cast<byte>(code_unit); | 357 AddOneByteChar(static_cast<byte>(code_unit)); |
360 position_ += kOneByteSize; | |
361 return; | |
362 } | 358 } |
363 | 359 |
364 INLINE(void AddChar(uc32 code_unit)) { | 360 INLINE(void AddChar(uc32 code_unit)) { |
365 if (position_ >= backing_store_.length()) ExpandBuffer(); | 361 if (is_one_byte_ && |
366 if (is_one_byte_) { | 362 code_unit <= static_cast<uc32>(unibrow::Latin1::kMaxChar)) { |
367 if (code_unit <= static_cast<uc32>(unibrow::Latin1::kMaxChar)) { | 363 AddOneByteChar(static_cast<byte>(code_unit)); |
368 backing_store_[position_] = static_cast<byte>(code_unit); | |
369 position_ += kOneByteSize; | |
370 return; | |
371 } | |
372 ConvertToTwoByte(); | |
373 } | |
374 if (code_unit <= | |
375 static_cast<uc32>(unibrow::Utf16::kMaxNonSurrogateCharCode)) { | |
376 *reinterpret_cast<uint16_t*>(&backing_store_[position_]) = code_unit; | |
377 position_ += kUC16Size; | |
378 } else { | 364 } else { |
379 *reinterpret_cast<uint16_t*>(&backing_store_[position_]) = | 365 AddCharSlow(code_unit); |
380 unibrow::Utf16::LeadSurrogate(code_unit); | |
381 position_ += kUC16Size; | |
382 if (position_ >= backing_store_.length()) ExpandBuffer(); | |
383 *reinterpret_cast<uint16_t*>(&backing_store_[position_]) = | |
384 unibrow::Utf16::TrailSurrogate(code_unit); | |
385 position_ += kUC16Size; | |
386 } | 366 } |
387 } | 367 } |
388 | 368 |
389 bool is_one_byte() const { return is_one_byte_; } | 369 bool is_one_byte() const { return is_one_byte_; } |
390 | 370 |
391 bool is_contextual_keyword(Vector<const char> keyword) const { | 371 bool is_contextual_keyword(Vector<const char> keyword) const { |
392 return is_one_byte() && keyword.length() == position_ && | 372 return is_one_byte() && keyword.length() == position_ && |
393 (memcmp(keyword.start(), backing_store_.start(), position_) == 0); | 373 (memcmp(keyword.start(), backing_store_.start(), position_) == 0); |
394 } | 374 } |
395 | 375 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 static const int kMaxGrowth = 1 * MB; | 407 static const int kMaxGrowth = 1 * MB; |
428 | 408 |
429 inline bool IsValidAscii(char code_unit) { | 409 inline bool IsValidAscii(char code_unit) { |
430 // Control characters and printable characters span the range of | 410 // Control characters and printable characters span the range of |
431 // valid ASCII characters (0-127). Chars are unsigned on some | 411 // valid ASCII characters (0-127). Chars are unsigned on some |
432 // platforms which causes compiler warnings if the validity check | 412 // platforms which causes compiler warnings if the validity check |
433 // tests the lower bound >= 0 as it's always true. | 413 // tests the lower bound >= 0 as it's always true. |
434 return iscntrl(code_unit) || isprint(code_unit); | 414 return iscntrl(code_unit) || isprint(code_unit); |
435 } | 415 } |
436 | 416 |
437 inline int NewCapacity(int min_capacity) { | 417 INLINE(void AddOneByteChar(byte one_byte_char)) { |
438 int capacity = Max(min_capacity, backing_store_.length()); | 418 DCHECK(is_one_byte_); |
439 int new_capacity = Min(capacity * kGrowthFactory, capacity + kMaxGrowth); | 419 if (position_ >= backing_store_.length()) ExpandBuffer(); |
440 return new_capacity; | 420 backing_store_[position_] = one_byte_char; |
| 421 position_ += kOneByteSize; |
441 } | 422 } |
442 | 423 |
443 void ExpandBuffer() { | 424 void AddCharSlow(uc32 code_unit); |
444 Vector<byte> new_store = Vector<byte>::New(NewCapacity(kInitialCapacity)); | 425 int NewCapacity(int min_capacity); |
445 MemCopy(new_store.start(), backing_store_.start(), position_); | 426 void ExpandBuffer(); |
446 backing_store_.Dispose(); | 427 void ConvertToTwoByte(); |
447 backing_store_ = new_store; | |
448 } | |
449 | |
450 void ConvertToTwoByte() { | |
451 DCHECK(is_one_byte_); | |
452 Vector<byte> new_store; | |
453 int new_content_size = position_ * kUC16Size; | |
454 if (new_content_size >= backing_store_.length()) { | |
455 // Ensure room for all currently read code units as UC16 as well | |
456 // as the code unit about to be stored. | |
457 new_store = Vector<byte>::New(NewCapacity(new_content_size)); | |
458 } else { | |
459 new_store = backing_store_; | |
460 } | |
461 uint8_t* src = backing_store_.start(); | |
462 uint16_t* dst = reinterpret_cast<uint16_t*>(new_store.start()); | |
463 for (int i = position_ - 1; i >= 0; i--) { | |
464 dst[i] = src[i]; | |
465 } | |
466 if (new_store.start() != backing_store_.start()) { | |
467 backing_store_.Dispose(); | |
468 backing_store_ = new_store; | |
469 } | |
470 position_ = new_content_size; | |
471 is_one_byte_ = false; | |
472 } | |
473 | 428 |
474 bool is_one_byte_; | 429 bool is_one_byte_; |
475 int position_; | 430 int position_; |
476 Vector<byte> backing_store_; | 431 Vector<byte> backing_store_; |
477 | 432 |
478 DISALLOW_COPY_AND_ASSIGN(LiteralBuffer); | 433 DISALLOW_COPY_AND_ASSIGN(LiteralBuffer); |
479 }; | 434 }; |
480 | 435 |
481 // The current and look-ahead token. | 436 // The current and look-ahead token. |
482 struct TokenDesc { | 437 struct TokenDesc { |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 bool found_html_comment_; | 755 bool found_html_comment_; |
801 | 756 |
802 MessageTemplate::Template scanner_error_; | 757 MessageTemplate::Template scanner_error_; |
803 Location scanner_error_location_; | 758 Location scanner_error_location_; |
804 }; | 759 }; |
805 | 760 |
806 } // namespace internal | 761 } // namespace internal |
807 } // namespace v8 | 762 } // namespace v8 |
808 | 763 |
809 #endif // V8_PARSING_SCANNER_H_ | 764 #endif // V8_PARSING_SCANNER_H_ |
OLD | NEW |