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

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

Issue 2101953002: [Refactoring] Clean up code for serializing ScriptValues (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 months 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 "bindings/core/v8/ScriptValueSerializer.h" 5 #include "bindings/core/v8/ScriptValueSerializer.h"
6 6
7 #include "bindings/core/v8/Transferables.h" 7 #include "bindings/core/v8/Transferables.h"
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"
(...skipping 18 matching lines...) Expand all
29 #include "wtf/DateMath.h" 29 #include "wtf/DateMath.h"
30 #include "wtf/text/StringHash.h" 30 #include "wtf/text/StringHash.h"
31 #include "wtf/text/StringUTF8Adaptor.h" 31 #include "wtf/text/StringUTF8Adaptor.h"
32 #include <memory> 32 #include <memory>
33 33
34 // FIXME: consider crashing in debug mode on deserialization errors 34 // FIXME: consider crashing in debug mode on deserialization errors
35 // NOTE: be sure to change wireFormatVersion as necessary! 35 // NOTE: be sure to change wireFormatVersion as necessary!
36 36
37 namespace blink { 37 namespace blink {
38 38
39 namespace {
40
39 // This code implements the HTML5 Structured Clone algorithm: 41 // This code implements the HTML5 Structured Clone algorithm:
40 // http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#safe-pa ssing-of-structured-data 42 // http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#safe-pa ssing-of-structured-data
41 43
42 // ZigZag encoding helps VarInt encoding stay small for negative 44 // ZigZag encoding helps VarInt encoding stay small for negative
43 // numbers with small absolute values. 45 // numbers with small absolute values.
44 class ZigZag { 46 class ZigZag {
45 public: 47 public:
46 static uint32_t encode(uint32_t value) 48 static uint32_t encode(uint32_t value)
47 { 49 {
48 if (value & (1U << 31)) 50 if (value & (1U << 31))
49 value = ((~value) << 1) + 1; 51 value = ((~value) << 1) + 1;
50 else 52 else
51 value <<= 1; 53 value <<= 1;
52 return value; 54 return value;
53 } 55 }
54 56
55 static uint32_t decode(uint32_t value) 57 static uint32_t decode(uint32_t value)
56 { 58 {
57 if (value & 1) 59 if (value & 1)
58 value = ~(value >> 1); 60 value = ~(value >> 1);
59 else 61 else
60 value >>= 1; 62 value >>= 1;
61 return value; 63 return value;
62 } 64 }
63 65
64 private: 66 private:
65 ZigZag(); 67 ZigZag();
66 }; 68 };
67 69
68 static const int maxDepth = 20000; 70 const int maxDepth = 20000;
69 71
70 static bool shouldCheckForCycles(int depth) 72 bool shouldCheckForCycles(int depth)
71 { 73 {
72 ASSERT(depth >= 0); 74 ASSERT(depth >= 0);
73 // Since we are not required to spot the cycle as soon as it 75 // Since we are not required to spot the cycle as soon as it
74 // happens we can check for cycles only when the current depth 76 // happens we can check for cycles only when the current depth
75 // is a power of two. 77 // is a power of two.
76 return !(depth & (depth - 1)); 78 return !(depth & (depth - 1));
77 } 79 }
78 80
81 v8::Local<v8::Object> toV8Object(MessagePort* impl, v8::Local<v8::Object> creati onContext, v8::Isolate* isolate)
Yuki 2016/06/28 08:28:47 No need to address in this CL but just a suggestio
peria 2016/06/28 08:59:19 Thank you for pointing this out. I'll do it in ano
82 {
83 if (!impl)
84 return v8::Local<v8::Object>();
85 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate);
86 if (wrapper.IsEmpty())
87 return v8::Local<v8::Object>();
88 DCHECK(wrapper->IsObject());
89 return wrapper.As<v8::Object>();
90 }
91
92 v8::Local<v8::Object> toV8Object(ImageBitmap* impl, v8::Local<v8::Object> creati onContext, v8::Isolate* isolate)
93 {
94 if (!impl)
95 return v8::Local<v8::Object>();
96 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate);
97 if (wrapper.IsEmpty())
98 return v8::Local<v8::Object>();
99 return wrapper.As<v8::Object>();
100 }
101
102 v8::Local<v8::Object> toV8Object(OffscreenCanvas* impl, v8::Local<v8::Object> cr eationContext, v8::Isolate* isolate)
103 {
104 if (!impl)
105 return v8::Local<v8::Object>();
106 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate);
107 if (wrapper.IsEmpty())
108 return v8::Local<v8::Object>();
109 return wrapper.As<v8::Object>();
110 }
111
112 v8::Local<v8::Object> toV8Object(DOMArrayBufferBase* impl, v8::Local<v8::Object> creationContext, v8::Isolate* isolate)
113 {
114 if (!impl)
115 return v8::Local<v8::Object>();
116 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate);
117 if (wrapper.IsEmpty())
118 return v8::Local<v8::Object>();
119 return wrapper.As<v8::Object>();
120 }
121
122 // Returns true if the provided object is to be considered a 'host object', as u sed in the
123 // HTML5 structured clone algorithm.
124 bool isHostObject(v8::Local<v8::Object> object)
125 {
126 // If the object has any internal fields, then we won't be able to serialize or deserialize
127 // them; conveniently, this is also a quick way to detect DOM wrapper object s, because
128 // the mechanism for these relies on data stored in these fields. We should
129 // catch external array data as a special case.
130 return object->InternalFieldCount();
131 }
132
133 } // namespace
134
79 void SerializedScriptValueWriter::writeUndefined() 135 void SerializedScriptValueWriter::writeUndefined()
80 { 136 {
81 append(UndefinedTag); 137 append(UndefinedTag);
82 } 138 }
83 139
84 void SerializedScriptValueWriter::writeNull() 140 void SerializedScriptValueWriter::writeNull()
85 { 141 {
86 append(NullTag); 142 append(NullTag);
87 } 143 }
88 144
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 return serializer.handleError(Status::JSException, "Failed to get an element while cloning a collection.", this); 700 return serializer.handleError(Status::JSException, "Failed to get an element while cloning a collection.", this);
645 m_index++; 701 m_index++;
646 if (StateBase* newState = serializer.checkException(this)) 702 if (StateBase* newState = serializer.checkException(this))
647 return newState; 703 return newState;
648 if (StateBase* newState = serializer.doSerialize(value, this)) 704 if (StateBase* newState = serializer.doSerialize(value, this))
649 return newState; 705 return newState;
650 } 706 }
651 return serializer.writeCollection<T>(m_length, this); 707 return serializer.writeCollection<T>(m_length, this);
652 } 708 }
653 709
654 static v8::Local<v8::Object> toV8Object(MessagePort* impl, v8::Local<v8::Object> creationContext, v8::Isolate* isolate) 710 ScriptValueSerializer::ScriptValueSerializer(SerializedScriptValueWriter& writer , WebBlobInfoArray* blobInfo, ScriptState* scriptState)
655 {
656 if (!impl)
657 return v8::Local<v8::Object>();
658 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate);
659 if (wrapper.IsEmpty())
660 return v8::Local<v8::Object>();
661 ASSERT(wrapper->IsObject());
662 return wrapper.As<v8::Object>();
663 }
664
665 static v8::Local<v8::Object> toV8Object(ImageBitmap* impl, v8::Local<v8::Object> creationContext, v8::Isolate* isolate)
666 {
667 if (!impl)
668 return v8::Local<v8::Object>();
669 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate);
670 if (wrapper.IsEmpty())
671 return v8::Local<v8::Object>();
672 return wrapper.As<v8::Object>();
673 }
674
675 static v8::Local<v8::Object> toV8Object(OffscreenCanvas* impl, v8::Local<v8::Obj ect> creationContext, v8::Isolate* isolate)
676 {
677 if (!impl)
678 return v8::Local<v8::Object>();
679 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate);
680 if (wrapper.IsEmpty())
681 return v8::Local<v8::Object>();
682 return wrapper.As<v8::Object>();
683 }
684
685 static v8::Local<v8::Object> toV8Object(DOMArrayBufferBase* impl, v8::Local<v8:: Object> creationContext, v8::Isolate* isolate)
686 {
687 if (!impl)
688 return v8::Local<v8::Object>();
689 v8::Local<v8::Value> wrapper = toV8(impl, creationContext, isolate);
690 if (wrapper.IsEmpty())
691 return v8::Local<v8::Object>();
692 return wrapper.As<v8::Object>();
693 }
694
695 // Returns true if the provided object is to be considered a 'host object', as u sed in the
696 // HTML5 structured clone algorithm.
697 static bool isHostObject(v8::Local<v8::Object> object)
698 {
699 // If the object has any internal fields, then we won't be able to serialize or deserialize
700 // them; conveniently, this is also a quick way to detect DOM wrapper object s, because
701 // the mechanism for these relies on data stored in these fields. We should
702 // catch external array data as a special case.
703 return object->InternalFieldCount();
704 }
705
706 ScriptValueSerializer::ScriptValueSerializer(SerializedScriptValueWriter& writer , const Transferables* transferables, WebBlobInfoArray* blobInfo, ScriptState* s criptState)
707 : m_scriptState(scriptState) 711 : m_scriptState(scriptState)
708 , m_writer(writer) 712 , m_writer(writer)
709 , m_tryCatch(scriptState->isolate()) 713 , m_tryCatch(scriptState->isolate())
710 , m_depth(0) 714 , m_depth(0)
711 , m_status(Status::Success) 715 , m_status(Status::Success)
712 , m_nextObjectReference(0) 716 , m_nextObjectReference(0)
713 , m_blobInfo(blobInfo) 717 , m_blobInfo(blobInfo)
714 , m_blobDataHandles(nullptr) 718 , m_blobDataHandles(nullptr)
715 { 719 {
716 DCHECK(!m_tryCatch.HasCaught()); 720 DCHECK(!m_tryCatch.HasCaught());
717 if (transferables)
718 copyTransferables(*transferables);
719 } 721 }
720 722
721 void ScriptValueSerializer::copyTransferables(const Transferables& transferables ) 723 void ScriptValueSerializer::copyTransferables(const Transferables& transferables )
722 { 724 {
723 v8::Local<v8::Object> creationContext = m_scriptState->context()->Global(); 725 v8::Local<v8::Object> creationContext = m_scriptState->context()->Global();
724 726
725 // Also kept in separate ObjectPools, iterate and copy the contents 727 // Also kept in separate ObjectPools, iterate and copy the contents
726 // of each kind of transferable vector. 728 // of each kind of transferable vector.
727 729
728 const auto& messagePorts = transferables.messagePorts; 730 const auto& messagePorts = transferables.messagePorts;
(...skipping 20 matching lines...) Expand all
749 const auto& offscreenCanvases = transferables.offscreenCanvases; 751 const auto& offscreenCanvases = transferables.offscreenCanvases;
750 for (size_t i = 0; i < offscreenCanvases.size(); ++i) { 752 for (size_t i = 0; i < offscreenCanvases.size(); ++i) {
751 v8::Local<v8::Object> v8OffscreenCanvas = toV8Object(offscreenCanvases[i ].get(), creationContext, isolate()); 753 v8::Local<v8::Object> v8OffscreenCanvas = toV8Object(offscreenCanvases[i ].get(), creationContext, isolate());
752 if (!m_transferredOffscreenCanvas.contains(v8OffscreenCanvas)) 754 if (!m_transferredOffscreenCanvas.contains(v8OffscreenCanvas))
753 m_transferredOffscreenCanvas.set(v8OffscreenCanvas, i); 755 m_transferredOffscreenCanvas.set(v8OffscreenCanvas, i);
754 } 756 }
755 } 757 }
756 758
757 PassRefPtr<SerializedScriptValue> ScriptValueSerializer::serialize(v8::Local<v8: :Value> value, Transferables* transferables, ExceptionState& exceptionState) 759 PassRefPtr<SerializedScriptValue> ScriptValueSerializer::serialize(v8::Local<v8: :Value> value, Transferables* transferables, ExceptionState& exceptionState)
758 { 760 {
761 DCHECK(!m_blobDataHandles);
762
759 RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::creat e(); 763 RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::creat e();
764
760 m_blobDataHandles = &serializedValue->blobDataHandles(); 765 m_blobDataHandles = &serializedValue->blobDataHandles();
766 if (transferables)
767 copyTransferables(*transferables);
761 768
762 v8::HandleScope scope(isolate()); 769 v8::HandleScope scope(isolate());
763 writer().writeVersion(); 770 writer().writeVersion();
764 StateBase* state = doSerialize(value, nullptr); 771 StateBase* state = doSerialize(value, nullptr);
765 while (state) 772 while (state)
766 state = state->advance(*this); 773 state = state->advance(*this);
767 774
768 switch (m_status) { 775 switch (m_status) {
769 case Status::Success: 776 case Status::Success:
770 transferData(transferables, exceptionState, serializedValue.get()); 777 transferData(transferables, exceptionState, serializedValue.get());
771 break; 778 break;
772 case Status::InputError: 779 case Status::InputError:
773 case Status::DataCloneError: 780 case Status::DataCloneError:
774 exceptionState.throwDOMException(blink::DataCloneError, errorMessage()); 781 exceptionState.throwDOMException(blink::DataCloneError, m_errorMessage);
775 break; 782 break;
776 case Status::JSException: 783 case Status::JSException:
777 exceptionState.rethrowV8Exception(m_tryCatch.Exception()); 784 exceptionState.rethrowV8Exception(m_tryCatch.Exception());
778 break; 785 break;
779 default: 786 default:
780 NOTREACHED(); 787 NOTREACHED();
781 } 788 }
782 789
783 m_blobDataHandles = nullptr;
784
785 return serializedValue.release(); 790 return serializedValue.release();
786 } 791 }
787 792
788 void ScriptValueSerializer::transferData(Transferables* transferables, Exception State& exceptionState, SerializedScriptValue* serializedValue) 793 void ScriptValueSerializer::transferData(Transferables* transferables, Exception State& exceptionState, SerializedScriptValue* serializedValue)
789 { 794 {
790 serializedValue->setData(m_writer.takeWireString()); 795 serializedValue->setData(m_writer.takeWireString());
791 DCHECK(serializedValue->data().impl()->hasOneRef()); 796 DCHECK(serializedValue->data().impl()->hasOneRef());
792 if (!transferables) 797 if (!transferables)
793 return; 798 return;
794 799
(...skipping 15 matching lines...) Expand all
810 } 815 }
811 816
812 // static 817 // static
813 String ScriptValueSerializer::serializeNullValue() 818 String ScriptValueSerializer::serializeNullValue()
814 { 819 {
815 SerializedScriptValueWriter valueWriter; 820 SerializedScriptValueWriter valueWriter;
816 valueWriter.writeNull(); 821 valueWriter.writeNull();
817 return valueWriter.takeWireString(); 822 return valueWriter.takeWireString();
818 } 823 }
819 824
820 ScriptValueSerializer::StateBase* ScriptValueSerializer::doSerialize(v8::Local<v 8::Value> value, ScriptValueSerializer::StateBase* next) 825 ScriptValueSerializer::StateBase* ScriptValueSerializer::doSerialize(v8::Local<v 8::Value> value, StateBase* next)
821 { 826 {
822 m_writer.writeReferenceCount(m_nextObjectReference); 827 m_writer.writeReferenceCount(m_nextObjectReference);
823 828
824 if (value.IsEmpty()) 829 if (value.IsEmpty())
825 return handleError(Status::InputError, "The empty property cannot be clo ned.", next); 830 return handleError(Status::InputError, "The empty property cannot be clo ned.", next);
826 831
827 uint32_t objectReference; 832 uint32_t objectReference;
828 if ((value->IsObject() || value->IsDate() || value->IsRegExp()) 833 if ((value->IsObject() || value->IsDate() || value->IsRegExp())
829 && m_objectPool.tryGet(value.As<v8::Object>(), &objectReference)) { 834 && m_objectPool.tryGet(value.As<v8::Object>(), &objectReference)) {
830 // Note that IsObject() also detects wrappers (eg, it will catch the thi ngs 835 // Note that IsObject() also detects wrappers (eg, it will catch the thi ngs
(...skipping 20 matching lines...) Expand all
851 } else if (value->IsNumber()) { 856 } else if (value->IsNumber()) {
852 m_writer.writeNumber(value.As<v8::Number>()->Value()); 857 m_writer.writeNumber(value.As<v8::Number>()->Value());
853 } else if (value->IsString()) { 858 } else if (value->IsString()) {
854 writeString(value); 859 writeString(value);
855 } else { 860 } else {
856 return handleError(Status::DataCloneError, "A value could not be cloned. ", next); 861 return handleError(Status::DataCloneError, "A value could not be cloned. ", next);
857 } 862 }
858 return nullptr; 863 return nullptr;
859 } 864 }
860 865
861 ScriptValueSerializer::StateBase* ScriptValueSerializer::doSerializeObject(v8::L ocal<v8::Object> object, ScriptValueSerializer::StateBase* next) 866 ScriptValueSerializer::StateBase* ScriptValueSerializer::doSerializeObject(v8::L ocal<v8::Object> object, StateBase* next)
862 { 867 {
863 DCHECK(!object.IsEmpty()); 868 DCHECK(!object.IsEmpty());
864 869
865 870
866 if (object->IsArrayBufferView()) { 871 if (object->IsArrayBufferView()) {
867 return writeAndGreyArrayBufferView(object, next); 872 return writeAndGreyArrayBufferView(object, next);
868 } 873 }
869 if (object->IsArrayBuffer()) { 874 if (object->IsArrayBuffer()) {
870 return writeAndGreyArrayBuffer(object, next); 875 return writeAndGreyArrayBuffer(object, next);
871 } 876 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 } 952 }
948 953
949 // Since IsNativeError is expensive, this check should always be the last ch eck. 954 // Since IsNativeError is expensive, this check should always be the last ch eck.
950 if (isHostObject(object) || object->IsCallable() || object->IsNativeError()) { 955 if (isHostObject(object) || object->IsCallable() || object->IsNativeError()) {
951 return handleError(Status::DataCloneError, "An object could not be clone d.", next); 956 return handleError(Status::DataCloneError, "An object could not be clone d.", next);
952 } 957 }
953 958
954 return startObjectState(object, next); 959 return startObjectState(object, next);
955 } 960 }
956 961
957 ScriptValueSerializer::StateBase* ScriptValueSerializer::doSerializeArrayBuffer( v8::Local<v8::Value> arrayBuffer, ScriptValueSerializer::StateBase* next) 962 ScriptValueSerializer::StateBase* ScriptValueSerializer::doSerializeArrayBuffer( v8::Local<v8::Value> arrayBuffer, StateBase* next)
958 { 963 {
959 return doSerialize(arrayBuffer, next); 964 return doSerialize(arrayBuffer, next);
960 } 965 }
961 966
962 ScriptValueSerializer::StateBase* ScriptValueSerializer::checkException(ScriptVa lueSerializer::StateBase* state) 967 ScriptValueSerializer::StateBase* ScriptValueSerializer::checkException(StateBas e* state)
963 { 968 {
964 return m_tryCatch.HasCaught() ? handleError(Status::JSException, "", state) : nullptr; 969 return m_tryCatch.HasCaught() ? handleError(Status::JSException, "", state) : nullptr;
965 } 970 }
966 971
967 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeObject(uint32_t nu mProperties, ScriptValueSerializer::StateBase* state) 972 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeObject(uint32_t nu mProperties, StateBase* state)
968 { 973 {
969 m_writer.writeObject(numProperties); 974 m_writer.writeObject(numProperties);
970 return pop(state); 975 return pop(state);
971 } 976 }
972 977
973 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeSparseArray(uint32 _t numProperties, uint32_t length, ScriptValueSerializer::StateBase* state) 978 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeSparseArray(uint32 _t numProperties, uint32_t length, StateBase* state)
974 { 979 {
975 m_writer.writeSparseArray(numProperties, length); 980 m_writer.writeSparseArray(numProperties, length);
976 return pop(state); 981 return pop(state);
977 } 982 }
978 983
979 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeDenseArray(uint32_ t numProperties, uint32_t length, ScriptValueSerializer::StateBase* state) 984 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeDenseArray(uint32_ t numProperties, uint32_t length, StateBase* state)
980 { 985 {
981 m_writer.writeDenseArray(numProperties, length); 986 m_writer.writeDenseArray(numProperties, length);
982 return pop(state); 987 return pop(state);
983 } 988 }
984 989
985 template <> 990 template <>
986 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeCollection<v8::Map >(uint32_t length, ScriptValueSerializer::StateBase* state) 991 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeCollection<v8::Map >(uint32_t length, StateBase* state)
987 { 992 {
988 m_writer.writeMap(length); 993 m_writer.writeMap(length);
989 return pop(state); 994 return pop(state);
990 } 995 }
991 996
992 template <> 997 template <>
993 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeCollection<v8::Set >(uint32_t length, ScriptValueSerializer::StateBase* state) 998 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeCollection<v8::Set >(uint32_t length, StateBase* state)
994 { 999 {
995 m_writer.writeSet(length); 1000 m_writer.writeSet(length);
996 return pop(state); 1001 return pop(state);
997 } 1002 }
998 1003
999 ScriptValueSerializer::StateBase* ScriptValueSerializer::handleError(ScriptValue Serializer::Status errorStatus, const String& message, ScriptValueSerializer::St ateBase* state) 1004 ScriptValueSerializer::StateBase* ScriptValueSerializer::handleError(ScriptValue Serializer::Status errorStatus, const String& message, StateBase* state)
1000 { 1005 {
1001 DCHECK(errorStatus != Status::Success); 1006 DCHECK(errorStatus != Status::Success);
1002 m_status = errorStatus; 1007 m_status = errorStatus;
1003 m_errorMessage = message; 1008 m_errorMessage = message;
1004 while (state) { 1009 while (state) {
1005 StateBase* tmp = state->nextState(); 1010 state = pop(state);
1006 delete state;
1007 state = tmp;
1008 } 1011 }
1009 return new ErrorState; 1012 return new ErrorState;
1010 } 1013 }
1011 1014
1012 bool ScriptValueSerializer::checkComposite(ScriptValueSerializer::StateBase* top ) 1015 bool ScriptValueSerializer::checkComposite(StateBase* top)
1013 { 1016 {
1014 ASSERT(top); 1017 ASSERT(top);
1015 if (m_depth > maxDepth) 1018 if (m_depth > maxDepth)
1016 return false; 1019 return false;
1017 if (!shouldCheckForCycles(m_depth)) 1020 if (!shouldCheckForCycles(m_depth))
1018 return true; 1021 return true;
1019 v8::Local<v8::Value> composite = top->composite(); 1022 v8::Local<v8::Value> composite = top->composite();
1020 for (StateBase* state = top->nextState(); state; state = state->nextState()) { 1023 for (StateBase* state = top->nextState(); state; state = state->nextState()) {
1021 if (state->composite() == composite) 1024 if (state->composite() == composite)
1022 return false; 1025 return false;
(...skipping 22 matching lines...) Expand all
1045 v8::Local<v8::NumberObject> numberObject = value.As<v8::NumberObject>(); 1048 v8::Local<v8::NumberObject> numberObject = value.As<v8::NumberObject>();
1046 m_writer.writeNumberObject(numberObject->ValueOf()); 1049 m_writer.writeNumberObject(numberObject->ValueOf());
1047 } 1050 }
1048 1051
1049 void ScriptValueSerializer::writeBooleanObject(v8::Local<v8::Value> value) 1052 void ScriptValueSerializer::writeBooleanObject(v8::Local<v8::Value> value)
1050 { 1053 {
1051 v8::Local<v8::BooleanObject> booleanObject = value.As<v8::BooleanObject>(); 1054 v8::Local<v8::BooleanObject> booleanObject = value.As<v8::BooleanObject>();
1052 m_writer.writeBooleanObject(booleanObject->ValueOf()); 1055 m_writer.writeBooleanObject(booleanObject->ValueOf());
1053 } 1056 }
1054 1057
1055 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeBlob(v8::Local<v8: :Value> value, ScriptValueSerializer::StateBase* next) 1058 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeBlob(v8::Local<v8: :Value> value, StateBase* next)
1056 { 1059 {
1057 Blob* blob = V8Blob::toImpl(value.As<v8::Object>()); 1060 Blob* blob = V8Blob::toImpl(value.As<v8::Object>());
1058 if (!blob) 1061 if (!blob)
1059 return 0; 1062 return nullptr;
1060 if (blob->isClosed()) 1063 if (blob->isClosed())
1061 return handleError(Status::DataCloneError, "A Blob object has been close d, and could therefore not be cloned.", next); 1064 return handleError(Status::DataCloneError, "A Blob object has been close d, and could therefore not be cloned.", next);
1062 int blobIndex = -1; 1065 int blobIndex = -1;
1063 m_blobDataHandles->set(blob->uuid(), blob->blobDataHandle()); 1066 m_blobDataHandles->set(blob->uuid(), blob->blobDataHandle());
1064 if (appendBlobInfo(blob->uuid(), blob->type(), blob->size(), &blobIndex)) 1067 if (appendBlobInfo(blob->uuid(), blob->type(), blob->size(), &blobIndex))
1065 m_writer.writeBlobIndex(blobIndex); 1068 m_writer.writeBlobIndex(blobIndex);
1066 else 1069 else
1067 m_writer.writeBlob(blob->uuid(), blob->type(), blob->size()); 1070 m_writer.writeBlob(blob->uuid(), blob->type(), blob->size());
1068 return 0; 1071 return nullptr;
1069 } 1072 }
1070 1073
1071 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeCompositorProxy(v8 ::Local<v8::Value> value, ScriptValueSerializer::StateBase* next) 1074 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeCompositorProxy(v8 ::Local<v8::Value> value, StateBase* next)
1072 { 1075 {
1073 CompositorProxy* compositorProxy = V8CompositorProxy::toImpl(value.As<v8::Ob ject>()); 1076 CompositorProxy* compositorProxy = V8CompositorProxy::toImpl(value.As<v8::Ob ject>());
1074 if (!compositorProxy) 1077 if (!compositorProxy)
1075 return nullptr; 1078 return nullptr;
1076 if (!compositorProxy->connected()) 1079 if (!compositorProxy->connected())
1077 return handleError(Status::DataCloneError, "A CompositorProxy object has been disconnected, and could therefore not be cloned.", next); 1080 return handleError(Status::DataCloneError, "A CompositorProxy object has been disconnected, and could therefore not be cloned.", next);
1078 m_writer.writeCompositorProxy(*compositorProxy); 1081 m_writer.writeCompositorProxy(*compositorProxy);
1079 return nullptr; 1082 return nullptr;
1080 } 1083 }
1081 1084
1082 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeFile(v8::Local<v8: :Value> value, ScriptValueSerializer::StateBase* next) 1085 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeFile(v8::Local<v8: :Value> value, StateBase* next)
1083 { 1086 {
1084 File* file = V8File::toImpl(value.As<v8::Object>()); 1087 File* file = V8File::toImpl(value.As<v8::Object>());
1085 if (!file) 1088 if (!file)
1086 return 0; 1089 return nullptr;
1087 if (file->isClosed()) 1090 if (file->isClosed())
1088 return handleError(Status::DataCloneError, "A File object has been close d, and could therefore not be cloned.", next); 1091 return handleError(Status::DataCloneError, "A File object has been close d, and could therefore not be cloned.", next);
1089 int blobIndex = -1; 1092 int blobIndex = -1;
1090 m_blobDataHandles->set(file->uuid(), file->blobDataHandle()); 1093 m_blobDataHandles->set(file->uuid(), file->blobDataHandle());
1091 if (appendFileInfo(file, &blobIndex)) { 1094 if (appendFileInfo(file, &blobIndex)) {
1092 ASSERT(blobIndex >= 0); 1095 ASSERT(blobIndex >= 0);
1093 m_writer.writeFileIndex(blobIndex); 1096 m_writer.writeFileIndex(blobIndex);
1094 } else { 1097 } else {
1095 m_writer.writeFile(*file); 1098 m_writer.writeFile(*file);
1096 } 1099 }
1097 return 0; 1100 return nullptr;
1098 } 1101 }
1099 1102
1100 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeFileList(v8::Local <v8::Value> value, ScriptValueSerializer::StateBase* next) 1103 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeFileList(v8::Local <v8::Value> value, StateBase* next)
1101 { 1104 {
1102 FileList* fileList = V8FileList::toImpl(value.As<v8::Object>()); 1105 FileList* fileList = V8FileList::toImpl(value.As<v8::Object>());
1103 if (!fileList) 1106 if (!fileList)
1104 return 0; 1107 return nullptr;
1105 unsigned length = fileList->length(); 1108 unsigned length = fileList->length();
1106 Vector<int> blobIndices; 1109 Vector<int> blobIndices;
1107 for (unsigned i = 0; i < length; ++i) { 1110 for (unsigned i = 0; i < length; ++i) {
1108 int blobIndex = -1; 1111 int blobIndex = -1;
1109 const File* file = fileList->item(i); 1112 const File* file = fileList->item(i);
1110 if (file->isClosed()) 1113 if (file->isClosed())
1111 return handleError(Status::DataCloneError, "A File object has been c losed, and could therefore not be cloned.", next); 1114 return handleError(Status::DataCloneError, "A File object has been c losed, and could therefore not be cloned.", next);
1112 m_blobDataHandles->set(file->uuid(), file->blobDataHandle()); 1115 m_blobDataHandles->set(file->uuid(), file->blobDataHandle());
1113 if (appendFileInfo(file, &blobIndex)) { 1116 if (appendFileInfo(file, &blobIndex)) {
1114 ASSERT(!i || blobIndex > 0); 1117 ASSERT(!i || blobIndex > 0);
1115 ASSERT(blobIndex >= 0); 1118 ASSERT(blobIndex >= 0);
1116 blobIndices.append(blobIndex); 1119 blobIndices.append(blobIndex);
1117 } 1120 }
1118 } 1121 }
1119 if (!blobIndices.isEmpty()) 1122 if (!blobIndices.isEmpty())
1120 m_writer.writeFileListIndex(blobIndices); 1123 m_writer.writeFileListIndex(blobIndices);
1121 else 1124 else
1122 m_writer.writeFileList(*fileList); 1125 m_writer.writeFileList(*fileList);
1123 return 0; 1126 return nullptr;
1124 } 1127 }
1125 1128
1126 void ScriptValueSerializer::writeImageData(v8::Local<v8::Value> value) 1129 void ScriptValueSerializer::writeImageData(v8::Local<v8::Value> value)
1127 { 1130 {
1128 ImageData* imageData = V8ImageData::toImpl(value.As<v8::Object>()); 1131 ImageData* imageData = V8ImageData::toImpl(value.As<v8::Object>());
1129 if (!imageData) 1132 if (!imageData)
1130 return; 1133 return;
1131 DOMUint8ClampedArray* pixelArray = imageData->data(); 1134 DOMUint8ClampedArray* pixelArray = imageData->data();
1132 m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray- >data(), pixelArray->length()); 1135 m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray- >data(), pixelArray->length());
1133 } 1136 }
1134 1137
1135 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeAndGreyImageBitmap (v8::Local<v8::Object> object, ScriptValueSerializer::StateBase* next) 1138 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeAndGreyImageBitmap (v8::Local<v8::Object> object, StateBase* next)
1136 { 1139 {
1137 ImageBitmap* imageBitmap = V8ImageBitmap::toImpl(object); 1140 ImageBitmap* imageBitmap = V8ImageBitmap::toImpl(object);
1138 if (!imageBitmap) 1141 if (!imageBitmap)
1139 return nullptr; 1142 return nullptr;
1140 if (imageBitmap->isNeutered()) 1143 if (imageBitmap->isNeutered())
1141 return handleError(Status::DataCloneError, "An ImageBitmap is detached a nd could not be cloned.", next); 1144 return handleError(Status::DataCloneError, "An ImageBitmap is detached a nd could not be cloned.", next);
1142 1145
1143 uint32_t index; 1146 uint32_t index;
1144 if (m_transferredImageBitmaps.tryGet(object, &index)) { 1147 if (m_transferredImageBitmaps.tryGet(object, &index)) {
1145 m_writer.writeTransferredImageBitmap(index); 1148 m_writer.writeTransferredImageBitmap(index);
1146 } else { 1149 } else {
1147 greyObject(object); 1150 greyObject(object);
1148 std::unique_ptr<uint8_t[]> pixelData = imageBitmap->copyBitmapData(Premu ltiplyAlpha); 1151 std::unique_ptr<uint8_t[]> pixelData = imageBitmap->copyBitmapData(Premu ltiplyAlpha);
1149 m_writer.writeImageBitmap(imageBitmap->width(), imageBitmap->height(), s tatic_cast<uint32_t>(imageBitmap->originClean()), pixelData.get(), imageBitmap-> width() * imageBitmap->height() * 4); 1152 m_writer.writeImageBitmap(imageBitmap->width(), imageBitmap->height(), s tatic_cast<uint32_t>(imageBitmap->originClean()), pixelData.get(), imageBitmap-> width() * imageBitmap->height() * 4);
1150 } 1153 }
1151 return nullptr; 1154 return nullptr;
1152 } 1155 }
1153 1156
1154 void ScriptValueSerializer::writeRegExp(v8::Local<v8::Value> value) 1157 void ScriptValueSerializer::writeRegExp(v8::Local<v8::Value> value)
1155 { 1158 {
1156 v8::Local<v8::RegExp> regExp = value.As<v8::RegExp>(); 1159 v8::Local<v8::RegExp> regExp = value.As<v8::RegExp>();
1157 m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags()); 1160 m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags());
1158 } 1161 }
1159 1162
1160 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeAndGreyArrayBuffer View(v8::Local<v8::Object> object, ScriptValueSerializer::StateBase* next) 1163 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeAndGreyArrayBuffer View(v8::Local<v8::Object> object, StateBase* next)
1161 { 1164 {
1162 ASSERT(!object.IsEmpty()); 1165 ASSERT(!object.IsEmpty());
1163 DOMArrayBufferView* arrayBufferView = V8ArrayBufferView::toImpl(object); 1166 DOMArrayBufferView* arrayBufferView = V8ArrayBufferView::toImpl(object);
1164 if (!arrayBufferView) 1167 if (!arrayBufferView)
1165 return 0; 1168 return nullptr;
1166 if (!arrayBufferView->bufferBase()) 1169 if (!arrayBufferView->bufferBase())
1167 return handleError(Status::DataCloneError, "An ArrayBuffer could not be cloned.", next); 1170 return handleError(Status::DataCloneError, "An ArrayBuffer could not be cloned.", next);
1168 v8::Local<v8::Value> underlyingBuffer = toV8(arrayBufferView->bufferBase(), m_scriptState->context()->Global(), isolate()); 1171 v8::Local<v8::Value> underlyingBuffer = toV8(arrayBufferView->bufferBase(), m_scriptState->context()->Global(), isolate());
1169 if (underlyingBuffer.IsEmpty()) 1172 if (underlyingBuffer.IsEmpty())
1170 return handleError(Status::DataCloneError, "An ArrayBuffer could not be cloned.", next); 1173 return handleError(Status::DataCloneError, "An ArrayBuffer could not be cloned.", next);
1171 StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next); 1174 StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next);
1172 if (stateOut) 1175 if (stateOut)
1173 return stateOut; 1176 return stateOut;
1174 m_writer.writeArrayBufferView(*arrayBufferView); 1177 m_writer.writeArrayBufferView(*arrayBufferView);
1175 // This should be safe: we serialize something that we know to be a wrapper (see 1178 // This should be safe: we serialize something that we know to be a wrapper (see
1176 // the toV8 call above), so the call to doSerializeArrayBuffer should neithe r 1179 // the toV8 call above), so the call to doSerializeArrayBuffer should neithe r
1177 // cause the system stack to overflow nor should it have potential to reach 1180 // cause the system stack to overflow nor should it have potential to reach
1178 // this ArrayBufferView again. 1181 // this ArrayBufferView again.
1179 // 1182 //
1180 // We do need to grey the underlying buffer before we grey its view, however ; 1183 // We do need to grey the underlying buffer before we grey its view, however ;
1181 // ArrayBuffers may be shared, so they need to be given reference IDs, and a n 1184 // ArrayBuffers may be shared, so they need to be given reference IDs, and a n
1182 // ArrayBufferView cannot be constructed without a corresponding ArrayBuffer 1185 // ArrayBufferView cannot be constructed without a corresponding ArrayBuffer
1183 // (or without an additional tag that would allow us to do two-stage constru ction 1186 // (or without an additional tag that would allow us to do two-stage constru ction
1184 // like we do for Objects and Arrays). 1187 // like we do for Objects and Arrays).
1185 greyObject(object); 1188 greyObject(object);
1186 return 0; 1189 return nullptr;
1187 } 1190 }
1188 1191
1189 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeAndGreyArrayBuffer (v8::Local<v8::Object> object, ScriptValueSerializer::StateBase* next) 1192 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeAndGreyArrayBuffer (v8::Local<v8::Object> object, StateBase* next)
1190 { 1193 {
1191 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(object); 1194 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(object);
1192 if (!arrayBuffer) 1195 if (!arrayBuffer)
1193 return nullptr; 1196 return nullptr;
1194 if (arrayBuffer->isNeutered()) 1197 if (arrayBuffer->isNeutered())
1195 return handleError(Status::DataCloneError, "An ArrayBuffer is neutered a nd could not be cloned.", next); 1198 return handleError(Status::DataCloneError, "An ArrayBuffer is neutered a nd could not be cloned.", next);
1196 1199
1197 uint32_t index; 1200 uint32_t index;
1198 if (m_transferredArrayBuffers.tryGet(object, &index)) { 1201 if (m_transferredArrayBuffers.tryGet(object, &index)) {
1199 m_writer.writeTransferredArrayBuffer(index); 1202 m_writer.writeTransferredArrayBuffer(index);
1200 } else { 1203 } else {
1201 greyObject(object); 1204 greyObject(object);
1202 m_writer.writeArrayBuffer(*arrayBuffer); 1205 m_writer.writeArrayBuffer(*arrayBuffer);
1203 } 1206 }
1204 return nullptr; 1207 return nullptr;
1205 } 1208 }
1206 1209
1207 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeTransferredOffscre enCanvas(v8::Local<v8::Value> value, uint32_t index, ScriptValueSerializer::Stat eBase* next) 1210 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeTransferredOffscre enCanvas(v8::Local<v8::Value> value, uint32_t index, StateBase* next)
1208 { 1211 {
1209 OffscreenCanvas* offscreenCanvas = V8OffscreenCanvas::toImpl(value.As<v8::Ob ject>()); 1212 OffscreenCanvas* offscreenCanvas = V8OffscreenCanvas::toImpl(value.As<v8::Ob ject>());
1210 if (!offscreenCanvas) 1213 if (!offscreenCanvas)
1211 return nullptr; 1214 return nullptr;
1212 if (offscreenCanvas->isNeutered()) 1215 if (offscreenCanvas->isNeutered())
1213 return handleError(Status::DataCloneError, "An OffscreenCanvas is detach ed and could not be cloned.", next); 1216 return handleError(Status::DataCloneError, "An OffscreenCanvas is detach ed and could not be cloned.", next);
1214 if (offscreenCanvas->renderingContext()) 1217 if (offscreenCanvas->renderingContext())
1215 return handleError(Status::DataCloneError, "An OffscreenCanvas with a co ntext could not be cloned.", next); 1218 return handleError(Status::DataCloneError, "An OffscreenCanvas with a co ntext could not be cloned.", next);
1216 m_writer.writeTransferredOffscreenCanvas(index, offscreenCanvas->width(), of fscreenCanvas->height(), offscreenCanvas->getAssociatedCanvasId()); 1219 m_writer.writeTransferredOffscreenCanvas(index, offscreenCanvas->width(), of fscreenCanvas->height(), offscreenCanvas->getAssociatedCanvasId());
1217 return nullptr; 1220 return nullptr;
1218 } 1221 }
1219 1222
1220 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeTransferredSharedA rrayBuffer(v8::Local<v8::Value> value, uint32_t index, ScriptValueSerializer::St ateBase* next) 1223 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeTransferredSharedA rrayBuffer(v8::Local<v8::Value> value, uint32_t index, StateBase* next)
1221 { 1224 {
1222 ASSERT(RuntimeEnabledFeatures::sharedArrayBufferEnabled()); 1225 ASSERT(RuntimeEnabledFeatures::sharedArrayBufferEnabled());
1223 DOMSharedArrayBuffer* sharedArrayBuffer = V8SharedArrayBuffer::toImpl(value. As<v8::Object>()); 1226 DOMSharedArrayBuffer* sharedArrayBuffer = V8SharedArrayBuffer::toImpl(value. As<v8::Object>());
1224 if (!sharedArrayBuffer) 1227 if (!sharedArrayBuffer)
1225 return 0; 1228 return 0;
1226 m_writer.writeTransferredSharedArrayBuffer(index); 1229 m_writer.writeTransferredSharedArrayBuffer(index);
1227 return 0; 1230 return nullptr;
1228 } 1231 }
1229 1232
1230 bool ScriptValueSerializer::shouldSerializeDensely(uint32_t length, uint32_t pro pertyCount) 1233 bool ScriptValueSerializer::shouldSerializeDensely(uint32_t length, uint32_t pro pertyCount)
1231 { 1234 {
1232 // Let K be the cost of serializing all property values that are there 1235 // Let K be the cost of serializing all property values that are there
1233 // Cost of serializing sparsely: 5*propertyCount + K (5 bytes per uint32_t k ey) 1236 // Cost of serializing sparsely: 5*propertyCount + K (5 bytes per uint32_t k ey)
1234 // Cost of serializing densely: K + 1*(length - propertyCount) (1 byte for a ll properties that are not there) 1237 // Cost of serializing densely: K + 1*(length - propertyCount) (1 byte for a ll properties that are not there)
1235 // so densely is better than sparsly whenever 6*propertyCount > length 1238 // so densely is better than sparsly whenever 6*propertyCount > length
1236 return 6 * propertyCount >= length; 1239 return 6 * propertyCount >= length;
1237 } 1240 }
1238 1241
1239 ScriptValueSerializer::StateBase* ScriptValueSerializer::startArrayState(v8::Loc al<v8::Array> array, ScriptValueSerializer::StateBase* next) 1242 ScriptValueSerializer::StateBase* ScriptValueSerializer::startArrayState(v8::Loc al<v8::Array> array, StateBase* next)
1240 { 1243 {
1241 v8::Local<v8::Array> propertyNames; 1244 v8::Local<v8::Array> propertyNames;
1242 if (!array->GetOwnPropertyNames(context()).ToLocal(&propertyNames)) 1245 if (!array->GetOwnPropertyNames(context()).ToLocal(&propertyNames))
1243 return checkException(next); 1246 return checkException(next);
1244 uint32_t length = array->Length(); 1247 uint32_t length = array->Length();
1245 1248
1246 if (shouldSerializeDensely(length, propertyNames->Length())) { 1249 if (shouldSerializeDensely(length, propertyNames->Length())) {
1247 m_writer.writeGenerateFreshDenseArray(length);
1248 // In serializing a dense array, indexed properties are ignored, so we g et 1250 // In serializing a dense array, indexed properties are ignored, so we g et
1249 // non indexed own property names here. 1251 // non indexed own property names here.
1250 if (!array->GetPropertyNames(context(), v8::KeyCollectionMode::kIncludeP rototypes, static_cast<v8::PropertyFilter>(v8::ONLY_ENUMERABLE | v8::SKIP_SYMBOL S), v8::IndexFilter::kSkipIndices).ToLocal(&propertyNames)) 1252 if (!array->GetPropertyNames(context(), v8::KeyCollectionMode::kIncludeP rototypes, static_cast<v8::PropertyFilter>(v8::ONLY_ENUMERABLE | v8::SKIP_SYMBOL S), v8::IndexFilter::kSkipIndices).ToLocal(&propertyNames))
1251 return checkException(next); 1253 return checkException(next);
1254
1255 m_writer.writeGenerateFreshDenseArray(length);
1252 return push(new DenseArrayState(array, propertyNames, next, isolate())); 1256 return push(new DenseArrayState(array, propertyNames, next, isolate()));
1253 } 1257 }
1254 1258
1255 m_writer.writeGenerateFreshSparseArray(length); 1259 m_writer.writeGenerateFreshSparseArray(length);
1256 return push(new SparseArrayState(array, propertyNames, next, isolate())); 1260 return push(new SparseArrayState(array, propertyNames, next, isolate()));
1257 } 1261 }
1258 1262
1259 ScriptValueSerializer::StateBase* ScriptValueSerializer::startMapState(v8::Local <v8::Map> map, ScriptValueSerializer::StateBase* next) 1263 ScriptValueSerializer::StateBase* ScriptValueSerializer::startMapState(v8::Local <v8::Map> map, StateBase* next)
1260 { 1264 {
1261 m_writer.writeGenerateFreshMap(); 1265 m_writer.writeGenerateFreshMap();
1262 return push(new MapState(map, next)); 1266 return push(new MapState(map, next));
1263 } 1267 }
1264 1268
1265 ScriptValueSerializer::StateBase* ScriptValueSerializer::startSetState(v8::Local <v8::Set> set, ScriptValueSerializer::StateBase* next) 1269 ScriptValueSerializer::StateBase* ScriptValueSerializer::startSetState(v8::Local <v8::Set> set, StateBase* next)
1266 { 1270 {
1267 m_writer.writeGenerateFreshSet(); 1271 m_writer.writeGenerateFreshSet();
1268 return push(new SetState(set, next)); 1272 return push(new SetState(set, next));
1269 } 1273 }
1270 1274
1271 ScriptValueSerializer::StateBase* ScriptValueSerializer::startObjectState(v8::Lo cal<v8::Object> object, ScriptValueSerializer::StateBase* next) 1275 ScriptValueSerializer::StateBase* ScriptValueSerializer::startObjectState(v8::Lo cal<v8::Object> object, StateBase* next)
1272 { 1276 {
1273 m_writer.writeGenerateFreshObject(); 1277 m_writer.writeGenerateFreshObject();
1274 // FIXME: check not a wrapper 1278 // FIXME: check not a wrapper
1275 return push(new ObjectState(object, next)); 1279 return push(new ObjectState(object, next));
1276 } 1280 }
1277 1281
1278 // Marks object as having been visited by the serializer and assigns it a unique object reference ID. 1282 // Marks object as having been visited by the serializer and assigns it a unique object reference ID.
1279 // An object may only be greyed once. 1283 // An object may only be greyed once.
1280 void ScriptValueSerializer::greyObject(const v8::Local<v8::Object>& object) 1284 void ScriptValueSerializer::greyObject(const v8::Local<v8::Object>& object)
1281 { 1285 {
(...skipping 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after
2442 return false; 2446 return false;
2443 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe renceStack.size() - 1]; 2447 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe renceStack.size() - 1];
2444 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1); 2448 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1);
2445 if (objectReference >= m_objectPool.size()) 2449 if (objectReference >= m_objectPool.size())
2446 return false; 2450 return false;
2447 *object = m_objectPool[objectReference]; 2451 *object = m_objectPool[objectReference];
2448 return true; 2452 return true;
2449 } 2453 }
2450 2454
2451 } // namespace blink 2455 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698