OLD | NEW |
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/V8ImageData.h" | 14 #include "bindings/core/v8/V8ImageData.h" |
15 #include "bindings/core/v8/V8MessagePort.h" | 15 #include "bindings/core/v8/V8MessagePort.h" |
| 16 #include "bindings/core/v8/V8SharedArrayBuffer.h" |
16 #include "core/dom/CompositorProxy.h" | 17 #include "core/dom/CompositorProxy.h" |
17 #include "core/dom/DOMDataView.h" | 18 #include "core/dom/DOMDataView.h" |
| 19 #include "core/dom/DOMSharedArrayBuffer.h" |
| 20 #include "core/dom/DOMTypedArray.h" |
18 #include "core/fileapi/Blob.h" | 21 #include "core/fileapi/Blob.h" |
19 #include "core/fileapi/File.h" | 22 #include "core/fileapi/File.h" |
20 #include "core/fileapi/FileList.h" | 23 #include "core/fileapi/FileList.h" |
| 24 #include "platform/RuntimeEnabledFeatures.h" |
21 #include "public/platform/Platform.h" | 25 #include "public/platform/Platform.h" |
22 #include "public/platform/WebBlobInfo.h" | 26 #include "public/platform/WebBlobInfo.h" |
23 #include "wtf/DateMath.h" | 27 #include "wtf/DateMath.h" |
24 #include "wtf/text/StringHash.h" | 28 #include "wtf/text/StringHash.h" |
25 #include "wtf/text/StringUTF8Adaptor.h" | 29 #include "wtf/text/StringUTF8Adaptor.h" |
| 30 #include <stdio.h> |
26 | 31 |
27 // FIXME: consider crashing in debug mode on deserialization errors | 32 // FIXME: consider crashing in debug mode on deserialization errors |
28 // NOTE: be sure to change wireFormatVersion as necessary! | 33 // NOTE: be sure to change wireFormatVersion as necessary! |
29 | 34 |
30 namespace blink { | 35 namespace blink { |
31 | 36 |
32 // This code implements the HTML5 Structured Clone algorithm: | 37 // This code implements the HTML5 Structured Clone algorithm: |
33 // http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#safe-pa
ssing-of-structured-data | 38 // http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#safe-pa
ssing-of-structured-data |
34 | 39 |
35 // ZigZag encoding helps VarInt encoding stay small for negative | 40 // ZigZag encoding helps VarInt encoding stay small for negative |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 void SerializedScriptValueWriter::writeArrayBuffer(const DOMArrayBuffer& arrayBu
ffer) | 245 void SerializedScriptValueWriter::writeArrayBuffer(const DOMArrayBuffer& arrayBu
ffer) |
241 { | 246 { |
242 append(ArrayBufferTag); | 247 append(ArrayBufferTag); |
243 doWriteArrayBuffer(arrayBuffer); | 248 doWriteArrayBuffer(arrayBuffer); |
244 } | 249 } |
245 | 250 |
246 void SerializedScriptValueWriter::writeArrayBufferView(const DOMArrayBufferView&
arrayBufferView) | 251 void SerializedScriptValueWriter::writeArrayBufferView(const DOMArrayBufferView&
arrayBufferView) |
247 { | 252 { |
248 append(ArrayBufferViewTag); | 253 append(ArrayBufferViewTag); |
249 #if ENABLE(ASSERT) | 254 #if ENABLE(ASSERT) |
250 const DOMArrayBuffer& arrayBuffer = *arrayBufferView.buffer(); | 255 ASSERT(static_cast<const uint8_t*>(arrayBufferView.bufferBase()->data()) + a
rrayBufferView.byteOffset() == |
251 ASSERT(static_cast<const uint8_t*>(arrayBuffer.data()) + arrayBufferView.byt
eOffset() == | |
252 static_cast<const uint8_t*>(arrayBufferView.baseAddress())); | 256 static_cast<const uint8_t*>(arrayBufferView.baseAddress())); |
253 #endif | 257 #endif |
254 DOMArrayBufferView::ViewType type = arrayBufferView.type(); | 258 DOMArrayBufferView::ViewType type = arrayBufferView.type(); |
255 | 259 |
256 switch (type) { | 260 switch (type) { |
257 case DOMArrayBufferView::TypeInt8: | 261 case DOMArrayBufferView::TypeInt8: |
258 append(ByteArrayTag); | 262 append(ByteArrayTag); |
259 break; | 263 break; |
260 case DOMArrayBufferView::TypeUint8Clamped: | 264 case DOMArrayBufferView::TypeUint8Clamped: |
261 append(UnsignedByteClampedArrayTag); | 265 append(UnsignedByteClampedArrayTag); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 append(MessagePortTag); | 317 append(MessagePortTag); |
314 doWriteUint32(index); | 318 doWriteUint32(index); |
315 } | 319 } |
316 | 320 |
317 void SerializedScriptValueWriter::writeTransferredArrayBuffer(uint32_t index) | 321 void SerializedScriptValueWriter::writeTransferredArrayBuffer(uint32_t index) |
318 { | 322 { |
319 append(ArrayBufferTransferTag); | 323 append(ArrayBufferTransferTag); |
320 doWriteUint32(index); | 324 doWriteUint32(index); |
321 } | 325 } |
322 | 326 |
| 327 void SerializedScriptValueWriter::writeTransferredSharedArrayBuffer(uint32_t ind
ex) |
| 328 { |
| 329 ASSERT(RuntimeEnabledFeatures::sharedArrayBufferEnabled()); |
| 330 append(SharedArrayBufferTransferTag); |
| 331 doWriteUint32(index); |
| 332 } |
| 333 |
323 void SerializedScriptValueWriter::writeObjectReference(uint32_t reference) | 334 void SerializedScriptValueWriter::writeObjectReference(uint32_t reference) |
324 { | 335 { |
325 append(ObjectReferenceTag); | 336 append(ObjectReferenceTag); |
326 doWriteUint32(reference); | 337 doWriteUint32(reference); |
327 } | 338 } |
328 | 339 |
329 void SerializedScriptValueWriter::writeObject(uint32_t numProperties) | 340 void SerializedScriptValueWriter::writeObject(uint32_t numProperties) |
330 { | 341 { |
331 append(ObjectTag); | 342 append(ObjectTag); |
332 doWriteUint32(numProperties); | 343 doWriteUint32(numProperties); |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 { | 604 { |
594 if (!impl) | 605 if (!impl) |
595 return v8::Local<v8::ArrayBuffer>(); | 606 return v8::Local<v8::ArrayBuffer>(); |
596 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate); | 607 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate); |
597 if (wrapper.IsEmpty()) | 608 if (wrapper.IsEmpty()) |
598 return v8::Local<v8::ArrayBuffer>(); | 609 return v8::Local<v8::ArrayBuffer>(); |
599 ASSERT(wrapper->IsArrayBuffer()); | 610 ASSERT(wrapper->IsArrayBuffer()); |
600 return wrapper.As<v8::ArrayBuffer>(); | 611 return wrapper.As<v8::ArrayBuffer>(); |
601 } | 612 } |
602 | 613 |
| 614 static v8::Local<v8::SharedArrayBuffer> toV8Object(DOMSharedArrayBuffer* impl, v
8::Local<v8::Object> creationContext, v8::Isolate* isolate) |
| 615 { |
| 616 ASSERT(RuntimeEnabledFeatures::sharedArrayBufferEnabled()); |
| 617 if (!impl) |
| 618 return v8::Local<v8::SharedArrayBuffer>(); |
| 619 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate); |
| 620 ASSERT(wrapper->IsSharedArrayBuffer()); |
| 621 return wrapper.As<v8::SharedArrayBuffer>(); |
| 622 } |
| 623 |
603 // Returns true if the provided object is to be considered a 'host object', as u
sed in the | 624 // Returns true if the provided object is to be considered a 'host object', as u
sed in the |
604 // HTML5 structured clone algorithm. | 625 // HTML5 structured clone algorithm. |
605 static bool isHostObject(v8::Local<v8::Object> object) | 626 static bool isHostObject(v8::Local<v8::Object> object) |
606 { | 627 { |
607 // If the object has any internal fields, then we won't be able to serialize
or deserialize | 628 // If the object has any internal fields, then we won't be able to serialize
or deserialize |
608 // them; conveniently, this is also a quick way to detect DOM wrapper object
s, because | 629 // them; conveniently, this is also a quick way to detect DOM wrapper object
s, because |
609 // the mechanism for these relies on data stored in these fields. We should | 630 // the mechanism for these relies on data stored in these fields. We should |
610 // catch external array data as a special case. | 631 // catch external array data as a special case. |
611 return object->InternalFieldCount(); | 632 return object->InternalFieldCount(); |
612 } | 633 } |
613 | 634 |
614 ScriptValueSerializer::ScriptValueSerializer(SerializedScriptValueWriter& writer
, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, WebBlobInfoArr
ay* blobInfo, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, Script
State* scriptState) | 635 ScriptValueSerializer::ScriptValueSerializer(SerializedScriptValueWriter& writer
, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, SharedArrayBuf
ferArray* sharedArrayBuffers, WebBlobInfoArray* blobInfo, BlobDataHandleMap& blo
bDataHandles, v8::TryCatch& tryCatch, ScriptState* scriptState) |
615 : m_scriptState(scriptState) | 636 : m_scriptState(scriptState) |
616 , m_writer(writer) | 637 , m_writer(writer) |
617 , m_tryCatch(tryCatch) | 638 , m_tryCatch(tryCatch) |
618 , m_depth(0) | 639 , m_depth(0) |
619 , m_status(Success) | 640 , m_status(Success) |
620 , m_nextObjectReference(0) | 641 , m_nextObjectReference(0) |
621 , m_blobInfo(blobInfo) | 642 , m_blobInfo(blobInfo) |
622 , m_blobDataHandles(blobDataHandles) | 643 , m_blobDataHandles(blobDataHandles) |
623 { | 644 { |
624 ASSERT(!tryCatch.HasCaught()); | 645 ASSERT(!tryCatch.HasCaught()); |
625 v8::Local<v8::Object> creationContext = m_scriptState->context()->Global(); | 646 v8::Local<v8::Object> creationContext = m_scriptState->context()->Global(); |
626 if (messagePorts) { | 647 if (messagePorts) { |
627 for (size_t i = 0; i < messagePorts->size(); i++) | 648 for (size_t i = 0; i < messagePorts->size(); i++) |
628 m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get(),
creationContext, isolate()), i); | 649 m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get(),
creationContext, isolate()), i); |
629 } | 650 } |
630 if (arrayBuffers) { | 651 if (arrayBuffers) { |
631 for (size_t i = 0; i < arrayBuffers->size(); i++) { | 652 for (size_t i = 0; i < arrayBuffers->size(); i++) { |
632 v8::Local<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->at(i)
.get(), creationContext, isolate()); | 653 v8::Local<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->at(i)
.get(), creationContext, isolate()); |
633 // Coalesce multiple occurences of the same buffer to the first inde
x. | 654 // Coalesce multiple occurences of the same buffer to the first inde
x. |
634 if (!m_transferredArrayBuffers.contains(v8ArrayBuffer)) | 655 if (!m_transferredArrayBuffers.contains(v8ArrayBuffer)) |
635 m_transferredArrayBuffers.set(v8ArrayBuffer, i); | 656 m_transferredArrayBuffers.set(v8ArrayBuffer, i); |
636 } | 657 } |
637 } | 658 } |
| 659 if (sharedArrayBuffers) { |
| 660 ASSERT(sharedArrayBuffers->size() == 0 || RuntimeEnabledFeatures::shared
ArrayBufferEnabled()); |
| 661 for (size_t i = 0; i < sharedArrayBuffers->size(); i++) { |
| 662 v8::Local<v8::Object> v8SharedArrayBuffer = toV8Object(sharedArrayBu
ffers->at(i).get(), creationContext, isolate()); |
| 663 // Coalesce multiple occurences of the same buffer to the first inde
x. |
| 664 if (!m_transferredSharedArrayBuffers.contains(v8SharedArrayBuffer)) |
| 665 m_transferredSharedArrayBuffers.set(v8SharedArrayBuffer, i); |
| 666 } |
| 667 } |
638 } | 668 } |
639 | 669 |
640 ScriptValueSerializer::Status ScriptValueSerializer::serialize(v8::Local<v8::Val
ue> value) | 670 ScriptValueSerializer::Status ScriptValueSerializer::serialize(v8::Local<v8::Val
ue> value) |
641 { | 671 { |
642 v8::HandleScope scope(isolate()); | 672 v8::HandleScope scope(isolate()); |
643 m_writer.writeVersion(); | 673 m_writer.writeVersion(); |
644 StateBase* state = doSerialize(value, 0); | 674 StateBase* state = doSerialize(value, 0); |
645 while (state) | 675 while (state) |
646 state = state->advance(*this); | 676 state = state->advance(*this); |
647 return m_status; | 677 return m_status; |
(...skipping 11 matching lines...) Expand all Loading... |
659 m_writer.writeObjectReference(objectReference); | 689 m_writer.writeObjectReference(objectReference); |
660 } else { | 690 } else { |
661 return doSerializeValue(value, next); | 691 return doSerializeValue(value, next); |
662 } | 692 } |
663 return 0; | 693 return 0; |
664 } | 694 } |
665 | 695 |
666 ScriptValueSerializer::StateBase* ScriptValueSerializer::doSerializeValue(v8::Lo
cal<v8::Value> value, ScriptValueSerializer::StateBase* next) | 696 ScriptValueSerializer::StateBase* ScriptValueSerializer::doSerializeValue(v8::Lo
cal<v8::Value> value, ScriptValueSerializer::StateBase* next) |
667 { | 697 { |
668 uint32_t arrayBufferIndex; | 698 uint32_t arrayBufferIndex; |
| 699 uint32_t sharedArrayBufferIndex; |
669 if (value.IsEmpty()) | 700 if (value.IsEmpty()) |
670 return handleError(InputError, "The empty property name cannot be cloned
.", next); | 701 return handleError(InputError, "The empty property name cannot be cloned
.", next); |
671 if (value->IsUndefined()) { | 702 if (value->IsUndefined()) { |
672 m_writer.writeUndefined(); | 703 m_writer.writeUndefined(); |
673 } else if (value->IsNull()) { | 704 } else if (value->IsNull()) { |
674 m_writer.writeNull(); | 705 m_writer.writeNull(); |
675 } else if (value->IsTrue()) { | 706 } else if (value->IsTrue()) { |
676 m_writer.writeTrue(); | 707 m_writer.writeTrue(); |
677 } else if (value->IsFalse()) { | 708 } else if (value->IsFalse()) { |
678 m_writer.writeFalse(); | 709 m_writer.writeFalse(); |
679 } else if (value->IsInt32()) { | 710 } else if (value->IsInt32()) { |
680 m_writer.writeInt32(value.As<v8::Int32>()->Value()); | 711 m_writer.writeInt32(value.As<v8::Int32>()->Value()); |
681 } else if (value->IsUint32()) { | 712 } else if (value->IsUint32()) { |
682 m_writer.writeUint32(value.As<v8::Uint32>()->Value()); | 713 m_writer.writeUint32(value.As<v8::Uint32>()->Value()); |
683 } else if (value->IsNumber()) { | 714 } else if (value->IsNumber()) { |
684 m_writer.writeNumber(value.As<v8::Number>()->Value()); | 715 m_writer.writeNumber(value.As<v8::Number>()->Value()); |
685 } else if (V8ArrayBufferView::hasInstance(value, isolate())) { | 716 } else if (V8ArrayBufferView::hasInstance(value, isolate())) { |
686 return writeAndGreyArrayBufferView(value.As<v8::Object>(), next); | 717 return writeAndGreyArrayBufferView(value.As<v8::Object>(), next); |
687 } else if (value->IsString()) { | 718 } else if (value->IsString()) { |
688 writeString(value); | 719 writeString(value); |
689 } else if (V8MessagePort::hasInstance(value, isolate())) { | 720 } else if (V8MessagePort::hasInstance(value, isolate())) { |
690 uint32_t messagePortIndex; | 721 uint32_t messagePortIndex; |
691 if (m_transferredMessagePorts.tryGet(value.As<v8::Object>(), &messagePor
tIndex)) { | 722 if (m_transferredMessagePorts.tryGet(value.As<v8::Object>(), &messagePor
tIndex)) { |
692 m_writer.writeTransferredMessagePort(messagePortIndex); | 723 m_writer.writeTransferredMessagePort(messagePortIndex); |
693 } else { | 724 } else { |
694 return handleError(DataCloneError, "A MessagePort could not be clone
d.", next); | 725 return handleError(DataCloneError, "A MessagePort could not be clone
d.", next); |
695 } | 726 } |
696 } else if (V8ArrayBuffer::hasInstance(value, isolate()) && m_transferredArra
yBuffers.tryGet(value.As<v8::Object>(), &arrayBufferIndex)) { | 727 } else if (V8ArrayBuffer::hasInstance(value, isolate()) && m_transferredArra
yBuffers.tryGet(value.As<v8::Object>(), &arrayBufferIndex)) { |
697 return writeTransferredArrayBuffer(value, arrayBufferIndex, next); | 728 return writeTransferredArrayBuffer(value, arrayBufferIndex, next); |
| 729 } else if (V8SharedArrayBuffer::hasInstance(value, isolate()) && m_transferr
edSharedArrayBuffers.tryGet(value.As<v8::Object>(), &sharedArrayBufferIndex)) { |
| 730 return writeTransferredSharedArrayBuffer(value, sharedArrayBufferIndex,
next); |
698 } else { | 731 } else { |
699 v8::Local<v8::Object> jsObject = value.As<v8::Object>(); | 732 v8::Local<v8::Object> jsObject = value.As<v8::Object>(); |
700 if (jsObject.IsEmpty()) | 733 if (jsObject.IsEmpty()) |
701 return handleError(DataCloneError, "An object could not be cloned.",
next); | 734 return handleError(DataCloneError, "An object could not be cloned.",
next); |
702 greyObject(jsObject); | 735 greyObject(jsObject); |
703 if (value->IsDate()) { | 736 if (value->IsDate()) { |
704 m_writer.writeDate(value.As<v8::Date>()->ValueOf()); | 737 m_writer.writeDate(value.As<v8::Date>()->ValueOf()); |
705 } else if (value->IsStringObject()) { | 738 } else if (value->IsStringObject()) { |
706 writeStringObject(value); | 739 writeStringObject(value); |
707 } else if (value->IsNumberObject()) { | 740 } else if (value->IsNumberObject()) { |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
904 v8::Local<v8::RegExp> regExp = value.As<v8::RegExp>(); | 937 v8::Local<v8::RegExp> regExp = value.As<v8::RegExp>(); |
905 m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags()); | 938 m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags()); |
906 } | 939 } |
907 | 940 |
908 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeAndGreyArrayBuffer
View(v8::Local<v8::Object> object, ScriptValueSerializer::StateBase* next) | 941 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeAndGreyArrayBuffer
View(v8::Local<v8::Object> object, ScriptValueSerializer::StateBase* next) |
909 { | 942 { |
910 ASSERT(!object.IsEmpty()); | 943 ASSERT(!object.IsEmpty()); |
911 DOMArrayBufferView* arrayBufferView = V8ArrayBufferView::toImpl(object); | 944 DOMArrayBufferView* arrayBufferView = V8ArrayBufferView::toImpl(object); |
912 if (!arrayBufferView) | 945 if (!arrayBufferView) |
913 return 0; | 946 return 0; |
914 if (!arrayBufferView->buffer()) | 947 v8::Local<v8::Value> underlyingBuffer; |
915 return handleError(DataCloneError, "An ArrayBuffer could not be cloned."
, next); | 948 if (arrayBufferView->isShared()) { |
916 v8::Local<v8::Value> underlyingBuffer = toV8(arrayBufferView->buffer(), m_sc
riptState->context()->Global(), isolate()); | 949 if (!arrayBufferView->bufferShared()) |
| 950 return handleError(DataCloneError, "A SharedArrayBuffer could not be
cloned.", next); |
| 951 underlyingBuffer = toV8(arrayBufferView->bufferShared(), m_scriptState->
context()->Global(), isolate()); |
| 952 } else { |
| 953 if (!arrayBufferView->buffer()) |
| 954 return handleError(DataCloneError, "An ArrayBuffer could not be clon
ed.", next); |
| 955 underlyingBuffer = toV8(arrayBufferView->buffer(), m_scriptState->contex
t()->Global(), isolate()); |
| 956 } |
917 if (underlyingBuffer.IsEmpty()) | 957 if (underlyingBuffer.IsEmpty()) |
918 return handleError(DataCloneError, "An ArrayBuffer could not be cloned."
, next); | 958 return handleError(DataCloneError, "An ArrayBuffer could not be cloned."
, next); |
919 StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next); | 959 StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next); |
920 if (stateOut) | 960 if (stateOut) |
921 return stateOut; | 961 return stateOut; |
922 m_writer.writeArrayBufferView(*arrayBufferView); | 962 m_writer.writeArrayBufferView(*arrayBufferView); |
923 // This should be safe: we serialize something that we know to be a wrapper
(see | 963 // This should be safe: we serialize something that we know to be a wrapper
(see |
924 // the toV8 call above), so the call to doSerializeArrayBuffer should neithe
r | 964 // the toV8 call above), so the call to doSerializeArrayBuffer should neithe
r |
925 // cause the system stack to overflow nor should it have potential to reach | 965 // cause the system stack to overflow nor should it have potential to reach |
926 // this ArrayBufferView again. | 966 // this ArrayBufferView again. |
(...skipping 23 matching lines...) Expand all Loading... |
950 { | 990 { |
951 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(value.As<v8::Object>()); | 991 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(value.As<v8::Object>()); |
952 if (!arrayBuffer) | 992 if (!arrayBuffer) |
953 return 0; | 993 return 0; |
954 if (arrayBuffer->isNeutered()) | 994 if (arrayBuffer->isNeutered()) |
955 return handleError(DataCloneError, "An ArrayBuffer is neutered and could
not be cloned.", next); | 995 return handleError(DataCloneError, "An ArrayBuffer is neutered and could
not be cloned.", next); |
956 m_writer.writeTransferredArrayBuffer(index); | 996 m_writer.writeTransferredArrayBuffer(index); |
957 return 0; | 997 return 0; |
958 } | 998 } |
959 | 999 |
| 1000 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeTransferredSharedA
rrayBuffer(v8::Local<v8::Value> value, uint32_t index, ScriptValueSerializer::St
ateBase* next) |
| 1001 { |
| 1002 ASSERT(RuntimeEnabledFeatures::sharedArrayBufferEnabled()); |
| 1003 DOMSharedArrayBuffer* sharedArrayBuffer = V8SharedArrayBuffer::toImpl(value.
As<v8::Object>()); |
| 1004 if (!sharedArrayBuffer) |
| 1005 return 0; |
| 1006 m_writer.writeTransferredSharedArrayBuffer(index); |
| 1007 return 0; |
| 1008 } |
| 1009 |
960 bool ScriptValueSerializer::shouldSerializeDensely(uint32_t length, uint32_t pro
pertyCount) | 1010 bool ScriptValueSerializer::shouldSerializeDensely(uint32_t length, uint32_t pro
pertyCount) |
961 { | 1011 { |
962 // Let K be the cost of serializing all property values that are there | 1012 // Let K be the cost of serializing all property values that are there |
963 // Cost of serializing sparsely: 5*propertyCount + K (5 bytes per uint32_t k
ey) | 1013 // Cost of serializing sparsely: 5*propertyCount + K (5 bytes per uint32_t k
ey) |
964 // Cost of serializing densely: K + 1*(length - propertyCount) (1 byte for a
ll properties that are not there) | 1014 // Cost of serializing densely: K + 1*(length - propertyCount) (1 byte for a
ll properties that are not there) |
965 // so densely is better than sparsly whenever 6*propertyCount > length | 1015 // so densely is better than sparsly whenever 6*propertyCount > length |
966 return 6 * propertyCount >= length; | 1016 return 6 * propertyCount >= length; |
967 } | 1017 } |
968 | 1018 |
969 ScriptValueSerializer::StateBase* ScriptValueSerializer::startArrayState(v8::Loc
al<v8::Array> array, ScriptValueSerializer::StateBase* next) | 1019 ScriptValueSerializer::StateBase* ScriptValueSerializer::startArrayState(v8::Loc
al<v8::Array> array, ScriptValueSerializer::StateBase* next) |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1226 case ArrayBufferTransferTag: { | 1276 case ArrayBufferTransferTag: { |
1227 if (!m_version) | 1277 if (!m_version) |
1228 return false; | 1278 return false; |
1229 uint32_t index; | 1279 uint32_t index; |
1230 if (!doReadUint32(&index)) | 1280 if (!doReadUint32(&index)) |
1231 return false; | 1281 return false; |
1232 if (!creator.tryGetTransferredArrayBuffer(index, value)) | 1282 if (!creator.tryGetTransferredArrayBuffer(index, value)) |
1233 return false; | 1283 return false; |
1234 break; | 1284 break; |
1235 } | 1285 } |
| 1286 case SharedArrayBufferTransferTag: { |
| 1287 if (!m_version) |
| 1288 return false; |
| 1289 uint32_t index; |
| 1290 if (!doReadUint32(&index)) |
| 1291 return false; |
| 1292 if (!creator.tryGetTransferredSharedArrayBuffer(index, value)) |
| 1293 return false; |
| 1294 break; |
| 1295 } |
1236 case ObjectReferenceTag: { | 1296 case ObjectReferenceTag: { |
1237 if (!m_version) | 1297 if (!m_version) |
1238 return false; | 1298 return false; |
1239 uint32_t reference; | 1299 uint32_t reference; |
1240 if (!doReadUint32(&reference)) | 1300 if (!doReadUint32(&reference)) |
1241 return false; | 1301 return false; |
1242 if (!creator.tryGetObjectFromObjectReference(reference, value)) | 1302 if (!creator.tryGetObjectFromObjectReference(reference, value)) |
1243 return false; | 1303 return false; |
1244 break; | 1304 break; |
1245 } | 1305 } |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1447 return false; | 1507 return false; |
1448 *value = toV8(arrayBuffer.release(), m_scriptState->context()->Global(), iso
late()); | 1508 *value = toV8(arrayBuffer.release(), m_scriptState->context()->Global(), iso
late()); |
1449 return !value->IsEmpty(); | 1509 return !value->IsEmpty(); |
1450 } | 1510 } |
1451 | 1511 |
1452 bool SerializedScriptValueReader::readArrayBufferView(v8::Local<v8::Value>* valu
e, ScriptValueCompositeCreator& creator) | 1512 bool SerializedScriptValueReader::readArrayBufferView(v8::Local<v8::Value>* valu
e, ScriptValueCompositeCreator& creator) |
1453 { | 1513 { |
1454 ArrayBufferViewSubTag subTag; | 1514 ArrayBufferViewSubTag subTag; |
1455 uint32_t byteOffset; | 1515 uint32_t byteOffset; |
1456 uint32_t byteLength; | 1516 uint32_t byteLength; |
1457 RefPtr<DOMArrayBuffer> arrayBuffer; | 1517 RefPtr<DOMArrayBufferBase> arrayBuffer; |
1458 v8::Local<v8::Value> arrayBufferV8Value; | 1518 v8::Local<v8::Value> arrayBufferV8Value; |
1459 if (!readArrayBufferViewSubTag(&subTag)) | 1519 if (!readArrayBufferViewSubTag(&subTag)) |
1460 return false; | 1520 return false; |
1461 if (!doReadUint32(&byteOffset)) | 1521 if (!doReadUint32(&byteOffset)) |
1462 return false; | 1522 return false; |
1463 if (!doReadUint32(&byteLength)) | 1523 if (!doReadUint32(&byteLength)) |
1464 return false; | 1524 return false; |
1465 if (!creator.consumeTopOfStack(&arrayBufferV8Value)) | 1525 if (!creator.consumeTopOfStack(&arrayBufferV8Value)) |
1466 return false; | 1526 return false; |
1467 if (arrayBufferV8Value.IsEmpty()) | 1527 if (arrayBufferV8Value.IsEmpty()) |
1468 return false; | 1528 return false; |
1469 arrayBuffer = V8ArrayBuffer::toImpl(arrayBufferV8Value.As<v8::Object>()); | 1529 if (arrayBufferV8Value->IsArrayBuffer()) { |
1470 if (!arrayBuffer) | 1530 arrayBuffer = V8ArrayBuffer::toImpl(arrayBufferV8Value.As<v8::Object>())
; |
1471 return false; | 1531 if (!arrayBuffer) |
| 1532 return false; |
| 1533 } else if (arrayBufferV8Value->IsSharedArrayBuffer()) { |
| 1534 arrayBuffer = V8SharedArrayBuffer::toImpl(arrayBufferV8Value.As<v8::Obje
ct>()); |
| 1535 if (!arrayBuffer) |
| 1536 return false; |
| 1537 } else { |
| 1538 ASSERT_NOT_REACHED(); |
| 1539 } |
1472 | 1540 |
1473 // Check the offset, length and alignment. | 1541 // Check the offset, length and alignment. |
1474 int elementByteSize; | 1542 int elementByteSize; |
1475 switch (subTag) { | 1543 switch (subTag) { |
1476 case ByteArrayTag: | 1544 case ByteArrayTag: |
1477 elementByteSize = sizeof(DOMInt8Array::ValueType); | 1545 elementByteSize = sizeof(DOMInt8Array::ValueType); |
1478 break; | 1546 break; |
1479 case UnsignedByteArrayTag: | 1547 case UnsignedByteArrayTag: |
1480 elementByteSize = sizeof(DOMUint8Array::ValueType); | 1548 elementByteSize = sizeof(DOMUint8Array::ValueType); |
1481 break; | 1549 break; |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1868 v8::Local<v8::Object> creationContext = m_reader.scriptState()->context(
)->Global(); | 1936 v8::Local<v8::Object> creationContext = m_reader.scriptState()->context(
)->Global(); |
1869 result = toV8(buffer.get(), creationContext, isolate); | 1937 result = toV8(buffer.get(), creationContext, isolate); |
1870 if (result.IsEmpty()) | 1938 if (result.IsEmpty()) |
1871 return false; | 1939 return false; |
1872 m_arrayBuffers[index] = result; | 1940 m_arrayBuffers[index] = result; |
1873 } | 1941 } |
1874 *object = result; | 1942 *object = result; |
1875 return true; | 1943 return true; |
1876 } | 1944 } |
1877 | 1945 |
| 1946 bool ScriptValueDeserializer::tryGetTransferredSharedArrayBuffer(uint32_t index,
v8::Local<v8::Value>* object) |
| 1947 { |
| 1948 ASSERT(RuntimeEnabledFeatures::sharedArrayBufferEnabled()); |
| 1949 if (!m_arrayBufferContents) |
| 1950 return false; |
| 1951 if (index >= m_arrayBuffers.size()) |
| 1952 return false; |
| 1953 v8::Local<v8::Value> result = m_arrayBuffers.at(index); |
| 1954 if (result.IsEmpty()) { |
| 1955 RefPtr<DOMSharedArrayBuffer> buffer = DOMSharedArrayBuffer::create(m_arr
ayBufferContents->at(index)); |
| 1956 v8::Isolate* isolate = m_reader.scriptState()->isolate(); |
| 1957 v8::Local<v8::Object> creationContext = m_reader.scriptState()->context(
)->Global(); |
| 1958 result = toV8(buffer.get(), creationContext, isolate); |
| 1959 m_arrayBuffers[index] = result; |
| 1960 } |
| 1961 *object = result; |
| 1962 return true; |
| 1963 } |
| 1964 |
1878 bool ScriptValueDeserializer::tryGetObjectFromObjectReference(uint32_t reference
, v8::Local<v8::Value>* object) | 1965 bool ScriptValueDeserializer::tryGetObjectFromObjectReference(uint32_t reference
, v8::Local<v8::Value>* object) |
1879 { | 1966 { |
1880 if (reference >= m_objectPool.size()) | 1967 if (reference >= m_objectPool.size()) |
1881 return false; | 1968 return false; |
1882 *object = m_objectPool[reference]; | 1969 *object = m_objectPool[reference]; |
1883 return object; | 1970 return object; |
1884 } | 1971 } |
1885 | 1972 |
1886 uint32_t ScriptValueDeserializer::objectReferenceCount() | 1973 uint32_t ScriptValueDeserializer::objectReferenceCount() |
1887 { | 1974 { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1940 return false; | 2027 return false; |
1941 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe
renceStack.size() - 1]; | 2028 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe
renceStack.size() - 1]; |
1942 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() -
1); | 2029 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() -
1); |
1943 if (objectReference >= m_objectPool.size()) | 2030 if (objectReference >= m_objectPool.size()) |
1944 return false; | 2031 return false; |
1945 *object = m_objectPool[objectReference]; | 2032 *object = m_objectPool[objectReference]; |
1946 return true; | 2033 return true; |
1947 } | 2034 } |
1948 | 2035 |
1949 } // namespace blink | 2036 } // namespace blink |
OLD | NEW |