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 #ifndef V8_PARSING_JSON_PARSER_H_ | 5 #ifndef V8_PARSING_JSON_PARSER_H_ |
6 #define V8_PARSING_JSON_PARSER_H_ | 6 #define V8_PARSING_JSON_PARSER_H_ |
7 | 7 |
8 #include "src/char-predicates.h" | 8 #include "src/char-predicates.h" |
9 #include "src/conversions.h" | 9 #include "src/conversions.h" |
10 #include "src/debug/debug.h" | 10 #include "src/debug/debug.h" |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 AdvanceSkipWhitespace(); | 91 AdvanceSkipWhitespace(); |
92 return true; | 92 return true; |
93 } | 93 } |
94 return false; | 94 return false; |
95 } | 95 } |
96 | 96 |
97 // A JSON string (production JSONString) is subset of valid JavaScript string | 97 // A JSON string (production JSONString) is subset of valid JavaScript string |
98 // literals. The string must only be double-quoted (not single-quoted), and | 98 // literals. The string must only be double-quoted (not single-quoted), and |
99 // the only allowed backslash-escapes are ", /, \, b, f, n, r, t and | 99 // the only allowed backslash-escapes are ", /, \, b, f, n, r, t and |
100 // four-digit hex escapes (uXXXX). Any other use of backslashes is invalid. | 100 // four-digit hex escapes (uXXXX). Any other use of backslashes is invalid. |
101 Handle<String> ParseJsonString() { | 101 Handle<String> ParseJsonString() { return ScanJsonString<false>(); } |
102 return ScanJsonString<false>(); | |
103 } | |
104 | 102 |
105 bool ParseJsonString(Handle<String> expected) { | 103 bool ParseJsonString(Handle<String> expected) { |
106 int length = expected->length(); | 104 int length = expected->length(); |
107 if (source_->length() - position_ - 1 > length) { | 105 if (source_->length() - position_ - 1 > length) { |
108 DisallowHeapAllocation no_gc; | 106 DisallowHeapAllocation no_gc; |
109 String::FlatContent content = expected->GetFlatContent(); | 107 String::FlatContent content = expected->GetFlatContent(); |
110 if (content.IsOneByte()) { | 108 if (content.IsOneByte()) { |
111 DCHECK_EQ('"', c0_); | 109 DCHECK_EQ('"', c0_); |
112 const uint8_t* input_chars = seq_source_->GetChars() + position_ + 1; | 110 const uint8_t* input_chars = seq_source_->GetChars() + position_ + 1; |
113 const uint8_t* expected_chars = content.ToOneByteVector().start(); | 111 const uint8_t* expected_chars = content.ToOneByteVector().start(); |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 Handle<Object> value; | 467 Handle<Object> value; |
470 | 468 |
471 key = ParseJsonInternalizedString(); | 469 key = ParseJsonInternalizedString(); |
472 if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter(); | 470 if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter(); |
473 | 471 |
474 AdvanceSkipWhitespace(); | 472 AdvanceSkipWhitespace(); |
475 value = ParseJsonValue(); | 473 value = ParseJsonValue(); |
476 if (value.is_null()) return ReportUnexpectedCharacter(); | 474 if (value.is_null()) return ReportUnexpectedCharacter(); |
477 | 475 |
478 JSObject::DefinePropertyOrElementIgnoreAttributes(json_object, key, | 476 JSObject::DefinePropertyOrElementIgnoreAttributes(json_object, key, |
479 value).Check(); | 477 value) |
| 478 .Check(); |
480 } | 479 } |
481 } | 480 } |
482 | 481 |
483 if (c0_ != '}') { | 482 if (c0_ != '}') { |
484 return ReportUnexpectedCharacter(); | 483 return ReportUnexpectedCharacter(); |
485 } | 484 } |
486 } | 485 } |
487 AdvanceSkipWhitespace(); | 486 AdvanceSkipWhitespace(); |
488 return scope.CloseAndEscape(json_object); | 487 return scope.CloseAndEscape(json_object); |
489 } | 488 } |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 Advance(); | 574 Advance(); |
576 if (c0_ == '-' || c0_ == '+') Advance(); | 575 if (c0_ == '-' || c0_ == '+') Advance(); |
577 if (!IsDecimalDigit(c0_)) return ReportUnexpectedCharacter(); | 576 if (!IsDecimalDigit(c0_)) return ReportUnexpectedCharacter(); |
578 do { | 577 do { |
579 Advance(); | 578 Advance(); |
580 } while (IsDecimalDigit(c0_)); | 579 } while (IsDecimalDigit(c0_)); |
581 } | 580 } |
582 int length = position_ - beg_pos; | 581 int length = position_ - beg_pos; |
583 double number; | 582 double number; |
584 if (seq_one_byte) { | 583 if (seq_one_byte) { |
585 Vector<const uint8_t> chars(seq_source_->GetChars() + beg_pos, length); | 584 Vector<const uint8_t> chars(seq_source_->GetChars() + beg_pos, length); |
586 number = StringToDouble(isolate()->unicode_cache(), chars, | 585 number = StringToDouble(isolate()->unicode_cache(), chars, |
587 NO_FLAGS, // Hex, octal or trailing junk. | 586 NO_FLAGS, // Hex, octal or trailing junk. |
588 std::numeric_limits<double>::quiet_NaN()); | 587 std::numeric_limits<double>::quiet_NaN()); |
589 } else { | 588 } else { |
590 Vector<uint8_t> buffer = Vector<uint8_t>::New(length); | 589 Vector<uint8_t> buffer = Vector<uint8_t>::New(length); |
591 String::WriteToFlat(*source_, buffer.start(), beg_pos, position_); | 590 String::WriteToFlat(*source_, buffer.start(), beg_pos, position_); |
592 Vector<const uint8_t> result = | 591 Vector<const uint8_t> result = |
593 Vector<const uint8_t>(buffer.start(), length); | 592 Vector<const uint8_t>(buffer.start(), length); |
594 number = StringToDouble(isolate()->unicode_cache(), | 593 number = StringToDouble(isolate()->unicode_cache(), result, |
595 result, | |
596 NO_FLAGS, // Hex, octal or trailing junk. | 594 NO_FLAGS, // Hex, octal or trailing junk. |
597 0.0); | 595 0.0); |
598 buffer.Dispose(); | 596 buffer.Dispose(); |
599 } | 597 } |
600 SkipWhitespace(); | 598 SkipWhitespace(); |
601 return factory()->NewNumber(number, pretenure_); | 599 return factory()->NewNumber(number, pretenure_); |
602 } | 600 } |
603 | 601 |
604 | 602 |
605 template <typename StringType> | 603 template <typename StringType> |
606 inline void SeqStringSet(Handle<StringType> seq_str, int i, uc32 c); | 604 inline void SeqStringSet(Handle<StringType> seq_str, int i, uc32 c); |
607 | 605 |
608 template <> | 606 template <> |
609 inline void SeqStringSet(Handle<SeqTwoByteString> seq_str, int i, uc32 c) { | 607 inline void SeqStringSet(Handle<SeqTwoByteString> seq_str, int i, uc32 c) { |
610 seq_str->SeqTwoByteStringSet(i, c); | 608 seq_str->SeqTwoByteStringSet(i, c); |
611 } | 609 } |
612 | 610 |
613 template <> | 611 template <> |
614 inline void SeqStringSet(Handle<SeqOneByteString> seq_str, int i, uc32 c) { | 612 inline void SeqStringSet(Handle<SeqOneByteString> seq_str, int i, uc32 c) { |
615 seq_str->SeqOneByteStringSet(i, c); | 613 seq_str->SeqOneByteStringSet(i, c); |
616 } | 614 } |
617 | 615 |
618 template <typename StringType> | 616 template <typename StringType> |
619 inline Handle<StringType> NewRawString(Factory* factory, | 617 inline Handle<StringType> NewRawString(Factory* factory, int length, |
620 int length, | |
621 PretenureFlag pretenure); | 618 PretenureFlag pretenure); |
622 | 619 |
623 template <> | 620 template <> |
624 inline Handle<SeqTwoByteString> NewRawString(Factory* factory, | 621 inline Handle<SeqTwoByteString> NewRawString(Factory* factory, int length, |
625 int length, | |
626 PretenureFlag pretenure) { | 622 PretenureFlag pretenure) { |
627 return factory->NewRawTwoByteString(length, pretenure).ToHandleChecked(); | 623 return factory->NewRawTwoByteString(length, pretenure).ToHandleChecked(); |
628 } | 624 } |
629 | 625 |
630 template <> | 626 template <> |
631 inline Handle<SeqOneByteString> NewRawString(Factory* factory, | 627 inline Handle<SeqOneByteString> NewRawString(Factory* factory, int length, |
632 int length, | 628 PretenureFlag pretenure) { |
633 PretenureFlag pretenure) { | |
634 return factory->NewRawOneByteString(length, pretenure).ToHandleChecked(); | 629 return factory->NewRawOneByteString(length, pretenure).ToHandleChecked(); |
635 } | 630 } |
636 | 631 |
637 | 632 |
638 // Scans the rest of a JSON string starting from position_ and writes | 633 // Scans the rest of a JSON string starting from position_ and writes |
639 // prefix[start..end] along with the scanned characters into a | 634 // prefix[start..end] along with the scanned characters into a |
640 // sequential string of type StringType. | 635 // sequential string of type StringType. |
641 template <bool seq_one_byte> | 636 template <bool seq_one_byte> |
642 template <typename StringType, typename SinkChar> | 637 template <typename StringType, typename SinkChar> |
643 Handle<String> JsonParser<seq_one_byte>::SlowScanJsonString( | 638 Handle<String> JsonParser<seq_one_byte>::SlowScanJsonString( |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 } | 701 } |
707 if (sizeof(SinkChar) == kUC16Size || | 702 if (sizeof(SinkChar) == kUC16Size || |
708 value <= String::kMaxOneByteCharCode) { | 703 value <= String::kMaxOneByteCharCode) { |
709 SeqStringSet(seq_string, count++, value); | 704 SeqStringSet(seq_string, count++, value); |
710 break; | 705 break; |
711 } else { | 706 } else { |
712 // StringType is SeqOneByteString and we just read a non-Latin1 | 707 // StringType is SeqOneByteString and we just read a non-Latin1 |
713 // char. | 708 // char. |
714 position_ -= 6; // Rewind position_ to \ in \uxxxx. | 709 position_ -= 6; // Rewind position_ to \ in \uxxxx. |
715 Advance(); | 710 Advance(); |
716 return SlowScanJsonString<SeqTwoByteString, uc16>(seq_string, | 711 return SlowScanJsonString<SeqTwoByteString, uc16>(seq_string, 0, |
717 0, | |
718 count); | 712 count); |
719 } | 713 } |
720 } | 714 } |
721 default: | 715 default: |
722 return Handle<String>::null(); | 716 return Handle<String>::null(); |
723 } | 717 } |
724 Advance(); | 718 Advance(); |
725 } | 719 } |
726 } | 720 } |
727 | 721 |
(...skipping 21 matching lines...) Expand all Loading... |
749 // parsed is not a known internalized string, contains backslashes or | 743 // parsed is not a known internalized string, contains backslashes or |
750 // unexpectedly reaches the end of string, return with an empty handle. | 744 // unexpectedly reaches the end of string, return with an empty handle. |
751 uint32_t running_hash = isolate()->heap()->HashSeed(); | 745 uint32_t running_hash = isolate()->heap()->HashSeed(); |
752 int position = position_; | 746 int position = position_; |
753 uc32 c0 = c0_; | 747 uc32 c0 = c0_; |
754 do { | 748 do { |
755 if (c0 == '\\') { | 749 if (c0 == '\\') { |
756 c0_ = c0; | 750 c0_ = c0; |
757 int beg_pos = position_; | 751 int beg_pos = position_; |
758 position_ = position; | 752 position_ = position; |
759 return SlowScanJsonString<SeqOneByteString, uint8_t>(source_, | 753 return SlowScanJsonString<SeqOneByteString, uint8_t>(source_, beg_pos, |
760 beg_pos, | |
761 position_); | 754 position_); |
762 } | 755 } |
763 if (c0 < 0x20) return Handle<String>::null(); | 756 if (c0 < 0x20) return Handle<String>::null(); |
764 if (static_cast<uint32_t>(c0) > | 757 if (static_cast<uint32_t>(c0) > |
765 unibrow::Utf16::kMaxNonSurrogateCharCode) { | 758 unibrow::Utf16::kMaxNonSurrogateCharCode) { |
766 running_hash = | 759 running_hash = StringHasher::AddCharacterCore( |
767 StringHasher::AddCharacterCore(running_hash, | 760 running_hash, unibrow::Utf16::LeadSurrogate(c0)); |
768 unibrow::Utf16::LeadSurrogate(c0)); | 761 running_hash = StringHasher::AddCharacterCore( |
769 running_hash = | 762 running_hash, unibrow::Utf16::TrailSurrogate(c0)); |
770 StringHasher::AddCharacterCore(running_hash, | |
771 unibrow::Utf16::TrailSurrogate(c0)); | |
772 } else { | 763 } else { |
773 running_hash = StringHasher::AddCharacterCore(running_hash, c0); | 764 running_hash = StringHasher::AddCharacterCore(running_hash, c0); |
774 } | 765 } |
775 position++; | 766 position++; |
776 if (position >= source_length_) return Handle<String>::null(); | 767 if (position >= source_length_) return Handle<String>::null(); |
777 c0 = seq_source_->SeqOneByteStringGet(position); | 768 c0 = seq_source_->SeqOneByteStringGet(position); |
778 } while (c0 != '"'); | 769 } while (c0 != '"'); |
779 int length = position - position_; | 770 int length = position - position_; |
780 uint32_t hash = (length <= String::kMaxHashCalcLength) | 771 uint32_t hash = (length <= String::kMaxHashCalcLength) |
781 ? StringHasher::GetHashCore(running_hash) | 772 ? StringHasher::GetHashCore(running_hash) |
782 : static_cast<uint32_t>(length); | 773 : static_cast<uint32_t>(length); |
783 Vector<const uint8_t> string_vector( | 774 Vector<const uint8_t> string_vector(seq_source_->GetChars() + position_, |
784 seq_source_->GetChars() + position_, length); | 775 length); |
785 StringTable* string_table = isolate()->heap()->string_table(); | 776 StringTable* string_table = isolate()->heap()->string_table(); |
786 uint32_t capacity = string_table->Capacity(); | 777 uint32_t capacity = string_table->Capacity(); |
787 uint32_t entry = StringTable::FirstProbe(hash, capacity); | 778 uint32_t entry = StringTable::FirstProbe(hash, capacity); |
788 uint32_t count = 1; | 779 uint32_t count = 1; |
789 Handle<String> result; | 780 Handle<String> result; |
790 while (true) { | 781 while (true) { |
791 Object* element = string_table->KeyAt(entry); | 782 Object* element = string_table->KeyAt(entry); |
792 if (element == isolate()->heap()->undefined_value()) { | 783 if (element == isolate()->heap()->undefined_value()) { |
793 // Lookup failure. | 784 // Lookup failure. |
794 result = factory()->InternalizeOneByteString( | 785 result = |
795 seq_source_, position_, length); | 786 factory()->InternalizeOneByteString(seq_source_, position_, length); |
796 break; | 787 break; |
797 } | 788 } |
798 if (element != isolate()->heap()->the_hole_value() && | 789 if (element != isolate()->heap()->the_hole_value() && |
799 String::cast(element)->IsOneByteEqualTo(string_vector)) { | 790 String::cast(element)->IsOneByteEqualTo(string_vector)) { |
800 result = Handle<String>(String::cast(element), isolate()); | 791 result = Handle<String>(String::cast(element), isolate()); |
801 #ifdef DEBUG | 792 #ifdef DEBUG |
802 uint32_t hash_field = | 793 uint32_t hash_field = |
803 (hash << String::kHashShift) | String::kIsNotArrayIndexMask; | 794 (hash << String::kHashShift) | String::kIsNotArrayIndexMask; |
804 DCHECK_EQ(static_cast<int>(result->Hash()), | 795 DCHECK_EQ(static_cast<int>(result->Hash()), |
805 static_cast<int>(hash_field >> String::kHashShift)); | 796 static_cast<int>(hash_field >> String::kHashShift)); |
(...skipping 10 matching lines...) Expand all Loading... |
816 | 807 |
817 int beg_pos = position_; | 808 int beg_pos = position_; |
818 // Fast case for Latin1 only without escape characters. | 809 // Fast case for Latin1 only without escape characters. |
819 do { | 810 do { |
820 // Check for control character (0x00-0x1f) or unterminated string (<0). | 811 // Check for control character (0x00-0x1f) or unterminated string (<0). |
821 if (c0_ < 0x20) return Handle<String>::null(); | 812 if (c0_ < 0x20) return Handle<String>::null(); |
822 if (c0_ != '\\') { | 813 if (c0_ != '\\') { |
823 if (seq_one_byte || c0_ <= String::kMaxOneByteCharCode) { | 814 if (seq_one_byte || c0_ <= String::kMaxOneByteCharCode) { |
824 Advance(); | 815 Advance(); |
825 } else { | 816 } else { |
826 return SlowScanJsonString<SeqTwoByteString, uc16>(source_, | 817 return SlowScanJsonString<SeqTwoByteString, uc16>(source_, beg_pos, |
827 beg_pos, | |
828 position_); | 818 position_); |
829 } | 819 } |
830 } else { | 820 } else { |
831 return SlowScanJsonString<SeqOneByteString, uint8_t>(source_, | 821 return SlowScanJsonString<SeqOneByteString, uint8_t>(source_, beg_pos, |
832 beg_pos, | |
833 position_); | 822 position_); |
834 } | 823 } |
835 } while (c0_ != '"'); | 824 } while (c0_ != '"'); |
836 int length = position_ - beg_pos; | 825 int length = position_ - beg_pos; |
837 Handle<String> result = | 826 Handle<String> result = |
838 factory()->NewRawOneByteString(length, pretenure_).ToHandleChecked(); | 827 factory()->NewRawOneByteString(length, pretenure_).ToHandleChecked(); |
839 uint8_t* dest = SeqOneByteString::cast(*result)->GetChars(); | 828 uint8_t* dest = SeqOneByteString::cast(*result)->GetChars(); |
840 String::WriteToFlat(*source_, dest, beg_pos, position_); | 829 String::WriteToFlat(*source_, dest, beg_pos, position_); |
841 | 830 |
842 DCHECK_EQ('"', c0_); | 831 DCHECK_EQ('"', c0_); |
843 // Advance past the last '"'. | 832 // Advance past the last '"'. |
844 AdvanceSkipWhitespace(); | 833 AdvanceSkipWhitespace(); |
845 return result; | 834 return result; |
846 } | 835 } |
847 | 836 |
848 } // namespace internal | 837 } // namespace internal |
849 } // namespace v8 | 838 } // namespace v8 |
850 | 839 |
851 #endif // V8_PARSING_JSON_PARSER_H_ | 840 #endif // V8_PARSING_JSON_PARSER_H_ |
OLD | NEW |