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/conversions.h" | 10 #include "src/conversions.h" |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 // Array buffer (transferred). transferID:uint32_t | 96 // Array buffer (transferred). transferID:uint32_t |
97 kArrayBufferTransfer = 't', | 97 kArrayBufferTransfer = 't', |
98 // View into an array buffer. | 98 // View into an array buffer. |
99 // subtag:ArrayBufferViewTag, byteOffset:uint32_t, byteLength:uint32_t | 99 // subtag:ArrayBufferViewTag, byteOffset:uint32_t, byteLength:uint32_t |
100 // For typed arrays, byteOffset and byteLength must be divisible by the size | 100 // For typed arrays, byteOffset and byteLength must be divisible by the size |
101 // of the element. | 101 // of the element. |
102 // Note: kArrayBufferView is special, and should have an ArrayBuffer (or an | 102 // Note: kArrayBufferView is special, and should have an ArrayBuffer (or an |
103 // ObjectReference to one) serialized just before it. This is a quirk arising | 103 // ObjectReference to one) serialized just before it. This is a quirk arising |
104 // from the previous stack-based implementation. | 104 // from the previous stack-based implementation. |
105 kArrayBufferView = 'V', | 105 kArrayBufferView = 'V', |
| 106 // Shared array buffer (transferred). transferID:uint32_t |
| 107 kSharedArrayBufferTransfer = 'u', |
106 }; | 108 }; |
107 | 109 |
108 namespace { | 110 namespace { |
109 | 111 |
110 enum class ArrayBufferViewTag : uint8_t { | 112 enum class ArrayBufferViewTag : uint8_t { |
111 kInt8Array = 'b', | 113 kInt8Array = 'b', |
112 kUint8Array = 'B', | 114 kUint8Array = 'B', |
113 kUint8ClampedArray = 'C', | 115 kUint8ClampedArray = 'C', |
114 kInt16Array = 'w', | 116 kInt16Array = 'w', |
115 kUint16Array = 'W', | 117 kUint16Array = 'W', |
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 } | 552 } |
551 } | 553 } |
552 WriteTag(SerializationTag::kEndJSSet); | 554 WriteTag(SerializationTag::kEndJSSet); |
553 WriteVarint<uint32_t>(length); | 555 WriteVarint<uint32_t>(length); |
554 return Just(true); | 556 return Just(true); |
555 } | 557 } |
556 | 558 |
557 Maybe<bool> ValueSerializer::WriteJSArrayBuffer(JSArrayBuffer* array_buffer) { | 559 Maybe<bool> ValueSerializer::WriteJSArrayBuffer(JSArrayBuffer* array_buffer) { |
558 uint32_t* transfer_entry = array_buffer_transfer_map_.Find(array_buffer); | 560 uint32_t* transfer_entry = array_buffer_transfer_map_.Find(array_buffer); |
559 if (transfer_entry) { | 561 if (transfer_entry) { |
560 DCHECK(array_buffer->was_neutered()); | 562 DCHECK(array_buffer->was_neutered() || array_buffer->is_shared()); |
561 WriteTag(SerializationTag::kArrayBufferTransfer); | 563 WriteTag(array_buffer->is_shared() |
| 564 ? SerializationTag::kSharedArrayBufferTransfer |
| 565 : SerializationTag::kArrayBufferTransfer); |
562 WriteVarint(*transfer_entry); | 566 WriteVarint(*transfer_entry); |
563 return Just(true); | 567 return Just(true); |
564 } | 568 } |
565 | 569 |
| 570 if (array_buffer->is_shared()) return Nothing<bool>(); |
566 if (array_buffer->was_neutered()) return Nothing<bool>(); | 571 if (array_buffer->was_neutered()) return Nothing<bool>(); |
567 double byte_length = array_buffer->byte_length()->Number(); | 572 double byte_length = array_buffer->byte_length()->Number(); |
568 if (byte_length > std::numeric_limits<uint32_t>::max()) { | 573 if (byte_length > std::numeric_limits<uint32_t>::max()) { |
569 return Nothing<bool>(); | 574 return Nothing<bool>(); |
570 } | 575 } |
571 WriteTag(SerializationTag::kArrayBuffer); | 576 WriteTag(SerializationTag::kArrayBuffer); |
572 WriteVarint<uint32_t>(byte_length); | 577 WriteVarint<uint32_t>(byte_length); |
573 WriteRawBytes(array_buffer->backing_store(), byte_length); | 578 WriteRawBytes(array_buffer->backing_store(), byte_length); |
574 return Just(true); | 579 return Just(true); |
575 } | 580 } |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 case SerializationTag::kStringObject: | 830 case SerializationTag::kStringObject: |
826 return ReadJSValue(tag); | 831 return ReadJSValue(tag); |
827 case SerializationTag::kRegExp: | 832 case SerializationTag::kRegExp: |
828 return ReadJSRegExp(); | 833 return ReadJSRegExp(); |
829 case SerializationTag::kBeginJSMap: | 834 case SerializationTag::kBeginJSMap: |
830 return ReadJSMap(); | 835 return ReadJSMap(); |
831 case SerializationTag::kBeginJSSet: | 836 case SerializationTag::kBeginJSSet: |
832 return ReadJSSet(); | 837 return ReadJSSet(); |
833 case SerializationTag::kArrayBuffer: | 838 case SerializationTag::kArrayBuffer: |
834 return ReadJSArrayBuffer(); | 839 return ReadJSArrayBuffer(); |
835 case SerializationTag::kArrayBufferTransfer: | 840 case SerializationTag::kArrayBufferTransfer: { |
836 return ReadTransferredJSArrayBuffer(); | 841 const bool is_shared = false; |
| 842 return ReadTransferredJSArrayBuffer(is_shared); |
| 843 } |
| 844 case SerializationTag::kSharedArrayBufferTransfer: { |
| 845 const bool is_shared = true; |
| 846 return ReadTransferredJSArrayBuffer(is_shared); |
| 847 } |
837 default: | 848 default: |
838 return MaybeHandle<Object>(); | 849 return MaybeHandle<Object>(); |
839 } | 850 } |
840 } | 851 } |
841 | 852 |
842 MaybeHandle<String> ValueDeserializer::ReadUtf8String() { | 853 MaybeHandle<String> ValueDeserializer::ReadUtf8String() { |
843 uint32_t utf8_length; | 854 uint32_t utf8_length; |
844 Vector<const uint8_t> utf8_bytes; | 855 Vector<const uint8_t> utf8_bytes; |
845 if (!ReadVarint<uint32_t>().To(&utf8_length) || | 856 if (!ReadVarint<uint32_t>().To(&utf8_length) || |
846 utf8_length > | 857 utf8_length > |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1113 const bool should_initialize = false; | 1124 const bool should_initialize = false; |
1114 Handle<JSArrayBuffer> array_buffer = isolate_->factory()->NewJSArrayBuffer(); | 1125 Handle<JSArrayBuffer> array_buffer = isolate_->factory()->NewJSArrayBuffer(); |
1115 JSArrayBuffer::SetupAllocatingData(array_buffer, isolate_, byte_length, | 1126 JSArrayBuffer::SetupAllocatingData(array_buffer, isolate_, byte_length, |
1116 should_initialize); | 1127 should_initialize); |
1117 memcpy(array_buffer->backing_store(), position_, byte_length); | 1128 memcpy(array_buffer->backing_store(), position_, byte_length); |
1118 position_ += byte_length; | 1129 position_ += byte_length; |
1119 AddObjectWithID(id, array_buffer); | 1130 AddObjectWithID(id, array_buffer); |
1120 return array_buffer; | 1131 return array_buffer; |
1121 } | 1132 } |
1122 | 1133 |
1123 MaybeHandle<JSArrayBuffer> ValueDeserializer::ReadTransferredJSArrayBuffer() { | 1134 MaybeHandle<JSArrayBuffer> ValueDeserializer::ReadTransferredJSArrayBuffer( |
| 1135 bool is_shared) { |
1124 uint32_t id = next_id_++; | 1136 uint32_t id = next_id_++; |
1125 uint32_t transfer_id; | 1137 uint32_t transfer_id; |
1126 Handle<SeededNumberDictionary> transfer_map; | 1138 Handle<SeededNumberDictionary> transfer_map; |
1127 if (!ReadVarint<uint32_t>().To(&transfer_id) || | 1139 if (!ReadVarint<uint32_t>().To(&transfer_id) || |
1128 !array_buffer_transfer_map_.ToHandle(&transfer_map)) { | 1140 !array_buffer_transfer_map_.ToHandle(&transfer_map)) { |
1129 return MaybeHandle<JSArrayBuffer>(); | 1141 return MaybeHandle<JSArrayBuffer>(); |
1130 } | 1142 } |
1131 int index = transfer_map->FindEntry(isolate_, transfer_id); | 1143 int index = transfer_map->FindEntry(isolate_, transfer_id); |
1132 if (index == SeededNumberDictionary::kNotFound) { | 1144 if (index == SeededNumberDictionary::kNotFound) { |
1133 return MaybeHandle<JSArrayBuffer>(); | 1145 return MaybeHandle<JSArrayBuffer>(); |
1134 } | 1146 } |
1135 Handle<JSArrayBuffer> array_buffer( | 1147 Handle<JSArrayBuffer> array_buffer( |
1136 JSArrayBuffer::cast(transfer_map->ValueAt(index)), isolate_); | 1148 JSArrayBuffer::cast(transfer_map->ValueAt(index)), isolate_); |
| 1149 DCHECK_EQ(is_shared, array_buffer->is_shared()); |
1137 AddObjectWithID(id, array_buffer); | 1150 AddObjectWithID(id, array_buffer); |
1138 return array_buffer; | 1151 return array_buffer; |
1139 } | 1152 } |
1140 | 1153 |
1141 MaybeHandle<JSArrayBufferView> ValueDeserializer::ReadJSArrayBufferView( | 1154 MaybeHandle<JSArrayBufferView> ValueDeserializer::ReadJSArrayBufferView( |
1142 Handle<JSArrayBuffer> buffer) { | 1155 Handle<JSArrayBuffer> buffer) { |
1143 uint32_t buffer_byte_length = NumberToUint32(buffer->byte_length()); | 1156 uint32_t buffer_byte_length = NumberToUint32(buffer->byte_length()); |
1144 uint8_t tag; | 1157 uint8_t tag; |
1145 uint32_t byte_offset; | 1158 uint32_t byte_offset; |
1146 uint32_t byte_length; | 1159 uint32_t byte_length; |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1335 } | 1348 } |
1336 #endif | 1349 #endif |
1337 position_ = end_; | 1350 position_ = end_; |
1338 | 1351 |
1339 if (stack.size() != 1) return MaybeHandle<Object>(); | 1352 if (stack.size() != 1) return MaybeHandle<Object>(); |
1340 return scope.CloseAndEscape(stack[0]); | 1353 return scope.CloseAndEscape(stack[0]); |
1341 } | 1354 } |
1342 | 1355 |
1343 } // namespace internal | 1356 } // namespace internal |
1344 } // namespace v8 | 1357 } // namespace v8 |
OLD | NEW |