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

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

Issue 2264403004: Blink-compatible serialization of ArrayBuffer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: review comments Created 4 years, 3 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 | « src/value-serializer.h ('k') | 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 // flags:uint32_t. 83 // flags:uint32_t.
84 kRegExp = 'R', 84 kRegExp = 'R',
85 // Beginning of a JS map. 85 // Beginning of a JS map.
86 kBeginJSMap = ';', 86 kBeginJSMap = ';',
87 // End of a JS map. length:uint32_t. 87 // End of a JS map. length:uint32_t.
88 kEndJSMap = ':', 88 kEndJSMap = ':',
89 // Beginning of a JS set. 89 // Beginning of a JS set.
90 kBeginJSSet = '\'', 90 kBeginJSSet = '\'',
91 // End of a JS set. length:uint32_t. 91 // End of a JS set. length:uint32_t.
92 kEndJSSet = ',', 92 kEndJSSet = ',',
93 // Array buffer. byteLength:uint32_t, then raw data.
94 kArrayBuffer = 'B',
93 }; 95 };
94 96
95 ValueSerializer::ValueSerializer(Isolate* isolate) 97 ValueSerializer::ValueSerializer(Isolate* isolate)
96 : isolate_(isolate), 98 : isolate_(isolate),
97 zone_(isolate->allocator()), 99 zone_(isolate->allocator()),
98 id_map_(isolate->heap(), &zone_) {} 100 id_map_(isolate->heap(), &zone_) {}
99 101
100 ValueSerializer::~ValueSerializer() {} 102 ValueSerializer::~ValueSerializer() {}
101 103
102 void ValueSerializer::WriteHeader() { 104 void ValueSerializer::WriteHeader() {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 buffer_.insert(buffer_.end(), chars.begin(), chars.end()); 153 buffer_.insert(buffer_.end(), chars.begin(), chars.end());
152 } 154 }
153 155
154 void ValueSerializer::WriteTwoByteString(Vector<const uc16> chars) { 156 void ValueSerializer::WriteTwoByteString(Vector<const uc16> chars) {
155 // Warning: this uses host endianness. 157 // Warning: this uses host endianness.
156 WriteVarint<uint32_t>(chars.length() * sizeof(uc16)); 158 WriteVarint<uint32_t>(chars.length() * sizeof(uc16));
157 buffer_.insert(buffer_.end(), reinterpret_cast<const uint8_t*>(chars.begin()), 159 buffer_.insert(buffer_.end(), reinterpret_cast<const uint8_t*>(chars.begin()),
158 reinterpret_cast<const uint8_t*>(chars.end())); 160 reinterpret_cast<const uint8_t*>(chars.end()));
159 } 161 }
160 162
163 void ValueSerializer::WriteRawBytes(const void* source, size_t length) {
164 const uint8_t* begin = reinterpret_cast<const uint8_t*>(source);
165 buffer_.insert(buffer_.end(), begin, begin + length);
166 }
167
161 uint8_t* ValueSerializer::ReserveRawBytes(size_t bytes) { 168 uint8_t* ValueSerializer::ReserveRawBytes(size_t bytes) {
162 if (!bytes) return nullptr; 169 if (!bytes) return nullptr;
163 auto old_size = buffer_.size(); 170 auto old_size = buffer_.size();
164 buffer_.resize(buffer_.size() + bytes); 171 buffer_.resize(buffer_.size() + bytes);
165 return &buffer_[old_size]; 172 return &buffer_[old_size];
166 } 173 }
167 174
168 Maybe<bool> ValueSerializer::WriteObject(Handle<Object> object) { 175 Maybe<bool> ValueSerializer::WriteObject(Handle<Object> object) {
169 if (object->IsSmi()) { 176 if (object->IsSmi()) {
170 WriteSmi(Smi::cast(*object)); 177 WriteSmi(Smi::cast(*object));
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 return Just(true); 301 return Just(true);
295 case JS_VALUE_TYPE: 302 case JS_VALUE_TYPE:
296 return WriteJSValue(Handle<JSValue>::cast(receiver)); 303 return WriteJSValue(Handle<JSValue>::cast(receiver));
297 case JS_REGEXP_TYPE: 304 case JS_REGEXP_TYPE:
298 WriteJSRegExp(JSRegExp::cast(*receiver)); 305 WriteJSRegExp(JSRegExp::cast(*receiver));
299 return Just(true); 306 return Just(true);
300 case JS_MAP_TYPE: 307 case JS_MAP_TYPE:
301 return WriteJSMap(Handle<JSMap>::cast(receiver)); 308 return WriteJSMap(Handle<JSMap>::cast(receiver));
302 case JS_SET_TYPE: 309 case JS_SET_TYPE:
303 return WriteJSSet(Handle<JSSet>::cast(receiver)); 310 return WriteJSSet(Handle<JSSet>::cast(receiver));
311 case JS_ARRAY_BUFFER_TYPE:
312 return WriteJSArrayBuffer(JSArrayBuffer::cast(*receiver));
304 default: 313 default:
305 UNIMPLEMENTED(); 314 UNIMPLEMENTED();
306 break; 315 break;
307 } 316 }
308 return Nothing<bool>(); 317 return Nothing<bool>();
309 } 318 }
310 319
311 Maybe<bool> ValueSerializer::WriteJSObject(Handle<JSObject> object) { 320 Maybe<bool> ValueSerializer::WriteJSObject(Handle<JSObject> object) {
312 WriteTag(SerializationTag::kBeginJSObject); 321 WriteTag(SerializationTag::kBeginJSObject);
313 Handle<FixedArray> keys; 322 Handle<FixedArray> keys;
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 for (int i = 0; i < length; i++) { 492 for (int i = 0; i < length; i++) {
484 if (!WriteObject(handle(entries->get(i), isolate_)).FromMaybe(false)) { 493 if (!WriteObject(handle(entries->get(i), isolate_)).FromMaybe(false)) {
485 return Nothing<bool>(); 494 return Nothing<bool>();
486 } 495 }
487 } 496 }
488 WriteTag(SerializationTag::kEndJSSet); 497 WriteTag(SerializationTag::kEndJSSet);
489 WriteVarint<uint32_t>(length); 498 WriteVarint<uint32_t>(length);
490 return Just(true); 499 return Just(true);
491 } 500 }
492 501
502 Maybe<bool> ValueSerializer::WriteJSArrayBuffer(JSArrayBuffer* array_buffer) {
503 if (array_buffer->was_neutered()) return Nothing<bool>();
504 double byte_length = array_buffer->byte_length()->Number();
505 if (byte_length > std::numeric_limits<uint32_t>::max()) {
506 return Nothing<bool>();
507 }
508 WriteTag(SerializationTag::kArrayBuffer);
509 WriteVarint<uint32_t>(byte_length);
510 WriteRawBytes(array_buffer->backing_store(), byte_length);
511 return Just(true);
512 }
513
493 Maybe<uint32_t> ValueSerializer::WriteJSObjectProperties( 514 Maybe<uint32_t> ValueSerializer::WriteJSObjectProperties(
494 Handle<JSObject> object, Handle<FixedArray> keys) { 515 Handle<JSObject> object, Handle<FixedArray> keys) {
495 uint32_t properties_written = 0; 516 uint32_t properties_written = 0;
496 int length = keys->length(); 517 int length = keys->length();
497 for (int i = 0; i < length; i++) { 518 for (int i = 0; i < length; i++) {
498 Handle<Object> key(keys->get(i), isolate_); 519 Handle<Object> key(keys->get(i), isolate_);
499 520
500 bool success; 521 bool success;
501 LookupIterator it = LookupIterator::PropertyOrElement( 522 LookupIterator it = LookupIterator::PropertyOrElement(
502 isolate_, object, key, &success, LookupIterator::OWN); 523 isolate_, object, key, &success, LookupIterator::OWN);
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 case SerializationTag::kFalseObject: 697 case SerializationTag::kFalseObject:
677 case SerializationTag::kNumberObject: 698 case SerializationTag::kNumberObject:
678 case SerializationTag::kStringObject: 699 case SerializationTag::kStringObject:
679 return ReadJSValue(tag); 700 return ReadJSValue(tag);
680 case SerializationTag::kRegExp: 701 case SerializationTag::kRegExp:
681 return ReadJSRegExp(); 702 return ReadJSRegExp();
682 case SerializationTag::kBeginJSMap: 703 case SerializationTag::kBeginJSMap:
683 return ReadJSMap(); 704 return ReadJSMap();
684 case SerializationTag::kBeginJSSet: 705 case SerializationTag::kBeginJSSet:
685 return ReadJSSet(); 706 return ReadJSSet();
707 case SerializationTag::kArrayBuffer:
708 return ReadJSArrayBuffer();
686 default: 709 default:
687 return MaybeHandle<Object>(); 710 return MaybeHandle<Object>();
688 } 711 }
689 } 712 }
690 713
691 MaybeHandle<String> ValueDeserializer::ReadUtf8String() { 714 MaybeHandle<String> ValueDeserializer::ReadUtf8String() {
692 uint32_t utf8_length; 715 uint32_t utf8_length;
693 Vector<const uint8_t> utf8_bytes; 716 Vector<const uint8_t> utf8_bytes;
694 if (!ReadVarint<uint32_t>().To(&utf8_length) || 717 if (!ReadVarint<uint32_t>().To(&utf8_length) ||
695 utf8_length > 718 utf8_length >
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 967
945 uint32_t expected_length; 968 uint32_t expected_length;
946 if (!ReadVarint<uint32_t>().To(&expected_length) || 969 if (!ReadVarint<uint32_t>().To(&expected_length) ||
947 length != expected_length) { 970 length != expected_length) {
948 return MaybeHandle<JSSet>(); 971 return MaybeHandle<JSSet>();
949 } 972 }
950 DCHECK(HasObjectWithID(id)); 973 DCHECK(HasObjectWithID(id));
951 return scope.CloseAndEscape(set); 974 return scope.CloseAndEscape(set);
952 } 975 }
953 976
977 MaybeHandle<JSArrayBuffer> ValueDeserializer::ReadJSArrayBuffer() {
978 uint32_t id = next_id_++;
979 uint32_t byte_length;
980 Vector<const uint8_t> bytes;
981 if (!ReadVarint<uint32_t>().To(&byte_length) ||
982 byte_length > static_cast<size_t>(end_ - position_)) {
983 return MaybeHandle<JSArrayBuffer>();
984 }
985 const bool should_initialize = false;
986 Handle<JSArrayBuffer> array_buffer = isolate_->factory()->NewJSArrayBuffer();
987 JSArrayBuffer::SetupAllocatingData(array_buffer, isolate_, byte_length,
988 should_initialize);
989 memcpy(array_buffer->backing_store(), position_, byte_length);
990 position_ += byte_length;
991 AddObjectWithID(id, array_buffer);
992 return array_buffer;
993 }
994
954 Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties( 995 Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties(
955 Handle<JSObject> object, SerializationTag end_tag) { 996 Handle<JSObject> object, SerializationTag end_tag) {
956 for (uint32_t num_properties = 0;; num_properties++) { 997 for (uint32_t num_properties = 0;; num_properties++) {
957 SerializationTag tag; 998 SerializationTag tag;
958 if (!PeekTag().To(&tag)) return Nothing<uint32_t>(); 999 if (!PeekTag().To(&tag)) return Nothing<uint32_t>();
959 if (tag == end_tag) { 1000 if (tag == end_tag) {
960 ConsumeTag(end_tag); 1001 ConsumeTag(end_tag);
961 return Just(num_properties); 1002 return Just(num_properties);
962 } 1003 }
963 1004
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 } 1149 }
1109 #endif 1150 #endif
1110 position_ = end_; 1151 position_ = end_;
1111 1152
1112 if (stack.size() != 1) return MaybeHandle<Object>(); 1153 if (stack.size() != 1) return MaybeHandle<Object>();
1113 return scope.CloseAndEscape(stack[0]); 1154 return scope.CloseAndEscape(stack[0]);
1114 } 1155 }
1115 1156
1116 } // namespace internal 1157 } // namespace internal
1117 } // namespace v8 1158 } // namespace v8
OLDNEW
« no previous file with comments | « src/value-serializer.h ('k') | test/unittests/value-serializer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698