| 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_++;
|
|
|