Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(295)

Side by Side Diff: third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp

Issue 1423513005: Reland of: Make Imagebitmap Transferable (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase and issue fixing Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium 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 "config.h" 5 #include "config.h"
6 #include "bindings/core/v8/ScriptValueSerializer.h" 6 #include "bindings/core/v8/ScriptValueSerializer.h"
7 7
8 #include "bindings/core/v8/V8ArrayBuffer.h" 8 #include "bindings/core/v8/V8ArrayBuffer.h"
9 #include "bindings/core/v8/V8ArrayBufferView.h" 9 #include "bindings/core/v8/V8ArrayBufferView.h"
10 #include "bindings/core/v8/V8Blob.h" 10 #include "bindings/core/v8/V8Blob.h"
11 #include "bindings/core/v8/V8CompositorProxy.h" 11 #include "bindings/core/v8/V8CompositorProxy.h"
12 #include "bindings/core/v8/V8File.h" 12 #include "bindings/core/v8/V8File.h"
13 #include "bindings/core/v8/V8FileList.h" 13 #include "bindings/core/v8/V8FileList.h"
14 #include "bindings/core/v8/V8ImageBitmap.h"
14 #include "bindings/core/v8/V8ImageData.h" 15 #include "bindings/core/v8/V8ImageData.h"
15 #include "bindings/core/v8/V8MessagePort.h" 16 #include "bindings/core/v8/V8MessagePort.h"
16 #include "bindings/core/v8/V8SharedArrayBuffer.h" 17 #include "bindings/core/v8/V8SharedArrayBuffer.h"
17 #include "core/dom/CompositorProxy.h" 18 #include "core/dom/CompositorProxy.h"
18 #include "core/dom/DOMDataView.h" 19 #include "core/dom/DOMDataView.h"
19 #include "core/dom/DOMSharedArrayBuffer.h" 20 #include "core/dom/DOMSharedArrayBuffer.h"
20 #include "core/dom/DOMTypedArray.h" 21 #include "core/dom/DOMTypedArray.h"
21 #include "core/fileapi/Blob.h" 22 #include "core/fileapi/Blob.h"
22 #include "core/fileapi/File.h" 23 #include "core/fileapi/File.h"
23 #include "core/fileapi/FileList.h" 24 #include "core/fileapi/FileList.h"
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 append(MessagePortTag); 317 append(MessagePortTag);
317 doWriteUint32(index); 318 doWriteUint32(index);
318 } 319 }
319 320
320 void SerializedScriptValueWriter::writeTransferredArrayBuffer(uint32_t index) 321 void SerializedScriptValueWriter::writeTransferredArrayBuffer(uint32_t index)
321 { 322 {
322 append(ArrayBufferTransferTag); 323 append(ArrayBufferTransferTag);
323 doWriteUint32(index); 324 doWriteUint32(index);
324 } 325 }
325 326
327 void SerializedScriptValueWriter::writeTransferredImageBitmap(uint32_t index)
328 {
329 append(ImageBitmapTransferTag);
330 doWriteUint32(index);
331 }
332
326 void SerializedScriptValueWriter::writeTransferredSharedArrayBuffer(uint32_t ind ex) 333 void SerializedScriptValueWriter::writeTransferredSharedArrayBuffer(uint32_t ind ex)
327 { 334 {
328 ASSERT(RuntimeEnabledFeatures::sharedArrayBufferEnabled()); 335 ASSERT(RuntimeEnabledFeatures::sharedArrayBufferEnabled());
329 append(SharedArrayBufferTransferTag); 336 append(SharedArrayBufferTransferTag);
330 doWriteUint32(index); 337 doWriteUint32(index);
331 } 338 }
332 339
333 void SerializedScriptValueWriter::writeObjectReference(uint32_t reference) 340 void SerializedScriptValueWriter::writeObjectReference(uint32_t reference)
334 { 341 {
335 append(ObjectReferenceTag); 342 append(ObjectReferenceTag);
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 { 636 {
630 if (!impl) 637 if (!impl)
631 return v8::Local<v8::Object>(); 638 return v8::Local<v8::Object>();
632 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate); 639 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate);
633 if (wrapper.IsEmpty()) 640 if (wrapper.IsEmpty())
634 return v8::Local<v8::Object>(); 641 return v8::Local<v8::Object>();
635 ASSERT(wrapper->IsObject()); 642 ASSERT(wrapper->IsObject());
636 return wrapper.As<v8::Object>(); 643 return wrapper.As<v8::Object>();
637 } 644 }
638 645
646 static v8::Local<v8::Object> toV8Object(ImageBitmap* impl, v8::Local<v8::Object> creationContext, v8::Isolate* isolate)
647 {
648 if (!impl)
649 return v8::Local<v8::Object>();
650 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate);
651 if (wrapper.IsEmpty())
652 return v8::Local<v8::Object>();
653 return wrapper.As<v8::Object>();
654 }
655
639 static v8::Local<v8::Object> toV8Object(DOMArrayBufferBase* impl, v8::Local<v8:: Object> creationContext, v8::Isolate* isolate) 656 static v8::Local<v8::Object> toV8Object(DOMArrayBufferBase* impl, v8::Local<v8:: Object> creationContext, v8::Isolate* isolate)
640 { 657 {
641 if (!impl) 658 if (!impl)
642 return v8::Local<v8::Object>(); 659 return v8::Local<v8::Object>();
643 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate); 660 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate);
644 if (wrapper.IsEmpty()) 661 if (wrapper.IsEmpty())
645 return v8::Local<v8::Object>(); 662 return v8::Local<v8::Object>();
646 return wrapper.As<v8::Object>(); 663 return wrapper.As<v8::Object>();
647 } 664 }
648 665
649 // Returns true if the provided object is to be considered a 'host object', as u sed in the 666 // Returns true if the provided object is to be considered a 'host object', as u sed in the
650 // HTML5 structured clone algorithm. 667 // HTML5 structured clone algorithm.
651 static bool isHostObject(v8::Local<v8::Object> object) 668 static bool isHostObject(v8::Local<v8::Object> object)
652 { 669 {
653 // If the object has any internal fields, then we won't be able to serialize or deserialize 670 // If the object has any internal fields, then we won't be able to serialize or deserialize
654 // them; conveniently, this is also a quick way to detect DOM wrapper object s, because 671 // them; conveniently, this is also a quick way to detect DOM wrapper object s, because
655 // the mechanism for these relies on data stored in these fields. We should 672 // the mechanism for these relies on data stored in these fields. We should
656 // catch external array data as a special case. 673 // catch external array data as a special case.
657 return object->InternalFieldCount(); 674 return object->InternalFieldCount();
658 } 675 }
659 676
660 ScriptValueSerializer::ScriptValueSerializer(SerializedScriptValueWriter& writer , MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, WebBlobInfoArr ay* blobInfo, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, Script State* scriptState) 677 ScriptValueSerializer::ScriptValueSerializer(SerializedScriptValueWriter& writer , MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, ImageBitmapArr ay* imageBitmaps, WebBlobInfoArray* blobInfo, BlobDataHandleMap& blobDataHandles , v8::TryCatch& tryCatch, ScriptState* scriptState)
661 : m_scriptState(scriptState) 678 : m_scriptState(scriptState)
662 , m_writer(writer) 679 , m_writer(writer)
663 , m_tryCatch(tryCatch) 680 , m_tryCatch(tryCatch)
664 , m_depth(0) 681 , m_depth(0)
665 , m_status(Success) 682 , m_status(Success)
666 , m_nextObjectReference(0) 683 , m_nextObjectReference(0)
667 , m_blobInfo(blobInfo) 684 , m_blobInfo(blobInfo)
668 , m_blobDataHandles(blobDataHandles) 685 , m_blobDataHandles(blobDataHandles)
669 { 686 {
670 ASSERT(!tryCatch.HasCaught()); 687 ASSERT(!tryCatch.HasCaught());
671 v8::Local<v8::Object> creationContext = m_scriptState->context()->Global(); 688 v8::Local<v8::Object> creationContext = m_scriptState->context()->Global();
672 if (messagePorts) { 689 if (messagePorts) {
673 for (size_t i = 0; i < messagePorts->size(); i++) 690 for (size_t i = 0; i < messagePorts->size(); i++)
674 m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get(), creationContext, isolate()), i); 691 m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get(), creationContext, isolate()), i);
675 } 692 }
676 if (arrayBuffers) { 693 if (arrayBuffers) {
677 for (size_t i = 0; i < arrayBuffers->size(); i++) { 694 for (size_t i = 0; i < arrayBuffers->size(); i++) {
678 v8::Local<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->at(i) .get(), creationContext, isolate()); 695 v8::Local<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->at(i) .get(), creationContext, isolate());
679 // Coalesce multiple occurences of the same buffer to the first inde x. 696 // Coalesce multiple occurences of the same buffer to the first inde x.
680 if (!m_transferredArrayBuffers.contains(v8ArrayBuffer)) 697 if (!m_transferredArrayBuffers.contains(v8ArrayBuffer))
681 m_transferredArrayBuffers.set(v8ArrayBuffer, i); 698 m_transferredArrayBuffers.set(v8ArrayBuffer, i);
682 } 699 }
683 } 700 }
701 if (imageBitmaps) {
702 for (size_t i = 0; i < imageBitmaps->size(); i++) {
703 v8::Local<v8::Object> v8ImageBitmap = toV8Object(imageBitmaps->at(i) .get(), creationContext, isolate());
704 if (!m_transferredImageBitmaps.contains(v8ImageBitmap))
705 m_transferredImageBitmaps.set(v8ImageBitmap, i);
706 }
707 }
684 } 708 }
685 709
686 ScriptValueSerializer::Status ScriptValueSerializer::serialize(v8::Local<v8::Val ue> value) 710 ScriptValueSerializer::Status ScriptValueSerializer::serialize(v8::Local<v8::Val ue> value)
687 { 711 {
688 v8::HandleScope scope(isolate()); 712 v8::HandleScope scope(isolate());
689 m_writer.writeVersion(); 713 m_writer.writeVersion();
690 StateBase* state = doSerialize(value, 0); 714 StateBase* state = doSerialize(value, 0);
691 while (state) 715 while (state)
692 state = state->advance(*this); 716 state = state->advance(*this);
693 return m_status; 717 return m_status;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 } else if (value->IsUint32()) { 750 } else if (value->IsUint32()) {
727 m_writer.writeUint32(value.As<v8::Uint32>()->Value()); 751 m_writer.writeUint32(value.As<v8::Uint32>()->Value());
728 } else if (value->IsNumber()) { 752 } else if (value->IsNumber()) {
729 m_writer.writeNumber(value.As<v8::Number>()->Value()); 753 m_writer.writeNumber(value.As<v8::Number>()->Value());
730 } else if (value->IsString()) { 754 } else if (value->IsString()) {
731 writeString(value); 755 writeString(value);
732 } else if (value->IsObject()) { 756 } else if (value->IsObject()) {
733 v8::Local<v8::Object> jsObject = value.As<v8::Object>(); 757 v8::Local<v8::Object> jsObject = value.As<v8::Object>();
734 758
735 uint32_t arrayBufferIndex; 759 uint32_t arrayBufferIndex;
760 uint32_t imageBitmapIndex;
736 if (V8ArrayBufferView::hasInstance(value, isolate())) { 761 if (V8ArrayBufferView::hasInstance(value, isolate())) {
737 return writeAndGreyArrayBufferView(jsObject, next); 762 return writeAndGreyArrayBufferView(jsObject, next);
738 } else if (V8MessagePort::hasInstance(value, isolate())) { 763 } else if (V8MessagePort::hasInstance(value, isolate())) {
739 uint32_t messagePortIndex; 764 uint32_t messagePortIndex;
740 if (!m_transferredMessagePorts.tryGet(jsObject, &messagePortIndex)) 765 if (!m_transferredMessagePorts.tryGet(jsObject, &messagePortIndex))
741 return handleError(DataCloneError, "A MessagePort could not be c loned.", next); 766 return handleError(DataCloneError, "A MessagePort could not be c loned.", next);
742 m_writer.writeTransferredMessagePort(messagePortIndex); 767 m_writer.writeTransferredMessagePort(messagePortIndex);
743 return nullptr; 768 return nullptr;
744 } else if (V8ArrayBuffer::hasInstance(value, isolate()) && m_transferred ArrayBuffers.tryGet(jsObject, &arrayBufferIndex)) { 769 } else if (V8ArrayBuffer::hasInstance(value, isolate()) && m_transferred ArrayBuffers.tryGet(jsObject, &arrayBufferIndex)) {
745 return writeTransferredArrayBuffer(value, arrayBufferIndex, next); 770 return writeTransferredArrayBuffer(value, arrayBufferIndex, next);
771 } else if (V8ImageBitmap::hasInstance(value, isolate()) && m_transferred ImageBitmaps.tryGet(jsObject, &imageBitmapIndex)) {
772 return writeTransferredImageBitmap(value, imageBitmapIndex, next);
746 } else if (V8SharedArrayBuffer::hasInstance(value, isolate()) && m_trans ferredArrayBuffers.tryGet(jsObject, &arrayBufferIndex)) { 773 } else if (V8SharedArrayBuffer::hasInstance(value, isolate()) && m_trans ferredArrayBuffers.tryGet(jsObject, &arrayBufferIndex)) {
747 return writeTransferredSharedArrayBuffer(value, arrayBufferIndex, ne xt); 774 return writeTransferredSharedArrayBuffer(value, arrayBufferIndex, ne xt);
748 } 775 }
749 776
750 greyObject(jsObject); 777 greyObject(jsObject);
751 if (value->IsDate()) { 778 if (value->IsDate()) {
752 m_writer.writeDate(value.As<v8::Date>()->ValueOf()); 779 m_writer.writeDate(value.As<v8::Date>()->ValueOf());
753 } else if (value->IsStringObject()) { 780 } else if (value->IsStringObject()) {
754 writeStringObject(value); 781 writeStringObject(value);
755 } else if (value->IsNumberObject()) { 782 } else if (value->IsNumberObject()) {
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 { 1043 {
1017 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(value.As<v8::Object>()); 1044 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(value.As<v8::Object>());
1018 if (!arrayBuffer) 1045 if (!arrayBuffer)
1019 return 0; 1046 return 0;
1020 if (arrayBuffer->isNeutered()) 1047 if (arrayBuffer->isNeutered())
1021 return handleError(DataCloneError, "An ArrayBuffer is neutered and could not be cloned.", next); 1048 return handleError(DataCloneError, "An ArrayBuffer is neutered and could not be cloned.", next);
1022 m_writer.writeTransferredArrayBuffer(index); 1049 m_writer.writeTransferredArrayBuffer(index);
1023 return 0; 1050 return 0;
1024 } 1051 }
1025 1052
1053 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeTransferredImageBi tmap(v8::Local<v8::Value> value, uint32_t index, ScriptValueSerializer::StateBas e* next)
1054 {
1055 ImageBitmap* imageBitmap = V8ImageBitmap::toImpl(value.As<v8::Object>());
1056 if (!imageBitmap)
1057 return 0;
1058 if (imageBitmap->isNeutered())
1059 return handleError(DataCloneError, "An ImageBitmap is neutered and could not be cloned.", next);
1060 m_writer.writeTransferredImageBitmap(index);
1061 return 0;
1062 }
1063
1026 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeTransferredSharedA rrayBuffer(v8::Local<v8::Value> value, uint32_t index, ScriptValueSerializer::St ateBase* next) 1064 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeTransferredSharedA rrayBuffer(v8::Local<v8::Value> value, uint32_t index, ScriptValueSerializer::St ateBase* next)
1027 { 1065 {
1028 ASSERT(RuntimeEnabledFeatures::sharedArrayBufferEnabled()); 1066 ASSERT(RuntimeEnabledFeatures::sharedArrayBufferEnabled());
1029 DOMSharedArrayBuffer* sharedArrayBuffer = V8SharedArrayBuffer::toImpl(value. As<v8::Object>()); 1067 DOMSharedArrayBuffer* sharedArrayBuffer = V8SharedArrayBuffer::toImpl(value. As<v8::Object>());
1030 if (!sharedArrayBuffer) 1068 if (!sharedArrayBuffer)
1031 return 0; 1069 return 0;
1032 m_writer.writeTransferredSharedArrayBuffer(index); 1070 m_writer.writeTransferredSharedArrayBuffer(index);
1033 return 0; 1071 return 0;
1034 } 1072 }
1035 1073
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
1344 case ArrayBufferTransferTag: { 1382 case ArrayBufferTransferTag: {
1345 if (!m_version) 1383 if (!m_version)
1346 return false; 1384 return false;
1347 uint32_t index; 1385 uint32_t index;
1348 if (!doReadUint32(&index)) 1386 if (!doReadUint32(&index))
1349 return false; 1387 return false;
1350 if (!creator.tryGetTransferredArrayBuffer(index, value)) 1388 if (!creator.tryGetTransferredArrayBuffer(index, value))
1351 return false; 1389 return false;
1352 break; 1390 break;
1353 } 1391 }
1392 case ImageBitmapTransferTag: {
1393 if (!m_version)
1394 return false;
1395 uint32_t index;
1396 if (!doReadUint32(&index))
1397 return false;
1398 if (!creator.tryGetTransferredImageBitmap(index, value))
1399 return false;
1400 break;
1401 }
1354 case SharedArrayBufferTransferTag: { 1402 case SharedArrayBufferTransferTag: {
1355 if (!m_version) 1403 if (!m_version)
1356 return false; 1404 return false;
1357 uint32_t index; 1405 uint32_t index;
1358 if (!doReadUint32(&index)) 1406 if (!doReadUint32(&index))
1359 return false; 1407 return false;
1360 if (!creator.tryGetTransferredSharedArrayBuffer(index, value)) 1408 if (!creator.tryGetTransferredSharedArrayBuffer(index, value))
1361 return false; 1409 return false;
1362 break; 1410 break;
1363 } 1411 }
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after
2058 v8::Local<v8::Object> creationContext = m_reader.scriptState()->context( )->Global(); 2106 v8::Local<v8::Object> creationContext = m_reader.scriptState()->context( )->Global();
2059 result = toV8(buffer.get(), creationContext, isolate); 2107 result = toV8(buffer.get(), creationContext, isolate);
2060 if (result.IsEmpty()) 2108 if (result.IsEmpty())
2061 return false; 2109 return false;
2062 m_arrayBuffers[index] = result; 2110 m_arrayBuffers[index] = result;
2063 } 2111 }
2064 *object = result; 2112 *object = result;
2065 return true; 2113 return true;
2066 } 2114 }
2067 2115
2116 bool ScriptValueDeserializer::tryGetTransferredImageBitmap(uint32_t index, v8::L ocal<v8::Value>* object)
2117 {
2118 if (!m_imageBitmapContents)
2119 return false;
2120 if (index >= m_imageBitmaps.size())
2121 return false;
2122 v8::Local<v8::Value> result = m_imageBitmaps.at(index);
2123 if (result.IsEmpty()) {
2124 RefPtrWillBeRawPtr<ImageBitmap> bitmap = ImageBitmap::create(m_imageBitm apContents->at(index).get());
2125 v8::Isolate* isolate = m_reader.scriptState()->isolate();
2126 v8::Local<v8::Object> creationContext = m_reader.scriptState()->context( )->Global();
2127 result = toV8(bitmap.get(), creationContext, isolate);
2128 if (result.IsEmpty())
2129 return false;
2130 m_imageBitmaps[index] = result;
2131 }
2132 *object = result;
2133 return true;
2134 }
2135
2068 bool ScriptValueDeserializer::tryGetTransferredSharedArrayBuffer(uint32_t index, v8::Local<v8::Value>* object) 2136 bool ScriptValueDeserializer::tryGetTransferredSharedArrayBuffer(uint32_t index, v8::Local<v8::Value>* object)
2069 { 2137 {
2070 ASSERT(RuntimeEnabledFeatures::sharedArrayBufferEnabled()); 2138 ASSERT(RuntimeEnabledFeatures::sharedArrayBufferEnabled());
2071 if (!m_arrayBufferContents) 2139 if (!m_arrayBufferContents)
2072 return false; 2140 return false;
2073 if (index >= m_arrayBuffers.size()) 2141 if (index >= m_arrayBuffers.size())
2074 return false; 2142 return false;
2075 v8::Local<v8::Value> result = m_arrayBuffers.at(index); 2143 v8::Local<v8::Value> result = m_arrayBuffers.at(index);
2076 if (result.IsEmpty()) { 2144 if (result.IsEmpty()) {
2077 RefPtr<DOMSharedArrayBuffer> buffer = DOMSharedArrayBuffer::create(m_arr ayBufferContents->at(index)); 2145 RefPtr<DOMSharedArrayBuffer> buffer = DOMSharedArrayBuffer::create(m_arr ayBufferContents->at(index));
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
2157 return false; 2225 return false;
2158 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe renceStack.size() - 1]; 2226 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe renceStack.size() - 1];
2159 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1); 2227 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1);
2160 if (objectReference >= m_objectPool.size()) 2228 if (objectReference >= m_objectPool.size())
2161 return false; 2229 return false;
2162 *object = m_objectPool[objectReference]; 2230 *object = m_objectPool[objectReference];
2163 return true; 2231 return true;
2164 } 2232 }
2165 2233
2166 } // namespace blink 2234 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698