Index: src/value-serializer.cc |
diff --git a/src/value-serializer.cc b/src/value-serializer.cc |
index 8416ea3cd61dea9ad11ba148f83339153b4e4f4a..a41c182e328432f563c7b683deab1c8639ed31ae 100644 |
--- a/src/value-serializer.cc |
+++ b/src/value-serializer.cc |
@@ -124,8 +124,10 @@ enum class ArrayBufferViewTag : uint8_t { |
} // namespace |
-ValueSerializer::ValueSerializer(Isolate* isolate) |
+ValueSerializer::ValueSerializer(Isolate* isolate, |
+ v8::ValueSerializer::Delegate* delegate) |
: isolate_(isolate), |
+ delegate_(delegate), |
zone_(isolate->allocator()), |
id_map_(isolate->heap(), &zone_), |
array_buffer_transfer_map_(isolate->heap(), &zone_) {} |
@@ -247,9 +249,10 @@ Maybe<bool> ValueSerializer::WriteObject(Handle<Object> object) { |
return Just(true); |
} else if (object->IsJSReceiver()) { |
return WriteJSReceiver(Handle<JSReceiver>::cast(object)); |
+ } else { |
+ ThrowDataCloneError(MessageTemplate::kDataCloneError, object); |
+ return Nothing<bool>(); |
} |
- UNIMPLEMENTED(); |
- return Nothing<bool>(); |
} |
} |
@@ -337,11 +340,12 @@ Maybe<bool> ValueSerializer::WriteJSReceiver(Handle<JSReceiver> receiver) { |
// Eliminate callable and exotic objects, which should not be serialized. |
InstanceType instance_type = receiver->map()->instance_type(); |
if (receiver->IsCallable() || instance_type <= LAST_SPECIAL_RECEIVER_TYPE) { |
+ ThrowDataCloneError(MessageTemplate::kDataCloneError, receiver); |
return Nothing<bool>(); |
} |
// If we are at the end of the stack, abort. This function may recurse. |
- if (StackLimitCheck(isolate_).HasOverflowed()) return Nothing<bool>(); |
+ STACK_CHECK(isolate_, Nothing<bool>()); |
HandleScope scope(isolate_); |
switch (instance_type) { |
@@ -368,8 +372,8 @@ Maybe<bool> ValueSerializer::WriteJSReceiver(Handle<JSReceiver> receiver) { |
case JS_DATA_VIEW_TYPE: |
return WriteJSArrayBufferView(JSArrayBufferView::cast(*receiver)); |
default: |
- UNIMPLEMENTED(); |
- break; |
+ ThrowDataCloneError(MessageTemplate::kDataCloneError, receiver); |
+ return Nothing<bool>(); |
} |
return Nothing<bool>(); |
} |
@@ -479,6 +483,7 @@ Maybe<bool> ValueSerializer::WriteJSValue(Handle<JSValue> value) { |
v8::String::NO_NULL_TERMINATION); |
} else { |
DCHECK(inner_value->IsSymbol()); |
+ ThrowDataCloneError(MessageTemplate::kDataCloneError, value); |
return Nothing<bool>(); |
} |
return Just(true); |
@@ -567,10 +572,18 @@ Maybe<bool> ValueSerializer::WriteJSArrayBuffer(JSArrayBuffer* array_buffer) { |
return Just(true); |
} |
- if (array_buffer->is_shared()) return Nothing<bool>(); |
- if (array_buffer->was_neutered()) return Nothing<bool>(); |
+ if (array_buffer->is_shared()) { |
+ ThrowDataCloneError( |
+ MessageTemplate::kDataCloneErrorSharedArrayBufferNotTransferred); |
+ return Nothing<bool>(); |
+ } |
+ if (array_buffer->was_neutered()) { |
+ ThrowDataCloneError(MessageTemplate::kDataCloneErrorNeuteredArrayBuffer); |
+ return Nothing<bool>(); |
+ } |
double byte_length = array_buffer->byte_length()->Number(); |
if (byte_length > std::numeric_limits<uint32_t>::max()) { |
+ ThrowDataCloneError(MessageTemplate::kDataCloneError, handle(array_buffer)); |
return Nothing<bool>(); |
} |
WriteTag(SerializationTag::kArrayBuffer); |
@@ -629,6 +642,24 @@ Maybe<uint32_t> ValueSerializer::WriteJSObjectProperties( |
return Just(properties_written); |
} |
+void ValueSerializer::ThrowDataCloneError( |
+ MessageTemplate::Template template_index) { |
+ return ThrowDataCloneError(template_index, |
+ isolate_->factory()->empty_string()); |
+} |
+ |
+void ValueSerializer::ThrowDataCloneError( |
+ MessageTemplate::Template template_index, Handle<Object> arg0) { |
+ Handle<String> message = |
+ MessageTemplate::FormatMessage(isolate_, template_index, arg0); |
+ if (delegate_) { |
+ delegate_->ThrowDataCloneError(Utils::ToLocal(message)); |
+ } else { |
+ isolate_->Throw( |
+ *isolate_->factory()->NewError(isolate_->error_function(), message)); |
+ } |
+} |
+ |
ValueDeserializer::ValueDeserializer(Isolate* isolate, |
Vector<const uint8_t> data) |
: isolate_(isolate), |
@@ -887,7 +918,7 @@ MaybeHandle<String> ValueDeserializer::ReadTwoByteString() { |
MaybeHandle<JSObject> ValueDeserializer::ReadJSObject() { |
// If we are at the end of the stack, abort. This function may recurse. |
- if (StackLimitCheck(isolate_).HasOverflowed()) return MaybeHandle<JSObject>(); |
+ STACK_CHECK(isolate_, MaybeHandle<JSObject>()); |
uint32_t id = next_id_++; |
HandleScope scope(isolate_); |
@@ -910,7 +941,7 @@ MaybeHandle<JSObject> ValueDeserializer::ReadJSObject() { |
MaybeHandle<JSArray> ValueDeserializer::ReadSparseJSArray() { |
// If we are at the end of the stack, abort. This function may recurse. |
- if (StackLimitCheck(isolate_).HasOverflowed()) return MaybeHandle<JSArray>(); |
+ STACK_CHECK(isolate_, MaybeHandle<JSArray>()); |
uint32_t length; |
if (!ReadVarint<uint32_t>().To(&length)) return MaybeHandle<JSArray>(); |
@@ -938,7 +969,7 @@ MaybeHandle<JSArray> ValueDeserializer::ReadSparseJSArray() { |
MaybeHandle<JSArray> ValueDeserializer::ReadDenseJSArray() { |
// If we are at the end of the stack, abort. This function may recurse. |
- if (StackLimitCheck(isolate_).HasOverflowed()) return MaybeHandle<JSArray>(); |
+ STACK_CHECK(isolate_, MaybeHandle<JSArray>()); |
uint32_t length; |
if (!ReadVarint<uint32_t>().To(&length)) return MaybeHandle<JSArray>(); |
@@ -1042,7 +1073,7 @@ MaybeHandle<JSRegExp> ValueDeserializer::ReadJSRegExp() { |
MaybeHandle<JSMap> ValueDeserializer::ReadJSMap() { |
// If we are at the end of the stack, abort. This function may recurse. |
- if (StackLimitCheck(isolate_).HasOverflowed()) return MaybeHandle<JSMap>(); |
+ STACK_CHECK(isolate_, MaybeHandle<JSMap>()); |
HandleScope scope(isolate_); |
uint32_t id = next_id_++; |
@@ -1079,7 +1110,7 @@ MaybeHandle<JSMap> ValueDeserializer::ReadJSMap() { |
MaybeHandle<JSSet> ValueDeserializer::ReadJSSet() { |
// If we are at the end of the stack, abort. This function may recurse. |
- if (StackLimitCheck(isolate_).HasOverflowed()) return MaybeHandle<JSSet>(); |
+ STACK_CHECK(isolate_, MaybeHandle<JSSet>()); |
HandleScope scope(isolate_); |
uint32_t id = next_id_++; |