Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: src/value-serializer.cc

Issue 2256413002: Blink-compatible deserialization of "version 0" sparse arrays. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/unittests/value-serializer-unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
OLDNEW
« no previous file with comments | « no previous file | test/unittests/value-serializer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698