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