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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 free(buffer_); | 163 free(buffer_); |
164 } | 164 } |
165 } | 165 } |
166 } | 166 } |
167 | 167 |
168 void ValueSerializer::WriteHeader() { | 168 void ValueSerializer::WriteHeader() { |
169 WriteTag(SerializationTag::kVersion); | 169 WriteTag(SerializationTag::kVersion); |
170 WriteVarint(kLatestVersion); | 170 WriteVarint(kLatestVersion); |
171 } | 171 } |
172 | 172 |
| 173 void ValueSerializer::SetTreatArrayBufferViewsAsHostObjects(bool mode) { |
| 174 treat_array_buffer_views_as_host_objects_ = mode; |
| 175 } |
| 176 |
173 void ValueSerializer::WriteTag(SerializationTag tag) { | 177 void ValueSerializer::WriteTag(SerializationTag tag) { |
174 uint8_t raw_tag = static_cast<uint8_t>(tag); | 178 uint8_t raw_tag = static_cast<uint8_t>(tag); |
175 WriteRawBytes(&raw_tag, sizeof(raw_tag)); | 179 WriteRawBytes(&raw_tag, sizeof(raw_tag)); |
176 } | 180 } |
177 | 181 |
178 template <typename T> | 182 template <typename T> |
179 void ValueSerializer::WriteVarint(T value) { | 183 void ValueSerializer::WriteVarint(T value) { |
180 // Writes an unsigned integer as a base-128 varint. | 184 // Writes an unsigned integer as a base-128 varint. |
181 // The number is written, 7 bits at a time, from the least significant to the | 185 // The number is written, 7 bits at a time, from the least significant to the |
182 // most significant 7 bits. Each byte, except the last, has the MSB set. | 186 // most significant 7 bits. Each byte, except the last, has the MSB set. |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 WriteHeapNumber(HeapNumber::cast(*object)); | 315 WriteHeapNumber(HeapNumber::cast(*object)); |
312 return ThrowIfOutOfMemory(); | 316 return ThrowIfOutOfMemory(); |
313 case JS_TYPED_ARRAY_TYPE: | 317 case JS_TYPED_ARRAY_TYPE: |
314 case JS_DATA_VIEW_TYPE: { | 318 case JS_DATA_VIEW_TYPE: { |
315 // Despite being JSReceivers, these have their wrapped buffer serialized | 319 // Despite being JSReceivers, these have their wrapped buffer serialized |
316 // first. That makes this logic a little quirky, because it needs to | 320 // first. That makes this logic a little quirky, because it needs to |
317 // happen before we assign object IDs. | 321 // happen before we assign object IDs. |
318 // TODO(jbroman): It may be possible to avoid materializing a typed | 322 // TODO(jbroman): It may be possible to avoid materializing a typed |
319 // array's buffer here. | 323 // array's buffer here. |
320 Handle<JSArrayBufferView> view = Handle<JSArrayBufferView>::cast(object); | 324 Handle<JSArrayBufferView> view = Handle<JSArrayBufferView>::cast(object); |
321 if (!id_map_.Find(view)) { | 325 if (!id_map_.Find(view) && !treat_array_buffer_views_as_host_objects_) { |
322 Handle<JSArrayBuffer> buffer( | 326 Handle<JSArrayBuffer> buffer( |
323 view->IsJSTypedArray() | 327 view->IsJSTypedArray() |
324 ? Handle<JSTypedArray>::cast(view)->GetBuffer() | 328 ? Handle<JSTypedArray>::cast(view)->GetBuffer() |
325 : handle(JSArrayBuffer::cast(view->buffer()), isolate_)); | 329 : handle(JSArrayBuffer::cast(view->buffer()), isolate_)); |
326 if (!WriteJSReceiver(buffer).FromMaybe(false)) return Nothing<bool>(); | 330 if (!WriteJSReceiver(buffer).FromMaybe(false)) return Nothing<bool>(); |
327 } | 331 } |
328 return WriteJSReceiver(view); | 332 return WriteJSReceiver(view); |
329 } | 333 } |
330 default: | 334 default: |
331 if (object->IsString()) { | 335 if (object->IsString()) { |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 ThrowDataCloneError(MessageTemplate::kDataCloneError, array_buffer); | 765 ThrowDataCloneError(MessageTemplate::kDataCloneError, array_buffer); |
762 return Nothing<bool>(); | 766 return Nothing<bool>(); |
763 } | 767 } |
764 WriteTag(SerializationTag::kArrayBuffer); | 768 WriteTag(SerializationTag::kArrayBuffer); |
765 WriteVarint<uint32_t>(byte_length); | 769 WriteVarint<uint32_t>(byte_length); |
766 WriteRawBytes(array_buffer->backing_store(), byte_length); | 770 WriteRawBytes(array_buffer->backing_store(), byte_length); |
767 return ThrowIfOutOfMemory(); | 771 return ThrowIfOutOfMemory(); |
768 } | 772 } |
769 | 773 |
770 Maybe<bool> ValueSerializer::WriteJSArrayBufferView(JSArrayBufferView* view) { | 774 Maybe<bool> ValueSerializer::WriteJSArrayBufferView(JSArrayBufferView* view) { |
| 775 if (treat_array_buffer_views_as_host_objects_) { |
| 776 return WriteHostObject(handle(view, isolate_)); |
| 777 } |
771 WriteTag(SerializationTag::kArrayBufferView); | 778 WriteTag(SerializationTag::kArrayBufferView); |
772 ArrayBufferViewTag tag = ArrayBufferViewTag::kInt8Array; | 779 ArrayBufferViewTag tag = ArrayBufferViewTag::kInt8Array; |
773 if (view->IsJSTypedArray()) { | 780 if (view->IsJSTypedArray()) { |
774 switch (JSTypedArray::cast(view)->type()) { | 781 switch (JSTypedArray::cast(view)->type()) { |
775 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 782 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
776 case kExternal##Type##Array: \ | 783 case kExternal##Type##Array: \ |
777 tag = ArrayBufferViewTag::k##Type##Array; \ | 784 tag = ArrayBufferViewTag::k##Type##Array; \ |
778 break; | 785 break; |
779 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 786 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
780 #undef TYPED_ARRAY_CASE | 787 #undef TYPED_ARRAY_CASE |
(...skipping 1157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1938 if (stack.size() != 1) { | 1945 if (stack.size() != 1) { |
1939 isolate_->Throw(*isolate_->factory()->NewError( | 1946 isolate_->Throw(*isolate_->factory()->NewError( |
1940 MessageTemplate::kDataCloneDeserializationError)); | 1947 MessageTemplate::kDataCloneDeserializationError)); |
1941 return MaybeHandle<Object>(); | 1948 return MaybeHandle<Object>(); |
1942 } | 1949 } |
1943 return scope.CloseAndEscape(stack[0]); | 1950 return scope.CloseAndEscape(stack[0]); |
1944 } | 1951 } |
1945 | 1952 |
1946 } // namespace internal | 1953 } // namespace internal |
1947 } // namespace v8 | 1954 } // namespace v8 |
OLD | NEW |