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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |