| Index: src/value-serializer.cc
|
| diff --git a/src/value-serializer.cc b/src/value-serializer.cc
|
| index 6c3d7e058c2dbf27d35b2b7d2c02ce5faeb55812..b2828fa7f1dbe0853c677fefb7bc4514ba940d21 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,18 @@ 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>();
|
| + }
|
| + Maybe<bool> result = delegate_->WriteHostObject(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 +770,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 +885,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 +1011,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 +1359,21 @@ 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::Local<v8::Object> object;
|
| + if (!delegate_->ReadHostObject().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++) {
|
|
|