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

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: cast to size_t (windows) 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 draw data.
Jakob Kummerow 2016/08/25 08:59:36 nit: s/draw/raw/?
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>();
Jakob Kummerow 2016/08/25 08:59:36 nit: {}
507 WriteTag(SerializationTag::kArrayBuffer);
508 WriteVarint<uint32_t>(byte_length);
509 WriteRawBytes(array_buffer->backing_store(), byte_length);
510 return Just(true);
511 }
512
493 Maybe<uint32_t> ValueSerializer::WriteJSObjectProperties( 513 Maybe<uint32_t> ValueSerializer::WriteJSObjectProperties(
494 Handle<JSObject> object, Handle<FixedArray> keys) { 514 Handle<JSObject> object, Handle<FixedArray> keys) {
495 uint32_t properties_written = 0; 515 uint32_t properties_written = 0;
496 int length = keys->length(); 516 int length = keys->length();
497 for (int i = 0; i < length; i++) { 517 for (int i = 0; i < length; i++) {
498 Handle<Object> key(keys->get(i), isolate_); 518 Handle<Object> key(keys->get(i), isolate_);
499 519
500 bool success; 520 bool success;
501 LookupIterator it = LookupIterator::PropertyOrElement( 521 LookupIterator it = LookupIterator::PropertyOrElement(
502 isolate_, object, key, &success, LookupIterator::OWN); 522 isolate_, object, key, &success, LookupIterator::OWN);
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 case SerializationTag::kFalseObject: 696 case SerializationTag::kFalseObject:
677 case SerializationTag::kNumberObject: 697 case SerializationTag::kNumberObject:
678 case SerializationTag::kStringObject: 698 case SerializationTag::kStringObject:
679 return ReadJSValue(tag); 699 return ReadJSValue(tag);
680 case SerializationTag::kRegExp: 700 case SerializationTag::kRegExp:
681 return ReadJSRegExp(); 701 return ReadJSRegExp();
682 case SerializationTag::kBeginJSMap: 702 case SerializationTag::kBeginJSMap:
683 return ReadJSMap(); 703 return ReadJSMap();
684 case SerializationTag::kBeginJSSet: 704 case SerializationTag::kBeginJSSet:
685 return ReadJSSet(); 705 return ReadJSSet();
706 case SerializationTag::kArrayBuffer:
707 return ReadJSArrayBuffer();
686 default: 708 default:
687 return MaybeHandle<Object>(); 709 return MaybeHandle<Object>();
688 } 710 }
689 } 711 }
690 712
691 MaybeHandle<String> ValueDeserializer::ReadUtf8String() { 713 MaybeHandle<String> ValueDeserializer::ReadUtf8String() {
692 uint32_t utf8_length; 714 uint32_t utf8_length;
693 Vector<const uint8_t> utf8_bytes; 715 Vector<const uint8_t> utf8_bytes;
694 if (!ReadVarint<uint32_t>().To(&utf8_length) || 716 if (!ReadVarint<uint32_t>().To(&utf8_length) ||
695 utf8_length > 717 utf8_length >
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 966
945 uint32_t expected_length; 967 uint32_t expected_length;
946 if (!ReadVarint<uint32_t>().To(&expected_length) || 968 if (!ReadVarint<uint32_t>().To(&expected_length) ||
947 length != expected_length) { 969 length != expected_length) {
948 return MaybeHandle<JSSet>(); 970 return MaybeHandle<JSSet>();
949 } 971 }
950 DCHECK(HasObjectWithID(id)); 972 DCHECK(HasObjectWithID(id));
951 return scope.CloseAndEscape(set); 973 return scope.CloseAndEscape(set);
952 } 974 }
953 975
976 MaybeHandle<JSArrayBuffer> ValueDeserializer::ReadJSArrayBuffer() {
977 uint32_t id = next_id_++;
978 uint32_t byte_length;
979 Vector<const uint8_t> bytes;
980 if (!ReadVarint<uint32_t>().To(&byte_length) ||
981 byte_length > static_cast<size_t>(end_ - position_)) {
982 return MaybeHandle<JSArrayBuffer>();
983 }
984 const bool should_initialize = false;
985 Handle<JSArrayBuffer> array_buffer = isolate_->factory()->NewJSArrayBuffer();
986 JSArrayBuffer::SetupAllocatingData(array_buffer, isolate_, byte_length,
987 should_initialize);
988 memcpy(array_buffer->backing_store(), position_, byte_length);
989 position_ += byte_length;
990 AddObjectWithID(id, array_buffer);
991 return array_buffer;
992 }
993
954 Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties( 994 Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties(
955 Handle<JSObject> object, SerializationTag end_tag) { 995 Handle<JSObject> object, SerializationTag end_tag) {
956 for (uint32_t num_properties = 0;; num_properties++) { 996 for (uint32_t num_properties = 0;; num_properties++) {
957 SerializationTag tag; 997 SerializationTag tag;
958 if (!PeekTag().To(&tag)) return Nothing<uint32_t>(); 998 if (!PeekTag().To(&tag)) return Nothing<uint32_t>();
959 if (tag == end_tag) { 999 if (tag == end_tag) {
960 ConsumeTag(end_tag); 1000 ConsumeTag(end_tag);
961 return Just(num_properties); 1001 return Just(num_properties);
962 } 1002 }
963 1003
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 } 1148 }
1109 #endif 1149 #endif
1110 position_ = end_; 1150 position_ = end_;
1111 1151
1112 if (stack.size() != 1) return MaybeHandle<Object>(); 1152 if (stack.size() != 1) return MaybeHandle<Object>();
1113 return scope.CloseAndEscape(stack[0]); 1153 return scope.CloseAndEscape(stack[0]);
1114 } 1154 }
1115 1155
1116 } // namespace internal 1156 } // namespace internal
1117 } // namespace v8 1157 } // 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