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