| 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_JSON_PARSER_H_ | 5 #ifndef V8_JSON_PARSER_H_ |
| 6 #define V8_JSON_PARSER_H_ | 6 #define V8_JSON_PARSER_H_ |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/char-predicates-inl.h" | 10 #include "src/char-predicates-inl.h" |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 Handle<String> ParseJsonString() { | 97 Handle<String> ParseJsonString() { |
| 98 return ScanJsonString<false>(); | 98 return ScanJsonString<false>(); |
| 99 } | 99 } |
| 100 | 100 |
| 101 bool ParseJsonString(Handle<String> expected) { | 101 bool ParseJsonString(Handle<String> expected) { |
| 102 int length = expected->length(); | 102 int length = expected->length(); |
| 103 if (source_->length() - position_ - 1 > length) { | 103 if (source_->length() - position_ - 1 > length) { |
| 104 DisallowHeapAllocation no_gc; | 104 DisallowHeapAllocation no_gc; |
| 105 String::FlatContent content = expected->GetFlatContent(); | 105 String::FlatContent content = expected->GetFlatContent(); |
| 106 if (content.IsAscii()) { | 106 if (content.IsAscii()) { |
| 107 ASSERT_EQ('"', c0_); | 107 DCHECK_EQ('"', c0_); |
| 108 const uint8_t* input_chars = seq_source_->GetChars() + position_ + 1; | 108 const uint8_t* input_chars = seq_source_->GetChars() + position_ + 1; |
| 109 const uint8_t* expected_chars = content.ToOneByteVector().start(); | 109 const uint8_t* expected_chars = content.ToOneByteVector().start(); |
| 110 for (int i = 0; i < length; i++) { | 110 for (int i = 0; i < length; i++) { |
| 111 uint8_t c0 = input_chars[i]; | 111 uint8_t c0 = input_chars[i]; |
| 112 if (c0 != expected_chars[i] || | 112 if (c0 != expected_chars[i] || |
| 113 c0 == '"' || c0 < 0x20 || c0 == '\\') { | 113 c0 == '"' || c0 < 0x20 || c0 == '\\') { |
| 114 return false; | 114 return false; |
| 115 } | 115 } |
| 116 } | 116 } |
| 117 if (input_chars[length] == '"') { | 117 if (input_chars[length] == '"') { |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 | 293 |
| 294 | 294 |
| 295 // Parse a JSON object. Position must be right at '{'. | 295 // Parse a JSON object. Position must be right at '{'. |
| 296 template <bool seq_ascii> | 296 template <bool seq_ascii> |
| 297 Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() { | 297 Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() { |
| 298 HandleScope scope(isolate()); | 298 HandleScope scope(isolate()); |
| 299 Handle<JSObject> json_object = | 299 Handle<JSObject> json_object = |
| 300 factory()->NewJSObject(object_constructor(), pretenure_); | 300 factory()->NewJSObject(object_constructor(), pretenure_); |
| 301 Handle<Map> map(json_object->map()); | 301 Handle<Map> map(json_object->map()); |
| 302 ZoneList<Handle<Object> > properties(8, zone()); | 302 ZoneList<Handle<Object> > properties(8, zone()); |
| 303 ASSERT_EQ(c0_, '{'); | 303 DCHECK_EQ(c0_, '{'); |
| 304 | 304 |
| 305 bool transitioning = true; | 305 bool transitioning = true; |
| 306 | 306 |
| 307 AdvanceSkipWhitespace(); | 307 AdvanceSkipWhitespace(); |
| 308 if (c0_ != '}') { | 308 if (c0_ != '}') { |
| 309 do { | 309 do { |
| 310 if (c0_ != '"') return ReportUnexpectedCharacter(); | 310 if (c0_ != '"') return ReportUnexpectedCharacter(); |
| 311 | 311 |
| 312 int start_position = position_; | 312 int start_position = position_; |
| 313 Advance(); | 313 Advance(); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 if (expected_representation.IsDouble()) { | 390 if (expected_representation.IsDouble()) { |
| 391 value = Object::NewStorageFor(isolate(), value, | 391 value = Object::NewStorageFor(isolate(), value, |
| 392 expected_representation); | 392 expected_representation); |
| 393 } else if (expected_representation.IsHeapObject() && | 393 } else if (expected_representation.IsHeapObject() && |
| 394 !target->instance_descriptors()->GetFieldType( | 394 !target->instance_descriptors()->GetFieldType( |
| 395 descriptor)->NowContains(value)) { | 395 descriptor)->NowContains(value)) { |
| 396 Handle<HeapType> value_type(value->OptimalType( | 396 Handle<HeapType> value_type(value->OptimalType( |
| 397 isolate(), expected_representation)); | 397 isolate(), expected_representation)); |
| 398 Map::GeneralizeFieldType(target, descriptor, value_type); | 398 Map::GeneralizeFieldType(target, descriptor, value_type); |
| 399 } | 399 } |
| 400 ASSERT(target->instance_descriptors()->GetFieldType( | 400 DCHECK(target->instance_descriptors()->GetFieldType( |
| 401 descriptor)->NowContains(value)); | 401 descriptor)->NowContains(value)); |
| 402 properties.Add(value, zone()); | 402 properties.Add(value, zone()); |
| 403 map = target; | 403 map = target; |
| 404 continue; | 404 continue; |
| 405 } else { | 405 } else { |
| 406 transitioning = false; | 406 transitioning = false; |
| 407 } | 407 } |
| 408 } | 408 } |
| 409 | 409 |
| 410 // Commit the intermediate state to the object and stop transitioning. | 410 // Commit the intermediate state to the object and stop transitioning. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 } | 444 } |
| 445 AdvanceSkipWhitespace(); | 445 AdvanceSkipWhitespace(); |
| 446 return scope.CloseAndEscape(json_object); | 446 return scope.CloseAndEscape(json_object); |
| 447 } | 447 } |
| 448 | 448 |
| 449 // Parse a JSON array. Position must be right at '['. | 449 // Parse a JSON array. Position must be right at '['. |
| 450 template <bool seq_ascii> | 450 template <bool seq_ascii> |
| 451 Handle<Object> JsonParser<seq_ascii>::ParseJsonArray() { | 451 Handle<Object> JsonParser<seq_ascii>::ParseJsonArray() { |
| 452 HandleScope scope(isolate()); | 452 HandleScope scope(isolate()); |
| 453 ZoneList<Handle<Object> > elements(4, zone()); | 453 ZoneList<Handle<Object> > elements(4, zone()); |
| 454 ASSERT_EQ(c0_, '['); | 454 DCHECK_EQ(c0_, '['); |
| 455 | 455 |
| 456 AdvanceSkipWhitespace(); | 456 AdvanceSkipWhitespace(); |
| 457 if (c0_ != ']') { | 457 if (c0_ != ']') { |
| 458 do { | 458 do { |
| 459 Handle<Object> element = ParseJsonValue(); | 459 Handle<Object> element = ParseJsonValue(); |
| 460 if (element.is_null()) return ReportUnexpectedCharacter(); | 460 if (element.is_null()) return ReportUnexpectedCharacter(); |
| 461 elements.Add(element, zone()); | 461 elements.Add(element, zone()); |
| 462 } while (MatchSkipWhiteSpace(',')); | 462 } while (MatchSkipWhiteSpace(',')); |
| 463 if (c0_ != ']') { | 463 if (c0_ != ']') { |
| 464 return ReportUnexpectedCharacter(); | 464 return ReportUnexpectedCharacter(); |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 659 count); | 659 count); |
| 660 } | 660 } |
| 661 } | 661 } |
| 662 default: | 662 default: |
| 663 return Handle<String>::null(); | 663 return Handle<String>::null(); |
| 664 } | 664 } |
| 665 Advance(); | 665 Advance(); |
| 666 } | 666 } |
| 667 } | 667 } |
| 668 | 668 |
| 669 ASSERT_EQ('"', c0_); | 669 DCHECK_EQ('"', c0_); |
| 670 // Advance past the last '"'. | 670 // Advance past the last '"'. |
| 671 AdvanceSkipWhitespace(); | 671 AdvanceSkipWhitespace(); |
| 672 | 672 |
| 673 // Shrink seq_string length to count and return. | 673 // Shrink seq_string length to count and return. |
| 674 return SeqString::Truncate(seq_string, count); | 674 return SeqString::Truncate(seq_string, count); |
| 675 } | 675 } |
| 676 | 676 |
| 677 | 677 |
| 678 template <bool seq_ascii> | 678 template <bool seq_ascii> |
| 679 template <bool is_internalized> | 679 template <bool is_internalized> |
| 680 Handle<String> JsonParser<seq_ascii>::ScanJsonString() { | 680 Handle<String> JsonParser<seq_ascii>::ScanJsonString() { |
| 681 ASSERT_EQ('"', c0_); | 681 DCHECK_EQ('"', c0_); |
| 682 Advance(); | 682 Advance(); |
| 683 if (c0_ == '"') { | 683 if (c0_ == '"') { |
| 684 AdvanceSkipWhitespace(); | 684 AdvanceSkipWhitespace(); |
| 685 return factory()->empty_string(); | 685 return factory()->empty_string(); |
| 686 } | 686 } |
| 687 | 687 |
| 688 if (seq_ascii && is_internalized) { | 688 if (seq_ascii && is_internalized) { |
| 689 // Fast path for existing internalized strings. If the the string being | 689 // Fast path for existing internalized strings. If the the string being |
| 690 // parsed is not a known internalized string, contains backslashes or | 690 // parsed is not a known internalized string, contains backslashes or |
| 691 // unexpectedly reaches the end of string, return with an empty handle. | 691 // unexpectedly reaches the end of string, return with an empty handle. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 result = factory()->InternalizeOneByteString( | 734 result = factory()->InternalizeOneByteString( |
| 735 seq_source_, position_, length); | 735 seq_source_, position_, length); |
| 736 break; | 736 break; |
| 737 } | 737 } |
| 738 if (element != isolate()->heap()->the_hole_value() && | 738 if (element != isolate()->heap()->the_hole_value() && |
| 739 String::cast(element)->IsOneByteEqualTo(string_vector)) { | 739 String::cast(element)->IsOneByteEqualTo(string_vector)) { |
| 740 result = Handle<String>(String::cast(element), isolate()); | 740 result = Handle<String>(String::cast(element), isolate()); |
| 741 #ifdef DEBUG | 741 #ifdef DEBUG |
| 742 uint32_t hash_field = | 742 uint32_t hash_field = |
| 743 (hash << String::kHashShift) | String::kIsNotArrayIndexMask; | 743 (hash << String::kHashShift) | String::kIsNotArrayIndexMask; |
| 744 ASSERT_EQ(static_cast<int>(result->Hash()), | 744 DCHECK_EQ(static_cast<int>(result->Hash()), |
| 745 static_cast<int>(hash_field >> String::kHashShift)); | 745 static_cast<int>(hash_field >> String::kHashShift)); |
| 746 #endif | 746 #endif |
| 747 break; | 747 break; |
| 748 } | 748 } |
| 749 entry = StringTable::NextProbe(entry, count++, capacity); | 749 entry = StringTable::NextProbe(entry, count++, capacity); |
| 750 } | 750 } |
| 751 position_ = position; | 751 position_ = position; |
| 752 // Advance past the last '"'. | 752 // Advance past the last '"'. |
| 753 AdvanceSkipWhitespace(); | 753 AdvanceSkipWhitespace(); |
| 754 return result; | 754 return result; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 772 beg_pos, | 772 beg_pos, |
| 773 position_); | 773 position_); |
| 774 } | 774 } |
| 775 } while (c0_ != '"'); | 775 } while (c0_ != '"'); |
| 776 int length = position_ - beg_pos; | 776 int length = position_ - beg_pos; |
| 777 Handle<String> result = | 777 Handle<String> result = |
| 778 factory()->NewRawOneByteString(length, pretenure_).ToHandleChecked(); | 778 factory()->NewRawOneByteString(length, pretenure_).ToHandleChecked(); |
| 779 uint8_t* dest = SeqOneByteString::cast(*result)->GetChars(); | 779 uint8_t* dest = SeqOneByteString::cast(*result)->GetChars(); |
| 780 String::WriteToFlat(*source_, dest, beg_pos, position_); | 780 String::WriteToFlat(*source_, dest, beg_pos, position_); |
| 781 | 781 |
| 782 ASSERT_EQ('"', c0_); | 782 DCHECK_EQ('"', c0_); |
| 783 // Advance past the last '"'. | 783 // Advance past the last '"'. |
| 784 AdvanceSkipWhitespace(); | 784 AdvanceSkipWhitespace(); |
| 785 return result; | 785 return result; |
| 786 } | 786 } |
| 787 | 787 |
| 788 } } // namespace v8::internal | 788 } } // namespace v8::internal |
| 789 | 789 |
| 790 #endif // V8_JSON_PARSER_H_ | 790 #endif // V8_JSON_PARSER_H_ |
| OLD | NEW |