| 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 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 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>(); |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |