OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 #include "src/value-serializer.h" | 5 #include "src/value-serializer.h" |
6 | 6 |
7 #include <type_traits> | 7 #include <type_traits> |
8 | 8 |
9 #include "src/base/logging.h" | 9 #include "src/base/logging.h" |
10 #include "src/factory.h" | 10 #include "src/factory.h" |
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 used_as_prototype); | 710 used_as_prototype); |
711 | 711 |
712 // If the dictionary was reallocated, update the global handle. | 712 // If the dictionary was reallocated, update the global handle. |
713 if (!new_dictionary.is_identical_to(id_map_)) { | 713 if (!new_dictionary.is_identical_to(id_map_)) { |
714 GlobalHandles::Destroy(Handle<Object>::cast(id_map_).location()); | 714 GlobalHandles::Destroy(Handle<Object>::cast(id_map_).location()); |
715 id_map_ = Handle<SeededNumberDictionary>::cast( | 715 id_map_ = Handle<SeededNumberDictionary>::cast( |
716 isolate_->global_handles()->Create(*new_dictionary)); | 716 isolate_->global_handles()->Create(*new_dictionary)); |
717 } | 717 } |
718 } | 718 } |
719 | 719 |
720 static MaybeHandle<JSObject> CreateJSObjectFromKeyValuePairs( | 720 static Maybe<bool> SetPropertiesFromKeyValuePairs(Isolate* isolate, |
721 Isolate* isolate, Handle<Object>* data, uint32_t num_properties) { | 721 Handle<JSObject> object, |
722 Handle<JSObject> object = | 722 Handle<Object>* data, |
723 isolate->factory()->NewJSObject(isolate->object_function()); | 723 uint32_t num_properties) { |
724 for (unsigned i = 0; i < 2 * num_properties; i += 2) { | 724 for (unsigned i = 0; i < 2 * num_properties; i += 2) { |
725 Handle<Object> key = data[i]; | 725 Handle<Object> key = data[i]; |
726 Handle<Object> value = data[i + 1]; | 726 Handle<Object> value = data[i + 1]; |
727 bool success; | 727 bool success; |
728 LookupIterator it = LookupIterator::PropertyOrElement( | 728 LookupIterator it = LookupIterator::PropertyOrElement( |
729 isolate, object, key, &success, LookupIterator::OWN); | 729 isolate, object, key, &success, LookupIterator::OWN); |
730 if (!success || | 730 if (!success || |
731 JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, NONE) | 731 JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, NONE) |
732 .is_null()) { | 732 .is_null()) { |
733 return MaybeHandle<JSObject>(); | 733 return Nothing<bool>(); |
734 } | 734 } |
735 } | 735 } |
736 return object; | 736 return Just(true); |
737 } | 737 } |
738 | 738 |
739 MaybeHandle<Object> | 739 MaybeHandle<Object> |
740 ValueDeserializer::ReadObjectUsingEntireBufferForLegacyFormat() { | 740 ValueDeserializer::ReadObjectUsingEntireBufferForLegacyFormat() { |
741 if (version_ > 0) return MaybeHandle<Object>(); | 741 if (version_ > 0) return MaybeHandle<Object>(); |
742 | 742 |
743 HandleScope scope(isolate_); | 743 HandleScope scope(isolate_); |
744 std::vector<Handle<Object>> stack; | 744 std::vector<Handle<Object>> stack; |
745 while (position_ < end_) { | 745 while (position_ < end_) { |
746 SerializationTag tag; | 746 SerializationTag tag; |
747 if (!PeekTag().To(&tag)) break; | 747 if (!PeekTag().To(&tag)) break; |
748 | 748 |
749 Handle<Object> new_object; | 749 Handle<Object> new_object; |
750 switch (tag) { | 750 switch (tag) { |
751 case SerializationTag::kEndJSObject: { | 751 case SerializationTag::kEndJSObject: { |
752 ConsumeTag(SerializationTag::kEndJSObject); | 752 ConsumeTag(SerializationTag::kEndJSObject); |
753 | 753 |
754 // JS Object: Read the last 2*n values from the stack and use them as | 754 // JS Object: Read the last 2*n values from the stack and use them as |
755 // key-value pairs. | 755 // key-value pairs. |
756 uint32_t num_properties; | 756 uint32_t num_properties; |
757 if (!ReadVarint<uint32_t>().To(&num_properties) || | 757 if (!ReadVarint<uint32_t>().To(&num_properties) || |
758 stack.size() / 2 < num_properties) { | 758 stack.size() / 2 < num_properties) { |
759 return MaybeHandle<Object>(); | 759 return MaybeHandle<Object>(); |
760 } | 760 } |
761 | 761 |
762 size_t begin_properties = stack.size() - 2 * num_properties; | 762 size_t begin_properties = |
763 Handle<Object>* data = | 763 stack.size() - 2 * static_cast<size_t>(num_properties); |
764 num_properties ? &stack[begin_properties] : nullptr; | 764 Handle<JSObject> js_object = |
765 if (!CreateJSObjectFromKeyValuePairs(isolate_, data, num_properties) | 765 isolate_->factory()->NewJSObject(isolate_->object_function()); |
766 .ToHandle(&new_object)) { | 766 if (num_properties && |
| 767 !SetPropertiesFromKeyValuePairs( |
| 768 isolate_, js_object, &stack[begin_properties], num_properties) |
| 769 .FromMaybe(false)) { |
767 return MaybeHandle<Object>(); | 770 return MaybeHandle<Object>(); |
768 } | 771 } |
769 | 772 |
770 stack.resize(begin_properties); | 773 stack.resize(begin_properties); |
| 774 new_object = js_object; |
771 break; | 775 break; |
772 } | 776 } |
| 777 case SerializationTag::kEndSparseJSArray: { |
| 778 ConsumeTag(SerializationTag::kEndSparseJSArray); |
| 779 |
| 780 // Sparse JS Array: Read the last 2*|num_properties| from the stack. |
| 781 uint32_t num_properties; |
| 782 uint32_t length; |
| 783 if (!ReadVarint<uint32_t>().To(&num_properties) || |
| 784 !ReadVarint<uint32_t>().To(&length) || |
| 785 stack.size() / 2 < num_properties) { |
| 786 return MaybeHandle<Object>(); |
| 787 } |
| 788 |
| 789 Handle<JSArray> js_array = isolate_->factory()->NewJSArray(0); |
| 790 JSArray::SetLength(js_array, length); |
| 791 size_t begin_properties = |
| 792 stack.size() - 2 * static_cast<size_t>(num_properties); |
| 793 if (num_properties && |
| 794 !SetPropertiesFromKeyValuePairs( |
| 795 isolate_, js_array, &stack[begin_properties], num_properties) |
| 796 .FromMaybe(false)) { |
| 797 return MaybeHandle<Object>(); |
| 798 } |
| 799 |
| 800 stack.resize(begin_properties); |
| 801 new_object = js_array; |
| 802 break; |
| 803 } |
| 804 case SerializationTag::kEndDenseJSArray: |
| 805 // This was already broken in Chromium, and apparently wasn't missed. |
| 806 return MaybeHandle<Object>(); |
773 default: | 807 default: |
774 if (!ReadObject().ToHandle(&new_object)) return MaybeHandle<Object>(); | 808 if (!ReadObject().ToHandle(&new_object)) return MaybeHandle<Object>(); |
775 break; | 809 break; |
776 } | 810 } |
777 stack.push_back(new_object); | 811 stack.push_back(new_object); |
778 } | 812 } |
779 | 813 |
780 // Nothing remains but padding. | 814 // Nothing remains but padding. |
781 #ifdef DEBUG | 815 #ifdef DEBUG |
782 while (position_ < end_) { | 816 while (position_ < end_) { |
783 DCHECK(*position_++ == static_cast<uint8_t>(SerializationTag::kPadding)); | 817 DCHECK(*position_++ == static_cast<uint8_t>(SerializationTag::kPadding)); |
784 } | 818 } |
785 #endif | 819 #endif |
786 position_ = end_; | 820 position_ = end_; |
787 | 821 |
788 if (stack.size() != 1) return MaybeHandle<Object>(); | 822 if (stack.size() != 1) return MaybeHandle<Object>(); |
789 return scope.CloseAndEscape(stack[0]); | 823 return scope.CloseAndEscape(stack[0]); |
790 } | 824 } |
791 | 825 |
792 } // namespace internal | 826 } // namespace internal |
793 } // namespace v8 | 827 } // namespace v8 |
OLD | NEW |