OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef ScriptValueSerializer_h |
| 6 #define ScriptValueSerializer_h |
| 7 |
| 8 #include "bindings/core/v8/SerializationTag.h" |
| 9 #include "bindings/core/v8/SerializedScriptValue.h" |
| 10 #include "bindings/core/v8/V8Binding.h" |
| 11 #include "public/platform/WebCrypto.h" |
| 12 #include "public/platform/WebCryptoKey.h" |
| 13 #include "public/platform/WebCryptoKeyAlgorithm.h" |
| 14 #include "wtf/ArrayBufferContents.h" |
| 15 #include "wtf/HashMap.h" |
| 16 #include "wtf/Noncopyable.h" |
| 17 #include "wtf/Vector.h" |
| 18 #include "wtf/text/WTFString.h" |
| 19 #include <v8.h> |
| 20 |
| 21 namespace WTF { |
| 22 |
| 23 class ArrayBuffer; |
| 24 class ArrayBufferView; |
| 25 |
| 26 } |
| 27 |
| 28 namespace blink { |
| 29 |
| 30 class File; |
| 31 class FileList; |
| 32 |
| 33 namespace SerializedScriptValueInternal { |
| 34 |
| 35 typedef Vector<WTF::ArrayBufferContents, 1> ArrayBufferContentsArray; |
| 36 |
| 37 // V8ObjectMap is a map from V8 objects to arbitrary values of type T. |
| 38 // V8 objects (or handles to V8 objects) cannot be used as keys in ordinary wtf:
:HashMaps; |
| 39 // this class should be used instead. GCObject must be a subtype of v8::Object. |
| 40 // Suggested usage: |
| 41 // V8ObjectMap<v8::Object, int> map; |
| 42 // v8::Handle<v8::Object> obj = ...; |
| 43 // map.set(obj, 42); |
| 44 template<typename GCObject, typename T> |
| 45 class V8ObjectMap { |
| 46 public: |
| 47 bool contains(const v8::Handle<GCObject>& handle) |
| 48 { |
| 49 return m_map.contains(*handle); |
| 50 } |
| 51 |
| 52 bool tryGet(const v8::Handle<GCObject>& handle, T* valueOut) |
| 53 { |
| 54 typename HandleToT::iterator result = m_map.find(*handle); |
| 55 if (result != m_map.end()) { |
| 56 *valueOut = result->value; |
| 57 return true; |
| 58 } |
| 59 return false; |
| 60 } |
| 61 |
| 62 void set(const v8::Handle<GCObject>& handle, const T& value) |
| 63 { |
| 64 m_map.set(*handle, value); |
| 65 } |
| 66 |
| 67 private: |
| 68 // This implementation uses GetIdentityHash(), which sets a hidden property
on the object containing |
| 69 // a random integer (or returns the one that had been previously set). This
ensures that the table |
| 70 // never needs to be rebuilt across garbage collections at the expense of do
ing additional allocation |
| 71 // and making more round trips into V8. Note that since GetIdentityHash() is
defined only on |
| 72 // v8::Objects, this V8ObjectMap cannot be used to map v8::Strings to T (bec
ause the public V8 API |
| 73 // considers a v8::String to be a v8::Primitive). |
| 74 |
| 75 // If V8 exposes a way to get at the address of the object held by a handle,
then we can produce |
| 76 // an alternate implementation that does not need to do any V8-side allocati
on; however, it will |
| 77 // need to rehash after every garbage collection because a key object may ha
ve been moved. |
| 78 template<typename G> |
| 79 struct V8HandlePtrHash { |
| 80 static v8::Handle<G> unsafeHandleFromRawValue(const G* value) |
| 81 { |
| 82 const v8::Handle<G>* handle = reinterpret_cast<const v8::Handle<G>*>
(&value); |
| 83 return *handle; |
| 84 } |
| 85 |
| 86 static unsigned hash(const G* key) |
| 87 { |
| 88 return static_cast<unsigned>(unsafeHandleFromRawValue(key)->GetIdent
ityHash()); |
| 89 } |
| 90 static bool equal(const G* a, const G* b) |
| 91 { |
| 92 return unsafeHandleFromRawValue(a) == unsafeHandleFromRawValue(b); |
| 93 } |
| 94 // For HashArg. |
| 95 static const bool safeToCompareToEmptyOrDeleted = false; |
| 96 }; |
| 97 |
| 98 typedef WTF::HashMap<GCObject*, T, V8HandlePtrHash<GCObject> > HandleToT; |
| 99 HandleToT m_map; |
| 100 }; |
| 101 |
| 102 // Writer is responsible for serializing primitive types and storing |
| 103 // information used to reconstruct composite types. |
| 104 class Writer { |
| 105 STACK_ALLOCATED(); |
| 106 WTF_MAKE_NONCOPYABLE(Writer); |
| 107 public: |
| 108 typedef UChar BufferValueType; |
| 109 |
| 110 Writer() |
| 111 : m_position(0) |
| 112 { |
| 113 } |
| 114 |
| 115 // Write functions for primitive types. |
| 116 |
| 117 void writeUndefined(); |
| 118 void writeNull(); |
| 119 void writeTrue(); |
| 120 void writeFalse(); |
| 121 void writeBooleanObject(bool value); |
| 122 void writeOneByteString(v8::Handle<v8::String>&); |
| 123 void writeUCharString(v8::Handle<v8::String>&); |
| 124 void writeStringObject(const char* data, int length); |
| 125 void writeWebCoreString(const String&); |
| 126 void writeVersion(); |
| 127 void writeInt32(int32_t value); |
| 128 void writeUint32(uint32_t value); |
| 129 void writeDate(double numberValue); |
| 130 void writeNumber(double number); |
| 131 void writeNumberObject(double number); |
| 132 void writeBlob(const String& uuid, const String& type, unsigned long long si
ze); |
| 133 void writeBlobIndex(int blobIndex); |
| 134 void writeDOMFileSystem(int type, const String& name, const String& url); |
| 135 void writeFile(const File&); |
| 136 void writeFileIndex(int blobIndex); |
| 137 void writeFileList(const FileList&); |
| 138 void writeFileListIndex(const Vector<int>& blobIndices); |
| 139 bool writeCryptoKey(const WebCryptoKey&); |
| 140 void writeArrayBuffer(const ArrayBuffer&); |
| 141 void writeArrayBufferView(const ArrayBufferView&); |
| 142 void writeImageData(uint32_t width, uint32_t height, const uint8_t* pixelDat
a, uint32_t pixelDataLength); |
| 143 void writeRegExp(v8::Local<v8::String> pattern, v8::RegExp::Flags); |
| 144 void writeTransferredMessagePort(uint32_t index); |
| 145 void writeTransferredArrayBuffer(uint32_t index); |
| 146 void writeObjectReference(uint32_t reference); |
| 147 void writeObject(uint32_t numProperties); |
| 148 void writeSparseArray(uint32_t numProperties, uint32_t length); |
| 149 void writeDenseArray(uint32_t numProperties, uint32_t length); |
| 150 String takeWireString(); |
| 151 void writeReferenceCount(uint32_t numberOfReferences); |
| 152 void writeGenerateFreshObject(); |
| 153 void writeGenerateFreshSparseArray(uint32_t length); |
| 154 void writeGenerateFreshDenseArray(uint32_t length); |
| 155 |
| 156 protected: |
| 157 void doWriteFile(const File&); |
| 158 void doWriteArrayBuffer(const ArrayBuffer&); |
| 159 void doWriteString(const char* data, int length); |
| 160 void doWriteWebCoreString(const String&); |
| 161 void doWriteHmacKey(const WebCryptoKey&); |
| 162 void doWriteAesKey(const WebCryptoKey&); |
| 163 void doWriteRsaHashedKey(const WebCryptoKey&); |
| 164 void doWriteEcKey(const WebCryptoKey&); |
| 165 void doWriteAlgorithmId(WebCryptoAlgorithmId); |
| 166 void doWriteAsymmetricKeyType(WebCryptoKeyType); |
| 167 void doWriteNamedCurve(WebCryptoNamedCurve); |
| 168 void doWriteKeyUsages(const WebCryptoKeyUsageMask usages, bool extractable); |
| 169 int bytesNeededToWireEncode(uint32_t value); |
| 170 |
| 171 template<class T> |
| 172 void doWriteUintHelper(T value) |
| 173 { |
| 174 while (true) { |
| 175 uint8_t b = (value & SerializedScriptValue::varIntMask); |
| 176 value >>= SerializedScriptValue::varIntShift; |
| 177 if (!value) { |
| 178 append(b); |
| 179 break; |
| 180 } |
| 181 append(b | (1 << SerializedScriptValue::varIntShift)); |
| 182 } |
| 183 } |
| 184 |
| 185 void doWriteUint32(uint32_t value); |
| 186 void doWriteUint64(uint64_t value); |
| 187 void doWriteNumber(double number); |
| 188 void append(SerializationTag); |
| 189 void append(uint8_t b); |
| 190 void append(const uint8_t* data, int length); |
| 191 void ensureSpace(unsigned extra); |
| 192 void fillHole(); |
| 193 uint8_t* byteAt(int position); |
| 194 int v8StringWriteOptions(); |
| 195 |
| 196 private: |
| 197 Vector<BufferValueType> m_buffer; |
| 198 unsigned m_position; |
| 199 }; |
| 200 |
| 201 class Serializer { |
| 202 STACK_ALLOCATED(); |
| 203 WTF_MAKE_NONCOPYABLE(Serializer); |
| 204 protected: |
| 205 class StateBase; |
| 206 public: |
| 207 enum Status { |
| 208 Success, |
| 209 InputError, |
| 210 DataCloneError, |
| 211 JSException |
| 212 }; |
| 213 |
| 214 Serializer(Writer&, MessagePortArray* messagePorts, ArrayBufferArray* arrayB
uffers, WebBlobInfoArray*, BlobDataHandleMap& blobDataHandles, v8::TryCatch&, Sc
riptState*); |
| 215 v8::Isolate* isolate() { return m_scriptState->isolate(); } |
| 216 |
| 217 Status serialize(v8::Handle<v8::Value>); |
| 218 String errorMessage() { return m_errorMessage; } |
| 219 |
| 220 // Functions used by serialization states. |
| 221 Serializer::StateBase* doSerialize(v8::Handle<v8::Value>, Serializer::StateB
ase* next); |
| 222 |
| 223 StateBase* doSerializeArrayBuffer(v8::Handle<v8::Value> arrayBuffer, StateBa
se* next); |
| 224 StateBase* checkException(StateBase*); |
| 225 StateBase* writeObject(uint32_t numProperties, StateBase*); |
| 226 StateBase* writeSparseArray(uint32_t numProperties, uint32_t length, StateBa
se*); |
| 227 StateBase* writeDenseArray(uint32_t numProperties, uint32_t length, StateBas
e*); |
| 228 |
| 229 protected: |
| 230 class StateBase { |
| 231 WTF_MAKE_NONCOPYABLE(StateBase); |
| 232 public: |
| 233 virtual ~StateBase() { } |
| 234 |
| 235 // Link to the next state to form a stack. |
| 236 StateBase* nextState() { return m_next; } |
| 237 |
| 238 // Composite object we're processing in this state. |
| 239 v8::Handle<v8::Value> composite() { return m_composite; } |
| 240 |
| 241 // Serializes (a part of) the current composite and returns |
| 242 // the next state to process or null when this is the final |
| 243 // state. |
| 244 virtual StateBase* advance(Serializer&) = 0; |
| 245 |
| 246 protected: |
| 247 StateBase(v8::Handle<v8::Value> composite, StateBase* next) |
| 248 : m_composite(composite) |
| 249 , m_next(next) |
| 250 { |
| 251 } |
| 252 |
| 253 private: |
| 254 v8::Handle<v8::Value> m_composite; |
| 255 StateBase* m_next; |
| 256 }; |
| 257 |
| 258 // Dummy state that is used to signal serialization errors. |
| 259 class ErrorState final : public StateBase { |
| 260 public: |
| 261 ErrorState() |
| 262 : StateBase(v8Undefined(), 0) |
| 263 { |
| 264 } |
| 265 |
| 266 virtual StateBase* advance(Serializer&) override |
| 267 { |
| 268 delete this; |
| 269 return 0; |
| 270 } |
| 271 }; |
| 272 |
| 273 template <typename T> |
| 274 class State : public StateBase { |
| 275 public: |
| 276 v8::Handle<T> composite() { return v8::Handle<T>::Cast(StateBase::compos
ite()); } |
| 277 |
| 278 protected: |
| 279 State(v8::Handle<T> composite, StateBase* next) |
| 280 : StateBase(composite, next) |
| 281 { |
| 282 } |
| 283 }; |
| 284 |
| 285 class AbstractObjectState : public State<v8::Object> { |
| 286 public: |
| 287 AbstractObjectState(v8::Handle<v8::Object> object, StateBase* next) |
| 288 : State<v8::Object>(object, next) |
| 289 , m_index(0) |
| 290 , m_numSerializedProperties(0) |
| 291 , m_nameDone(false) |
| 292 { |
| 293 } |
| 294 |
| 295 protected: |
| 296 virtual StateBase* objectDone(unsigned numProperties, Serializer&) = 0; |
| 297 |
| 298 StateBase* serializeProperties(bool ignoreIndexed, Serializer&); |
| 299 v8::Local<v8::Array> m_propertyNames; |
| 300 |
| 301 private: |
| 302 v8::Local<v8::Value> m_propertyName; |
| 303 unsigned m_index; |
| 304 unsigned m_numSerializedProperties; |
| 305 bool m_nameDone; |
| 306 }; |
| 307 |
| 308 class ObjectState final : public AbstractObjectState { |
| 309 public: |
| 310 ObjectState(v8::Handle<v8::Object> object, StateBase* next) |
| 311 : AbstractObjectState(object, next) |
| 312 { |
| 313 } |
| 314 |
| 315 virtual StateBase* advance(Serializer&) override; |
| 316 |
| 317 protected: |
| 318 virtual StateBase* objectDone(unsigned numProperties, Serializer&) overr
ide; |
| 319 }; |
| 320 |
| 321 class DenseArrayState final : public AbstractObjectState { |
| 322 public: |
| 323 DenseArrayState(v8::Handle<v8::Array> array, v8::Handle<v8::Array> prope
rtyNames, StateBase* next, v8::Isolate* isolate) |
| 324 : AbstractObjectState(array, next) |
| 325 , m_arrayIndex(0) |
| 326 , m_arrayLength(array->Length()) |
| 327 { |
| 328 m_propertyNames = v8::Local<v8::Array>::New(isolate, propertyNames); |
| 329 } |
| 330 |
| 331 virtual StateBase* advance(Serializer&) override; |
| 332 |
| 333 protected: |
| 334 virtual StateBase* objectDone(unsigned numProperties, Serializer&) overr
ide; |
| 335 |
| 336 private: |
| 337 uint32_t m_arrayIndex; |
| 338 uint32_t m_arrayLength; |
| 339 }; |
| 340 |
| 341 class SparseArrayState final : public AbstractObjectState { |
| 342 public: |
| 343 SparseArrayState(v8::Handle<v8::Array> array, v8::Handle<v8::Array> prop
ertyNames, StateBase* next, v8::Isolate* isolate) |
| 344 : AbstractObjectState(array, next) |
| 345 { |
| 346 m_propertyNames = v8::Local<v8::Array>::New(isolate, propertyNames); |
| 347 } |
| 348 |
| 349 virtual StateBase* advance(Serializer&) override; |
| 350 |
| 351 protected: |
| 352 virtual StateBase* objectDone(unsigned numProperties, Serializer&) overr
ide; |
| 353 }; |
| 354 |
| 355 private: |
| 356 StateBase* push(StateBase* state) |
| 357 { |
| 358 ASSERT(state); |
| 359 ++m_depth; |
| 360 return checkComposite(state) ? state : handleError(InputError, "Value be
ing cloned is either cyclic or too deeply nested.", state); |
| 361 } |
| 362 |
| 363 StateBase* pop(StateBase* state) |
| 364 { |
| 365 ASSERT(state); |
| 366 --m_depth; |
| 367 StateBase* next = state->nextState(); |
| 368 delete state; |
| 369 return next; |
| 370 } |
| 371 |
| 372 bool checkComposite(StateBase* top); |
| 373 void writeString(v8::Handle<v8::Value>); |
| 374 void writeStringObject(v8::Handle<v8::Value>); |
| 375 void writeNumberObject(v8::Handle<v8::Value>); |
| 376 void writeBooleanObject(v8::Handle<v8::Value>); |
| 377 StateBase* writeBlob(v8::Handle<v8::Value>, StateBase* next); |
| 378 StateBase* writeDOMFileSystem(v8::Handle<v8::Value>, StateBase* next); |
| 379 StateBase* writeFile(v8::Handle<v8::Value>, StateBase* next); |
| 380 StateBase* writeFileList(v8::Handle<v8::Value>, StateBase* next); |
| 381 bool writeCryptoKey(v8::Handle<v8::Value>); |
| 382 void writeImageData(v8::Handle<v8::Value>); |
| 383 void writeRegExp(v8::Handle<v8::Value>); |
| 384 StateBase* writeAndGreyArrayBufferView(v8::Handle<v8::Object>, StateBase* ne
xt); |
| 385 StateBase* writeArrayBuffer(v8::Handle<v8::Value>, StateBase* next); |
| 386 StateBase* writeTransferredArrayBuffer(v8::Handle<v8::Value>, uint32_t index
, StateBase* next); |
| 387 static bool shouldSerializeDensely(uint32_t length, uint32_t propertyCount); |
| 388 |
| 389 StateBase* startArrayState(v8::Handle<v8::Array>, StateBase* next); |
| 390 StateBase* startObjectState(v8::Handle<v8::Object>, StateBase* next); |
| 391 |
| 392 // Marks object as having been visited by the serializer and assigns it a un
ique object reference ID. |
| 393 // An object may only be greyed once. |
| 394 void greyObject(const v8::Handle<v8::Object>&); |
| 395 bool appendBlobInfo(const String& uuid, const String& type, unsigned long lo
ng size, int* index); |
| 396 bool appendFileInfo(const File*, int* index); |
| 397 |
| 398 protected: |
| 399 StateBase* handleError(Status errorStatus, const String& message, StateBase*
); |
| 400 |
| 401 Writer& writer() { return m_writer; } |
| 402 uint32_t nextObjectReference() const { return m_nextObjectReference; } |
| 403 |
| 404 private: |
| 405 RefPtr<ScriptState> m_scriptState; |
| 406 Writer& m_writer; |
| 407 v8::TryCatch& m_tryCatch; |
| 408 int m_depth; |
| 409 Status m_status; |
| 410 String m_errorMessage; |
| 411 typedef V8ObjectMap<v8::Object, uint32_t> ObjectPool; |
| 412 ObjectPool m_objectPool; |
| 413 ObjectPool m_transferredMessagePorts; |
| 414 ObjectPool m_transferredArrayBuffers; |
| 415 uint32_t m_nextObjectReference; |
| 416 WebBlobInfoArray* m_blobInfo; |
| 417 BlobDataHandleMap& m_blobDataHandles; |
| 418 }; |
| 419 |
| 420 // Interface used by Reader to create objects of composite types. |
| 421 class CompositeCreator { |
| 422 STACK_ALLOCATED(); |
| 423 WTF_MAKE_NONCOPYABLE(CompositeCreator); |
| 424 public: |
| 425 CompositeCreator() { } |
| 426 virtual ~CompositeCreator() { } |
| 427 |
| 428 virtual bool consumeTopOfStack(v8::Handle<v8::Value>*) = 0; |
| 429 virtual uint32_t objectReferenceCount() = 0; |
| 430 virtual void pushObjectReference(const v8::Handle<v8::Value>&) = 0; |
| 431 virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Handle<
v8::Value>*) = 0; |
| 432 virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Val
ue>*) = 0; |
| 433 virtual bool tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::Val
ue>*) = 0; |
| 434 virtual bool newSparseArray(uint32_t length) = 0; |
| 435 virtual bool newDenseArray(uint32_t length) = 0; |
| 436 virtual bool newObject() = 0; |
| 437 virtual bool completeObject(uint32_t numProperties, v8::Handle<v8::Value>*)
= 0; |
| 438 virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8
::Handle<v8::Value>*) = 0; |
| 439 virtual bool completeDenseArray(uint32_t numProperties, uint32_t length, v8:
:Handle<v8::Value>*) = 0; |
| 440 }; |
| 441 |
| 442 // Reader is responsible for deserializing primitive types and |
| 443 // restoring information about saved objects of composite types. |
| 444 class Reader { |
| 445 STACK_ALLOCATED(); |
| 446 WTF_MAKE_NONCOPYABLE(Reader); |
| 447 public: |
| 448 Reader(const uint8_t* buffer, int length, const WebBlobInfoArray* blobInfo,
BlobDataHandleMap& blobDataHandles, ScriptState* scriptState) |
| 449 : m_scriptState(scriptState) |
| 450 , m_buffer(buffer) |
| 451 , m_length(length) |
| 452 , m_position(0) |
| 453 , m_version(0) |
| 454 , m_blobInfo(blobInfo) |
| 455 , m_blobDataHandles(blobDataHandles) |
| 456 { |
| 457 ASSERT(!(reinterpret_cast<size_t>(buffer) & 1)); |
| 458 ASSERT(length >= 0); |
| 459 } |
| 460 |
| 461 bool isEof() const { return m_position >= m_length; } |
| 462 |
| 463 ScriptState* scriptState() const { return m_scriptState.get(); } |
| 464 |
| 465 protected: |
| 466 v8::Isolate* isolate() const { return m_scriptState->isolate(); } |
| 467 unsigned length() const { return m_length; } |
| 468 unsigned position() const { return m_position; } |
| 469 |
| 470 const uint8_t* allocate(uint32_t size) |
| 471 { |
| 472 const uint8_t* allocated = m_buffer + m_position; |
| 473 m_position += size; |
| 474 return allocated; |
| 475 } |
| 476 |
| 477 public: |
| 478 bool read(v8::Handle<v8::Value>*, CompositeCreator&); |
| 479 bool readVersion(uint32_t& version); |
| 480 void setVersion(uint32_t); |
| 481 |
| 482 private: |
| 483 bool readTag(SerializationTag*); |
| 484 bool readWebCoreString(String*); |
| 485 bool readUint32(v8::Handle<v8::Value>*); |
| 486 void undoReadTag(); |
| 487 bool readArrayBufferViewSubTag(ArrayBufferViewSubTag*); |
| 488 bool readString(v8::Handle<v8::Value>*); |
| 489 bool readUCharString(v8::Handle<v8::Value>*); |
| 490 bool readStringObject(v8::Handle<v8::Value>*); |
| 491 bool readInt32(v8::Handle<v8::Value>*); |
| 492 bool readDate(v8::Handle<v8::Value>*); |
| 493 bool readNumber(v8::Handle<v8::Value>*); |
| 494 bool readNumberObject(v8::Handle<v8::Value>*); |
| 495 bool readImageData(v8::Handle<v8::Value>*); |
| 496 PassRefPtr<ArrayBuffer> doReadArrayBuffer(); |
| 497 bool readArrayBuffer(v8::Handle<v8::Value>*); |
| 498 bool readArrayBufferView(v8::Handle<v8::Value>*, CompositeCreator&); |
| 499 bool readRegExp(v8::Handle<v8::Value>*); |
| 500 bool readBlob(v8::Handle<v8::Value>*, bool isIndexed); |
| 501 bool readDOMFileSystem(v8::Handle<v8::Value>*); |
| 502 bool readFile(v8::Handle<v8::Value>*, bool isIndexed); |
| 503 bool readFileList(v8::Handle<v8::Value>*, bool isIndexed); |
| 504 bool readCryptoKey(v8::Handle<v8::Value>*); |
| 505 File* readFileHelper(); |
| 506 File* readFileIndexHelper(); |
| 507 |
| 508 template<class T> |
| 509 bool doReadUintHelper(T* value) |
| 510 { |
| 511 *value = 0; |
| 512 uint8_t currentByte; |
| 513 int shift = 0; |
| 514 do { |
| 515 if (m_position >= m_length) |
| 516 return false; |
| 517 currentByte = m_buffer[m_position++]; |
| 518 *value |= ((currentByte & SerializedScriptValue::varIntMask) << shif
t); |
| 519 shift += SerializedScriptValue::varIntShift; |
| 520 } while (currentByte & (1 << SerializedScriptValue::varIntShift)); |
| 521 return true; |
| 522 } |
| 523 |
| 524 bool doReadUint32(uint32_t* value); |
| 525 bool doReadUint64(uint64_t* value); |
| 526 bool doReadNumber(double* number); |
| 527 PassRefPtr<BlobDataHandle> getOrCreateBlobDataHandle(const String& uuid, con
st String& type, long long size = -1); |
| 528 bool doReadHmacKey(WebCryptoKeyAlgorithm&, WebCryptoKeyType&); |
| 529 bool doReadAesKey(WebCryptoKeyAlgorithm&, WebCryptoKeyType&); |
| 530 bool doReadRsaHashedKey(WebCryptoKeyAlgorithm&, WebCryptoKeyType&); |
| 531 bool doReadEcKey(WebCryptoKeyAlgorithm&, WebCryptoKeyType&); |
| 532 bool doReadAlgorithmId(WebCryptoAlgorithmId&); |
| 533 bool doReadAsymmetricKeyType(WebCryptoKeyType&); |
| 534 bool doReadNamedCurve(WebCryptoNamedCurve&); |
| 535 bool doReadKeyUsages(WebCryptoKeyUsageMask& usages, bool& extractable); |
| 536 |
| 537 private: |
| 538 RefPtr<ScriptState> m_scriptState; |
| 539 const uint8_t* m_buffer; |
| 540 const unsigned m_length; |
| 541 unsigned m_position; |
| 542 uint32_t m_version; |
| 543 const WebBlobInfoArray* m_blobInfo; |
| 544 const BlobDataHandleMap& m_blobDataHandles; |
| 545 }; |
| 546 |
| 547 class Deserializer : public CompositeCreator { |
| 548 STACK_ALLOCATED(); |
| 549 WTF_MAKE_NONCOPYABLE(Deserializer); |
| 550 public: |
| 551 Deserializer(Reader& reader, MessagePortArray* messagePorts, ArrayBufferCont
entsArray* arrayBufferContents) |
| 552 : m_reader(reader) |
| 553 , m_transferredMessagePorts(messagePorts) |
| 554 , m_arrayBufferContents(arrayBufferContents) |
| 555 , m_arrayBuffers(arrayBufferContents ? arrayBufferContents->size() : 0) |
| 556 , m_version(0) |
| 557 { |
| 558 } |
| 559 |
| 560 v8::Handle<v8::Value> deserialize(); |
| 561 virtual bool newSparseArray(uint32_t) override; |
| 562 virtual bool newDenseArray(uint32_t length) override; |
| 563 virtual bool consumeTopOfStack(v8::Handle<v8::Value>*) override; |
| 564 virtual bool newObject() override; |
| 565 virtual bool completeObject(uint32_t numProperties, v8::Handle<v8::Value>*)
override; |
| 566 virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8
::Handle<v8::Value>*) override; |
| 567 virtual bool completeDenseArray(uint32_t numProperties, uint32_t length, v8:
:Handle<v8::Value>*) override; |
| 568 virtual void pushObjectReference(const v8::Handle<v8::Value>&) override; |
| 569 virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Val
ue>*) override; |
| 570 virtual bool tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::Val
ue>*) override; |
| 571 virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Handle<
v8::Value>*) override; |
| 572 virtual uint32_t objectReferenceCount() override; |
| 573 |
| 574 protected: |
| 575 Reader& reader() { return m_reader; } |
| 576 bool read(v8::Local<v8::Value>*); |
| 577 |
| 578 private: |
| 579 bool initializeObject(v8::Handle<v8::Object>, uint32_t numProperties, v8::Ha
ndle<v8::Value>*); |
| 580 bool doDeserialize(); |
| 581 void push(v8::Local<v8::Value> value) { m_stack.append(value); }; |
| 582 void pop(unsigned length) |
| 583 { |
| 584 ASSERT(length <= m_stack.size()); |
| 585 m_stack.shrink(m_stack.size() - length); |
| 586 } |
| 587 unsigned stackDepth() const { return m_stack.size(); } |
| 588 |
| 589 v8::Local<v8::Value> element(unsigned index); |
| 590 void openComposite(const v8::Local<v8::Value>&); |
| 591 bool closeComposite(v8::Handle<v8::Value>*); |
| 592 |
| 593 Reader& m_reader; |
| 594 Vector<v8::Local<v8::Value> > m_stack; |
| 595 Vector<v8::Handle<v8::Value> > m_objectPool; |
| 596 Vector<uint32_t> m_openCompositeReferenceStack; |
| 597 RawPtrWillBeMember<MessagePortArray> m_transferredMessagePorts; |
| 598 ArrayBufferContentsArray* m_arrayBufferContents; |
| 599 Vector<v8::Handle<v8::Object> > m_arrayBuffers; |
| 600 uint32_t m_version; |
| 601 }; |
| 602 |
| 603 } // namespace SerializedScriptValueInternal |
| 604 |
| 605 } // namespace blink |
| 606 |
| 607 #endif // ScriptValueSerializer_h |
OLD | NEW |