Index: src/value-serializer.cc |
diff --git a/src/value-serializer.cc b/src/value-serializer.cc |
index 6c3d7e058c2dbf27d35b2b7d2c02ce5faeb55812..3904af3b3238dca3a98713aa92b970bf689b40cd 100644 |
--- a/src/value-serializer.cc |
+++ b/src/value-serializer.cc |
@@ -205,6 +205,14 @@ uint8_t* ValueSerializer::ReserveRawBytes(size_t bytes) { |
return &buffer_[old_size]; |
} |
+void ValueSerializer::WriteUint32(uint32_t value) { |
+ WriteVarint<uint32_t>(value); |
+} |
+ |
+void ValueSerializer::WriteUint64(uint64_t value) { |
+ WriteVarint<uint64_t>(value); |
+} |
+ |
void ValueSerializer::TransferArrayBuffer(uint32_t transfer_id, |
Handle<JSArrayBuffer> array_buffer) { |
DCHECK(!array_buffer_transfer_map_.Find(array_buffer)); |
@@ -352,8 +360,11 @@ Maybe<bool> ValueSerializer::WriteJSReceiver(Handle<JSReceiver> receiver) { |
case JS_ARRAY_TYPE: |
return WriteJSArray(Handle<JSArray>::cast(receiver)); |
case JS_OBJECT_TYPE: |
- case JS_API_OBJECT_TYPE: |
- return WriteJSObject(Handle<JSObject>::cast(receiver)); |
+ case JS_API_OBJECT_TYPE: { |
+ Handle<JSObject> js_object = Handle<JSObject>::cast(receiver); |
+ return js_object->GetInternalFieldCount() ? WriteHostObject(js_object) |
+ : WriteJSObject(js_object); |
+ } |
case JS_DATE_TYPE: |
WriteJSDate(JSDate::cast(*receiver)); |
return Just(true); |
@@ -700,6 +711,20 @@ Maybe<bool> ValueSerializer::WriteJSArrayBufferView(JSArrayBufferView* view) { |
return Just(true); |
} |
+Maybe<bool> ValueSerializer::WriteHostObject(Handle<JSObject> object) { |
+ if (!delegate_) { |
+ isolate_->Throw(*isolate_->factory()->NewError( |
+ isolate_->error_function(), MessageTemplate::kDataCloneError, object)); |
+ return Nothing<bool>(); |
+ } |
+ v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate_); |
+ Maybe<bool> result = |
+ delegate_->WriteHostObject(v8_isolate, Utils::ToLocal(object)); |
+ RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate_, Nothing<bool>()); |
+ DCHECK(!result.IsNothing()); |
+ return result; |
+} |
+ |
Maybe<uint32_t> ValueSerializer::WriteJSObjectPropertiesSlow( |
Handle<JSObject> object, Handle<FixedArray> keys) { |
uint32_t properties_written = 0; |
@@ -747,8 +772,10 @@ void ValueSerializer::ThrowDataCloneError( |
} |
ValueDeserializer::ValueDeserializer(Isolate* isolate, |
- Vector<const uint8_t> data) |
+ Vector<const uint8_t> data, |
+ v8::ValueDeserializer::Delegate* delegate) |
: isolate_(isolate), |
+ delegate_(delegate), |
position_(data.start()), |
end_(data.start() + data.length()), |
id_map_(Handle<SeededNumberDictionary>::cast( |
@@ -860,6 +887,21 @@ Maybe<Vector<const uint8_t>> ValueDeserializer::ReadRawBytes(int size) { |
return Just(Vector<const uint8_t>(start, size)); |
} |
+bool ValueDeserializer::ReadUint32(uint32_t* value) { |
+ return ReadVarint<uint32_t>().To(value); |
+} |
+ |
+bool ValueDeserializer::ReadUint64(uint64_t* value) { |
+ return ReadVarint<uint64_t>().To(value); |
+} |
+ |
+bool ValueDeserializer::ReadRawBytes(size_t length, const void** data) { |
+ if (length > static_cast<size_t>(end_ - position_)) return false; |
+ *data = position_; |
+ position_ += length; |
+ return true; |
+} |
+ |
void ValueDeserializer::TransferArrayBuffer( |
uint32_t transfer_id, Handle<JSArrayBuffer> array_buffer) { |
if (array_buffer_transfer_map_.is_null()) { |
@@ -971,7 +1013,10 @@ MaybeHandle<Object> ValueDeserializer::ReadObjectInternal() { |
return ReadTransferredJSArrayBuffer(is_shared); |
} |
default: |
- return MaybeHandle<Object>(); |
+ // TODO(jbroman): Introduce an explicit tag for host objects to avoid |
+ // having to treat every unknown tag as a potential host object. |
+ position_--; |
+ return ReadHostObject(); |
} |
} |
@@ -1316,6 +1361,22 @@ MaybeHandle<JSArrayBufferView> ValueDeserializer::ReadJSArrayBufferView( |
return typed_array; |
} |
+MaybeHandle<JSObject> ValueDeserializer::ReadHostObject() { |
+ if (!delegate_) return MaybeHandle<JSObject>(); |
+ STACK_CHECK(isolate_, MaybeHandle<JSObject>()); |
+ uint32_t id = next_id_++; |
+ v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate_); |
+ v8::Local<v8::Object> object; |
+ if (!delegate_->ReadHostObject(v8_isolate).ToLocal(&object)) { |
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate_, JSObject); |
+ return MaybeHandle<JSObject>(); |
+ } |
+ Handle<JSObject> js_object = |
+ Handle<JSObject>::cast(Utils::OpenHandle(*object)); |
+ AddObjectWithID(id, js_object); |
+ return js_object; |
+} |
+ |
Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties( |
Handle<JSObject> object, SerializationTag end_tag) { |
for (uint32_t num_properties = 0;; num_properties++) { |