Index: Source/bindings/core/v8/ScriptValueSerializer.h |
diff --git a/Source/bindings/core/v8/ScriptValueSerializer.h b/Source/bindings/core/v8/ScriptValueSerializer.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1b6c26706641ac48b1f99918cbabdac238a9f41c |
--- /dev/null |
+++ b/Source/bindings/core/v8/ScriptValueSerializer.h |
@@ -0,0 +1,607 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef ScriptValueSerializer_h |
+#define ScriptValueSerializer_h |
+ |
+#include "bindings/core/v8/SerializationTag.h" |
+#include "bindings/core/v8/SerializedScriptValue.h" |
+#include "bindings/core/v8/V8Binding.h" |
+#include "public/platform/WebCrypto.h" |
+#include "public/platform/WebCryptoKey.h" |
+#include "public/platform/WebCryptoKeyAlgorithm.h" |
+#include "wtf/ArrayBufferContents.h" |
+#include "wtf/HashMap.h" |
+#include "wtf/Noncopyable.h" |
+#include "wtf/Vector.h" |
+#include "wtf/text/WTFString.h" |
+#include <v8.h> |
+ |
+namespace WTF { |
+ |
+class ArrayBuffer; |
+class ArrayBufferView; |
+ |
+} |
+ |
+namespace blink { |
+ |
+class File; |
+class FileList; |
+ |
+namespace SerializedScriptValueInternal { |
+ |
+typedef Vector<WTF::ArrayBufferContents, 1> ArrayBufferContentsArray; |
+ |
+// V8ObjectMap is a map from V8 objects to arbitrary values of type T. |
+// V8 objects (or handles to V8 objects) cannot be used as keys in ordinary wtf::HashMaps; |
+// this class should be used instead. GCObject must be a subtype of v8::Object. |
+// Suggested usage: |
+// V8ObjectMap<v8::Object, int> map; |
+// v8::Handle<v8::Object> obj = ...; |
+// map.set(obj, 42); |
+template<typename GCObject, typename T> |
+class V8ObjectMap { |
+public: |
+ bool contains(const v8::Handle<GCObject>& handle) |
+ { |
+ return m_map.contains(*handle); |
+ } |
+ |
+ bool tryGet(const v8::Handle<GCObject>& handle, T* valueOut) |
+ { |
+ typename HandleToT::iterator result = m_map.find(*handle); |
+ if (result != m_map.end()) { |
+ *valueOut = result->value; |
+ return true; |
+ } |
+ return false; |
+ } |
+ |
+ void set(const v8::Handle<GCObject>& handle, const T& value) |
+ { |
+ m_map.set(*handle, value); |
+ } |
+ |
+private: |
+ // This implementation uses GetIdentityHash(), which sets a hidden property on the object containing |
+ // a random integer (or returns the one that had been previously set). This ensures that the table |
+ // never needs to be rebuilt across garbage collections at the expense of doing additional allocation |
+ // and making more round trips into V8. Note that since GetIdentityHash() is defined only on |
+ // v8::Objects, this V8ObjectMap cannot be used to map v8::Strings to T (because the public V8 API |
+ // considers a v8::String to be a v8::Primitive). |
+ |
+ // If V8 exposes a way to get at the address of the object held by a handle, then we can produce |
+ // an alternate implementation that does not need to do any V8-side allocation; however, it will |
+ // need to rehash after every garbage collection because a key object may have been moved. |
+ template<typename G> |
+ struct V8HandlePtrHash { |
+ static v8::Handle<G> unsafeHandleFromRawValue(const G* value) |
+ { |
+ const v8::Handle<G>* handle = reinterpret_cast<const v8::Handle<G>*>(&value); |
+ return *handle; |
+ } |
+ |
+ static unsigned hash(const G* key) |
+ { |
+ return static_cast<unsigned>(unsafeHandleFromRawValue(key)->GetIdentityHash()); |
+ } |
+ static bool equal(const G* a, const G* b) |
+ { |
+ return unsafeHandleFromRawValue(a) == unsafeHandleFromRawValue(b); |
+ } |
+ // For HashArg. |
+ static const bool safeToCompareToEmptyOrDeleted = false; |
+ }; |
+ |
+ typedef WTF::HashMap<GCObject*, T, V8HandlePtrHash<GCObject> > HandleToT; |
+ HandleToT m_map; |
+}; |
+ |
+// Writer is responsible for serializing primitive types and storing |
+// information used to reconstruct composite types. |
+class Writer { |
+ STACK_ALLOCATED(); |
+ WTF_MAKE_NONCOPYABLE(Writer); |
+public: |
+ typedef UChar BufferValueType; |
+ |
+ Writer() |
+ : m_position(0) |
+ { |
+ } |
+ |
+ // Write functions for primitive types. |
+ |
+ void writeUndefined(); |
+ void writeNull(); |
+ void writeTrue(); |
+ void writeFalse(); |
+ void writeBooleanObject(bool value); |
+ void writeOneByteString(v8::Handle<v8::String>&); |
+ void writeUCharString(v8::Handle<v8::String>&); |
+ void writeStringObject(const char* data, int length); |
+ void writeWebCoreString(const String&); |
+ void writeVersion(); |
+ void writeInt32(int32_t value); |
+ void writeUint32(uint32_t value); |
+ void writeDate(double numberValue); |
+ void writeNumber(double number); |
+ void writeNumberObject(double number); |
+ void writeBlob(const String& uuid, const String& type, unsigned long long size); |
+ void writeBlobIndex(int blobIndex); |
+ void writeDOMFileSystem(int type, const String& name, const String& url); |
+ void writeFile(const File&); |
+ void writeFileIndex(int blobIndex); |
+ void writeFileList(const FileList&); |
+ void writeFileListIndex(const Vector<int>& blobIndices); |
+ bool writeCryptoKey(const WebCryptoKey&); |
+ void writeArrayBuffer(const ArrayBuffer&); |
+ void writeArrayBufferView(const ArrayBufferView&); |
+ void writeImageData(uint32_t width, uint32_t height, const uint8_t* pixelData, uint32_t pixelDataLength); |
+ void writeRegExp(v8::Local<v8::String> pattern, v8::RegExp::Flags); |
+ void writeTransferredMessagePort(uint32_t index); |
+ void writeTransferredArrayBuffer(uint32_t index); |
+ void writeObjectReference(uint32_t reference); |
+ void writeObject(uint32_t numProperties); |
+ void writeSparseArray(uint32_t numProperties, uint32_t length); |
+ void writeDenseArray(uint32_t numProperties, uint32_t length); |
+ String takeWireString(); |
+ void writeReferenceCount(uint32_t numberOfReferences); |
+ void writeGenerateFreshObject(); |
+ void writeGenerateFreshSparseArray(uint32_t length); |
+ void writeGenerateFreshDenseArray(uint32_t length); |
+ |
+protected: |
+ void doWriteFile(const File&); |
+ void doWriteArrayBuffer(const ArrayBuffer&); |
+ void doWriteString(const char* data, int length); |
+ void doWriteWebCoreString(const String&); |
+ void doWriteHmacKey(const WebCryptoKey&); |
+ void doWriteAesKey(const WebCryptoKey&); |
+ void doWriteRsaHashedKey(const WebCryptoKey&); |
+ void doWriteEcKey(const WebCryptoKey&); |
+ void doWriteAlgorithmId(WebCryptoAlgorithmId); |
+ void doWriteAsymmetricKeyType(WebCryptoKeyType); |
+ void doWriteNamedCurve(WebCryptoNamedCurve); |
+ void doWriteKeyUsages(const WebCryptoKeyUsageMask usages, bool extractable); |
+ int bytesNeededToWireEncode(uint32_t value); |
+ |
+ template<class T> |
+ void doWriteUintHelper(T value) |
+ { |
+ while (true) { |
+ uint8_t b = (value & SerializedScriptValue::varIntMask); |
+ value >>= SerializedScriptValue::varIntShift; |
+ if (!value) { |
+ append(b); |
+ break; |
+ } |
+ append(b | (1 << SerializedScriptValue::varIntShift)); |
+ } |
+ } |
+ |
+ void doWriteUint32(uint32_t value); |
+ void doWriteUint64(uint64_t value); |
+ void doWriteNumber(double number); |
+ void append(SerializationTag); |
+ void append(uint8_t b); |
+ void append(const uint8_t* data, int length); |
+ void ensureSpace(unsigned extra); |
+ void fillHole(); |
+ uint8_t* byteAt(int position); |
+ int v8StringWriteOptions(); |
+ |
+private: |
+ Vector<BufferValueType> m_buffer; |
+ unsigned m_position; |
+}; |
+ |
+class Serializer { |
+ STACK_ALLOCATED(); |
+ WTF_MAKE_NONCOPYABLE(Serializer); |
+protected: |
+ class StateBase; |
+public: |
+ enum Status { |
+ Success, |
+ InputError, |
+ DataCloneError, |
+ JSException |
+ }; |
+ |
+ Serializer(Writer&, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, WebBlobInfoArray*, BlobDataHandleMap& blobDataHandles, v8::TryCatch&, ScriptState*); |
+ v8::Isolate* isolate() { return m_scriptState->isolate(); } |
+ |
+ Status serialize(v8::Handle<v8::Value>); |
+ String errorMessage() { return m_errorMessage; } |
+ |
+ // Functions used by serialization states. |
+ Serializer::StateBase* doSerialize(v8::Handle<v8::Value>, Serializer::StateBase* next); |
+ |
+ StateBase* doSerializeArrayBuffer(v8::Handle<v8::Value> arrayBuffer, StateBase* next); |
+ StateBase* checkException(StateBase*); |
+ StateBase* writeObject(uint32_t numProperties, StateBase*); |
+ StateBase* writeSparseArray(uint32_t numProperties, uint32_t length, StateBase*); |
+ StateBase* writeDenseArray(uint32_t numProperties, uint32_t length, StateBase*); |
+ |
+protected: |
+ class StateBase { |
+ WTF_MAKE_NONCOPYABLE(StateBase); |
+ public: |
+ virtual ~StateBase() { } |
+ |
+ // Link to the next state to form a stack. |
+ StateBase* nextState() { return m_next; } |
+ |
+ // Composite object we're processing in this state. |
+ v8::Handle<v8::Value> composite() { return m_composite; } |
+ |
+ // Serializes (a part of) the current composite and returns |
+ // the next state to process or null when this is the final |
+ // state. |
+ virtual StateBase* advance(Serializer&) = 0; |
+ |
+ protected: |
+ StateBase(v8::Handle<v8::Value> composite, StateBase* next) |
+ : m_composite(composite) |
+ , m_next(next) |
+ { |
+ } |
+ |
+ private: |
+ v8::Handle<v8::Value> m_composite; |
+ StateBase* m_next; |
+ }; |
+ |
+ // Dummy state that is used to signal serialization errors. |
+ class ErrorState final : public StateBase { |
+ public: |
+ ErrorState() |
+ : StateBase(v8Undefined(), 0) |
+ { |
+ } |
+ |
+ virtual StateBase* advance(Serializer&) override |
+ { |
+ delete this; |
+ return 0; |
+ } |
+ }; |
+ |
+ template <typename T> |
+ class State : public StateBase { |
+ public: |
+ v8::Handle<T> composite() { return v8::Handle<T>::Cast(StateBase::composite()); } |
+ |
+ protected: |
+ State(v8::Handle<T> composite, StateBase* next) |
+ : StateBase(composite, next) |
+ { |
+ } |
+ }; |
+ |
+ class AbstractObjectState : public State<v8::Object> { |
+ public: |
+ AbstractObjectState(v8::Handle<v8::Object> object, StateBase* next) |
+ : State<v8::Object>(object, next) |
+ , m_index(0) |
+ , m_numSerializedProperties(0) |
+ , m_nameDone(false) |
+ { |
+ } |
+ |
+ protected: |
+ virtual StateBase* objectDone(unsigned numProperties, Serializer&) = 0; |
+ |
+ StateBase* serializeProperties(bool ignoreIndexed, Serializer&); |
+ v8::Local<v8::Array> m_propertyNames; |
+ |
+ private: |
+ v8::Local<v8::Value> m_propertyName; |
+ unsigned m_index; |
+ unsigned m_numSerializedProperties; |
+ bool m_nameDone; |
+ }; |
+ |
+ class ObjectState final : public AbstractObjectState { |
+ public: |
+ ObjectState(v8::Handle<v8::Object> object, StateBase* next) |
+ : AbstractObjectState(object, next) |
+ { |
+ } |
+ |
+ virtual StateBase* advance(Serializer&) override; |
+ |
+ protected: |
+ virtual StateBase* objectDone(unsigned numProperties, Serializer&) override; |
+ }; |
+ |
+ class DenseArrayState final : public AbstractObjectState { |
+ public: |
+ DenseArrayState(v8::Handle<v8::Array> array, v8::Handle<v8::Array> propertyNames, StateBase* next, v8::Isolate* isolate) |
+ : AbstractObjectState(array, next) |
+ , m_arrayIndex(0) |
+ , m_arrayLength(array->Length()) |
+ { |
+ m_propertyNames = v8::Local<v8::Array>::New(isolate, propertyNames); |
+ } |
+ |
+ virtual StateBase* advance(Serializer&) override; |
+ |
+ protected: |
+ virtual StateBase* objectDone(unsigned numProperties, Serializer&) override; |
+ |
+ private: |
+ uint32_t m_arrayIndex; |
+ uint32_t m_arrayLength; |
+ }; |
+ |
+ class SparseArrayState final : public AbstractObjectState { |
+ public: |
+ SparseArrayState(v8::Handle<v8::Array> array, v8::Handle<v8::Array> propertyNames, StateBase* next, v8::Isolate* isolate) |
+ : AbstractObjectState(array, next) |
+ { |
+ m_propertyNames = v8::Local<v8::Array>::New(isolate, propertyNames); |
+ } |
+ |
+ virtual StateBase* advance(Serializer&) override; |
+ |
+ protected: |
+ virtual StateBase* objectDone(unsigned numProperties, Serializer&) override; |
+ }; |
+ |
+private: |
+ StateBase* push(StateBase* state) |
+ { |
+ ASSERT(state); |
+ ++m_depth; |
+ return checkComposite(state) ? state : handleError(InputError, "Value being cloned is either cyclic or too deeply nested.", state); |
+ } |
+ |
+ StateBase* pop(StateBase* state) |
+ { |
+ ASSERT(state); |
+ --m_depth; |
+ StateBase* next = state->nextState(); |
+ delete state; |
+ return next; |
+ } |
+ |
+ bool checkComposite(StateBase* top); |
+ void writeString(v8::Handle<v8::Value>); |
+ void writeStringObject(v8::Handle<v8::Value>); |
+ void writeNumberObject(v8::Handle<v8::Value>); |
+ void writeBooleanObject(v8::Handle<v8::Value>); |
+ StateBase* writeBlob(v8::Handle<v8::Value>, StateBase* next); |
+ StateBase* writeDOMFileSystem(v8::Handle<v8::Value>, StateBase* next); |
+ StateBase* writeFile(v8::Handle<v8::Value>, StateBase* next); |
+ StateBase* writeFileList(v8::Handle<v8::Value>, StateBase* next); |
+ bool writeCryptoKey(v8::Handle<v8::Value>); |
+ void writeImageData(v8::Handle<v8::Value>); |
+ void writeRegExp(v8::Handle<v8::Value>); |
+ StateBase* writeAndGreyArrayBufferView(v8::Handle<v8::Object>, StateBase* next); |
+ StateBase* writeArrayBuffer(v8::Handle<v8::Value>, StateBase* next); |
+ StateBase* writeTransferredArrayBuffer(v8::Handle<v8::Value>, uint32_t index, StateBase* next); |
+ static bool shouldSerializeDensely(uint32_t length, uint32_t propertyCount); |
+ |
+ StateBase* startArrayState(v8::Handle<v8::Array>, StateBase* next); |
+ StateBase* startObjectState(v8::Handle<v8::Object>, StateBase* next); |
+ |
+ // Marks object as having been visited by the serializer and assigns it a unique object reference ID. |
+ // An object may only be greyed once. |
+ void greyObject(const v8::Handle<v8::Object>&); |
+ bool appendBlobInfo(const String& uuid, const String& type, unsigned long long size, int* index); |
+ bool appendFileInfo(const File*, int* index); |
+ |
+protected: |
+ StateBase* handleError(Status errorStatus, const String& message, StateBase*); |
+ |
+ Writer& writer() { return m_writer; } |
+ uint32_t nextObjectReference() const { return m_nextObjectReference; } |
+ |
+private: |
+ RefPtr<ScriptState> m_scriptState; |
+ Writer& m_writer; |
+ v8::TryCatch& m_tryCatch; |
+ int m_depth; |
+ Status m_status; |
+ String m_errorMessage; |
+ typedef V8ObjectMap<v8::Object, uint32_t> ObjectPool; |
+ ObjectPool m_objectPool; |
+ ObjectPool m_transferredMessagePorts; |
+ ObjectPool m_transferredArrayBuffers; |
+ uint32_t m_nextObjectReference; |
+ WebBlobInfoArray* m_blobInfo; |
+ BlobDataHandleMap& m_blobDataHandles; |
+}; |
+ |
+// Interface used by Reader to create objects of composite types. |
+class CompositeCreator { |
+ STACK_ALLOCATED(); |
+ WTF_MAKE_NONCOPYABLE(CompositeCreator); |
+public: |
+ CompositeCreator() { } |
+ virtual ~CompositeCreator() { } |
+ |
+ virtual bool consumeTopOfStack(v8::Handle<v8::Value>*) = 0; |
+ virtual uint32_t objectReferenceCount() = 0; |
+ virtual void pushObjectReference(const v8::Handle<v8::Value>&) = 0; |
+ virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Handle<v8::Value>*) = 0; |
+ virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Value>*) = 0; |
+ virtual bool tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::Value>*) = 0; |
+ virtual bool newSparseArray(uint32_t length) = 0; |
+ virtual bool newDenseArray(uint32_t length) = 0; |
+ virtual bool newObject() = 0; |
+ virtual bool completeObject(uint32_t numProperties, v8::Handle<v8::Value>*) = 0; |
+ virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>*) = 0; |
+ virtual bool completeDenseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>*) = 0; |
+}; |
+ |
+// Reader is responsible for deserializing primitive types and |
+// restoring information about saved objects of composite types. |
+class Reader { |
+ STACK_ALLOCATED(); |
+ WTF_MAKE_NONCOPYABLE(Reader); |
+public: |
+ Reader(const uint8_t* buffer, int length, const WebBlobInfoArray* blobInfo, BlobDataHandleMap& blobDataHandles, ScriptState* scriptState) |
+ : m_scriptState(scriptState) |
+ , m_buffer(buffer) |
+ , m_length(length) |
+ , m_position(0) |
+ , m_version(0) |
+ , m_blobInfo(blobInfo) |
+ , m_blobDataHandles(blobDataHandles) |
+ { |
+ ASSERT(!(reinterpret_cast<size_t>(buffer) & 1)); |
+ ASSERT(length >= 0); |
+ } |
+ |
+ bool isEof() const { return m_position >= m_length; } |
+ |
+ ScriptState* scriptState() const { return m_scriptState.get(); } |
+ |
+protected: |
+ v8::Isolate* isolate() const { return m_scriptState->isolate(); } |
+ unsigned length() const { return m_length; } |
+ unsigned position() const { return m_position; } |
+ |
+ const uint8_t* allocate(uint32_t size) |
+ { |
+ const uint8_t* allocated = m_buffer + m_position; |
+ m_position += size; |
+ return allocated; |
+ } |
+ |
+public: |
+ bool read(v8::Handle<v8::Value>*, CompositeCreator&); |
+ bool readVersion(uint32_t& version); |
+ void setVersion(uint32_t); |
+ |
+private: |
+ bool readTag(SerializationTag*); |
+ bool readWebCoreString(String*); |
+ bool readUint32(v8::Handle<v8::Value>*); |
+ void undoReadTag(); |
+ bool readArrayBufferViewSubTag(ArrayBufferViewSubTag*); |
+ bool readString(v8::Handle<v8::Value>*); |
+ bool readUCharString(v8::Handle<v8::Value>*); |
+ bool readStringObject(v8::Handle<v8::Value>*); |
+ bool readInt32(v8::Handle<v8::Value>*); |
+ bool readDate(v8::Handle<v8::Value>*); |
+ bool readNumber(v8::Handle<v8::Value>*); |
+ bool readNumberObject(v8::Handle<v8::Value>*); |
+ bool readImageData(v8::Handle<v8::Value>*); |
+ PassRefPtr<ArrayBuffer> doReadArrayBuffer(); |
+ bool readArrayBuffer(v8::Handle<v8::Value>*); |
+ bool readArrayBufferView(v8::Handle<v8::Value>*, CompositeCreator&); |
+ bool readRegExp(v8::Handle<v8::Value>*); |
+ bool readBlob(v8::Handle<v8::Value>*, bool isIndexed); |
+ bool readDOMFileSystem(v8::Handle<v8::Value>*); |
+ bool readFile(v8::Handle<v8::Value>*, bool isIndexed); |
+ bool readFileList(v8::Handle<v8::Value>*, bool isIndexed); |
+ bool readCryptoKey(v8::Handle<v8::Value>*); |
+ File* readFileHelper(); |
+ File* readFileIndexHelper(); |
+ |
+ template<class T> |
+ bool doReadUintHelper(T* value) |
+ { |
+ *value = 0; |
+ uint8_t currentByte; |
+ int shift = 0; |
+ do { |
+ if (m_position >= m_length) |
+ return false; |
+ currentByte = m_buffer[m_position++]; |
+ *value |= ((currentByte & SerializedScriptValue::varIntMask) << shift); |
+ shift += SerializedScriptValue::varIntShift; |
+ } while (currentByte & (1 << SerializedScriptValue::varIntShift)); |
+ return true; |
+ } |
+ |
+ bool doReadUint32(uint32_t* value); |
+ bool doReadUint64(uint64_t* value); |
+ bool doReadNumber(double* number); |
+ PassRefPtr<BlobDataHandle> getOrCreateBlobDataHandle(const String& uuid, const String& type, long long size = -1); |
+ bool doReadHmacKey(WebCryptoKeyAlgorithm&, WebCryptoKeyType&); |
+ bool doReadAesKey(WebCryptoKeyAlgorithm&, WebCryptoKeyType&); |
+ bool doReadRsaHashedKey(WebCryptoKeyAlgorithm&, WebCryptoKeyType&); |
+ bool doReadEcKey(WebCryptoKeyAlgorithm&, WebCryptoKeyType&); |
+ bool doReadAlgorithmId(WebCryptoAlgorithmId&); |
+ bool doReadAsymmetricKeyType(WebCryptoKeyType&); |
+ bool doReadNamedCurve(WebCryptoNamedCurve&); |
+ bool doReadKeyUsages(WebCryptoKeyUsageMask& usages, bool& extractable); |
+ |
+private: |
+ RefPtr<ScriptState> m_scriptState; |
+ const uint8_t* m_buffer; |
+ const unsigned m_length; |
+ unsigned m_position; |
+ uint32_t m_version; |
+ const WebBlobInfoArray* m_blobInfo; |
+ const BlobDataHandleMap& m_blobDataHandles; |
+}; |
+ |
+class Deserializer : public CompositeCreator { |
+ STACK_ALLOCATED(); |
+ WTF_MAKE_NONCOPYABLE(Deserializer); |
+public: |
+ Deserializer(Reader& reader, MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContents) |
+ : m_reader(reader) |
+ , m_transferredMessagePorts(messagePorts) |
+ , m_arrayBufferContents(arrayBufferContents) |
+ , m_arrayBuffers(arrayBufferContents ? arrayBufferContents->size() : 0) |
+ , m_version(0) |
+ { |
+ } |
+ |
+ v8::Handle<v8::Value> deserialize(); |
+ virtual bool newSparseArray(uint32_t) override; |
+ virtual bool newDenseArray(uint32_t length) override; |
+ virtual bool consumeTopOfStack(v8::Handle<v8::Value>*) override; |
+ virtual bool newObject() override; |
+ virtual bool completeObject(uint32_t numProperties, v8::Handle<v8::Value>*) override; |
+ virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>*) override; |
+ virtual bool completeDenseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>*) override; |
+ virtual void pushObjectReference(const v8::Handle<v8::Value>&) override; |
+ virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Value>*) override; |
+ virtual bool tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::Value>*) override; |
+ virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Handle<v8::Value>*) override; |
+ virtual uint32_t objectReferenceCount() override; |
+ |
+protected: |
+ Reader& reader() { return m_reader; } |
+ bool read(v8::Local<v8::Value>*); |
+ |
+private: |
+ bool initializeObject(v8::Handle<v8::Object>, uint32_t numProperties, v8::Handle<v8::Value>*); |
+ bool doDeserialize(); |
+ void push(v8::Local<v8::Value> value) { m_stack.append(value); }; |
+ void pop(unsigned length) |
+ { |
+ ASSERT(length <= m_stack.size()); |
+ m_stack.shrink(m_stack.size() - length); |
+ } |
+ unsigned stackDepth() const { return m_stack.size(); } |
+ |
+ v8::Local<v8::Value> element(unsigned index); |
+ void openComposite(const v8::Local<v8::Value>&); |
+ bool closeComposite(v8::Handle<v8::Value>*); |
+ |
+ Reader& m_reader; |
+ Vector<v8::Local<v8::Value> > m_stack; |
+ Vector<v8::Handle<v8::Value> > m_objectPool; |
+ Vector<uint32_t> m_openCompositeReferenceStack; |
+ RawPtrWillBeMember<MessagePortArray> m_transferredMessagePorts; |
+ ArrayBufferContentsArray* m_arrayBufferContents; |
+ Vector<v8::Handle<v8::Object> > m_arrayBuffers; |
+ uint32_t m_version; |
+}; |
+ |
+} // namespace SerializedScriptValueInternal |
+ |
+} // namespace blink |
+ |
+#endif // ScriptValueSerializer_h |