Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 234 { | 234 { |
| 235 ASSERT(depth >= 0); | 235 ASSERT(depth >= 0); |
| 236 // Since we are not required to spot the cycle as soon as it | 236 // Since we are not required to spot the cycle as soon as it |
| 237 // happens we can check for cycles only when the current depth | 237 // happens we can check for cycles only when the current depth |
| 238 // is a power of two. | 238 // is a power of two. |
| 239 return !(depth & (depth - 1)); | 239 return !(depth & (depth - 1)); |
| 240 } | 240 } |
| 241 | 241 |
| 242 // Increment this for each incompatible change to the wire format. | 242 // Increment this for each incompatible change to the wire format. |
| 243 // Version 2: Added StringUCharTag for UChar v8 strings. | 243 // Version 2: Added StringUCharTag for UChar v8 strings. |
| 244 static const uint32_t wireFormatVersion = 2; | 244 // Version 3: Use blob uuids instead of urls. |
| 245 static const uint32_t wireFormatVersion = 3; | |
|
jsbell
2013/09/26 18:00:36
As an aside, we have a copy of this value living o
michaeln
2013/09/30 20:50:24
i'll sync up with the changes to fix that (thnx fo
| |
| 245 | 246 |
| 246 static const int maxDepth = 20000; | 247 static const int maxDepth = 20000; |
| 247 | 248 |
| 248 // VarInt encoding constants. | 249 // VarInt encoding constants. |
| 249 static const int varIntShift = 7; | 250 static const int varIntShift = 7; |
| 250 static const int varIntMask = (1 << varIntShift) - 1; | 251 static const int varIntMask = (1 << varIntShift) - 1; |
| 251 | 252 |
| 252 // ZigZag encoding helps VarInt encoding stay small for negative | 253 // ZigZag encoding helps VarInt encoding stay small for negative |
| 253 // numbers with small absolute values. | 254 // numbers with small absolute values. |
| 254 class ZigZag { | 255 class ZigZag { |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 392 append(NumberTag); | 393 append(NumberTag); |
| 393 doWriteNumber(number); | 394 doWriteNumber(number); |
| 394 } | 395 } |
| 395 | 396 |
| 396 void writeNumberObject(double number) | 397 void writeNumberObject(double number) |
| 397 { | 398 { |
| 398 append(NumberObjectTag); | 399 append(NumberObjectTag); |
| 399 doWriteNumber(number); | 400 doWriteNumber(number); |
| 400 } | 401 } |
| 401 | 402 |
| 402 void writeBlob(const String& url, const String& type, unsigned long long siz e) | 403 void writeBlob(const String& uuid, const String& type, unsigned long long si ze) |
| 403 { | 404 { |
| 404 append(BlobTag); | 405 append(BlobTag); |
| 405 doWriteWebCoreString(url); | 406 doWriteWebCoreString(uuid); |
| 406 doWriteWebCoreString(type); | 407 doWriteWebCoreString(type); |
| 407 doWriteUint64(size); | 408 doWriteUint64(size); |
| 408 } | 409 } |
| 409 | 410 |
| 410 void writeDOMFileSystem(int type, const String& name, const String& url) | 411 void writeDOMFileSystem(int type, const String& name, const String& url) |
| 411 { | 412 { |
| 412 append(DOMFileSystemTag); | 413 append(DOMFileSystemTag); |
| 413 doWriteUint32(type); | 414 doWriteUint32(type); |
| 414 doWriteWebCoreString(name); | 415 doWriteWebCoreString(name); |
| 415 doWriteWebCoreString(url); | 416 doWriteWebCoreString(url); |
| 416 } | 417 } |
| 417 | 418 |
| 418 void writeFile(const String& path, const String& url, const String& type) | 419 void writeFile(const File& file) |
| 419 { | 420 { |
| 420 append(FileTag); | 421 append(FileTag); |
| 421 doWriteWebCoreString(path); | 422 doWriteFile(file); |
| 422 doWriteWebCoreString(url); | |
| 423 doWriteWebCoreString(type); | |
| 424 } | 423 } |
| 425 | 424 |
| 426 void writeFileList(const FileList& fileList) | 425 void writeFileList(const FileList& fileList) |
| 427 { | 426 { |
| 428 append(FileListTag); | 427 append(FileListTag); |
| 429 uint32_t length = fileList.length(); | 428 uint32_t length = fileList.length(); |
| 430 doWriteUint32(length); | 429 doWriteUint32(length); |
| 431 for (unsigned i = 0; i < length; ++i) { | 430 for (unsigned i = 0; i < length; ++i) |
| 432 doWriteWebCoreString(fileList.item(i)->path()); | 431 doWriteFile(*fileList.item(i)); |
| 433 doWriteWebCoreString(fileList.item(i)->url().string()); | |
| 434 doWriteWebCoreString(fileList.item(i)->type()); | |
| 435 } | |
| 436 } | 432 } |
| 437 | 433 |
| 438 void writeArrayBuffer(const ArrayBuffer& arrayBuffer) | 434 void writeArrayBuffer(const ArrayBuffer& arrayBuffer) |
| 439 { | 435 { |
| 440 append(ArrayBufferTag); | 436 append(ArrayBufferTag); |
| 441 doWriteArrayBuffer(arrayBuffer); | 437 doWriteArrayBuffer(arrayBuffer); |
| 442 } | 438 } |
| 443 | 439 |
| 444 void writeArrayBufferView(const ArrayBufferView& arrayBufferView) | 440 void writeArrayBufferView(const ArrayBufferView& arrayBufferView) |
| 445 { | 441 { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 560 | 556 |
| 561 void writeGenerateFreshDenseArray(uint32_t length) | 557 void writeGenerateFreshDenseArray(uint32_t length) |
| 562 { | 558 { |
| 563 append(GenerateFreshDenseArrayTag); | 559 append(GenerateFreshDenseArrayTag); |
| 564 doWriteUint32(length); | 560 doWriteUint32(length); |
| 565 } | 561 } |
| 566 | 562 |
| 567 v8::Isolate* getIsolate() { return m_isolate; } | 563 v8::Isolate* getIsolate() { return m_isolate; } |
| 568 | 564 |
| 569 private: | 565 private: |
| 566 void doWriteFile(const File& file) | |
| 567 { | |
| 568 doWriteWebCoreString(file.path()); | |
| 569 doWriteWebCoreString(file.uuid()); | |
| 570 doWriteWebCoreString(file.type()); | |
| 571 } | |
| 572 | |
| 570 void doWriteArrayBuffer(const ArrayBuffer& arrayBuffer) | 573 void doWriteArrayBuffer(const ArrayBuffer& arrayBuffer) |
| 571 { | 574 { |
| 572 uint32_t byteLength = arrayBuffer.byteLength(); | 575 uint32_t byteLength = arrayBuffer.byteLength(); |
| 573 doWriteUint32(byteLength); | 576 doWriteUint32(byteLength); |
| 574 append(static_cast<const uint8_t*>(arrayBuffer.data()), byteLength); | 577 append(static_cast<const uint8_t*>(arrayBuffer.data()), byteLength); |
| 575 } | 578 } |
| 576 | 579 |
| 577 void doWriteString(const char* data, int length) | 580 void doWriteString(const char* data, int length) |
| 578 { | 581 { |
| 579 doWriteUint32(static_cast<uint32_t>(length)); | 582 doWriteUint32(static_cast<uint32_t>(length)); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 699 public: | 702 public: |
| 700 enum Status { | 703 enum Status { |
| 701 Success, | 704 Success, |
| 702 InputError, | 705 InputError, |
| 703 DataCloneError, | 706 DataCloneError, |
| 704 InvalidStateError, | 707 InvalidStateError, |
| 705 JSException, | 708 JSException, |
| 706 JSFailure | 709 JSFailure |
| 707 }; | 710 }; |
| 708 | 711 |
| 709 Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, Vector<String>& blobURLs, v8::TryCatch& tryCatch, v8::Isolate* is olate) | 712 Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, v8::I solate* isolate) |
| 710 : m_writer(writer) | 713 : m_writer(writer) |
| 711 , m_tryCatch(tryCatch) | 714 , m_tryCatch(tryCatch) |
| 712 , m_depth(0) | 715 , m_depth(0) |
| 713 , m_execDepth(0) | 716 , m_execDepth(0) |
| 714 , m_status(Success) | 717 , m_status(Success) |
| 715 , m_nextObjectReference(0) | 718 , m_nextObjectReference(0) |
| 716 , m_blobURLs(blobURLs) | 719 , m_blobDataHandles(blobDataHandles) |
| 717 , m_isolate(isolate) | 720 , m_isolate(isolate) |
| 718 { | 721 { |
| 719 ASSERT(!tryCatch.HasCaught()); | 722 ASSERT(!tryCatch.HasCaught()); |
| 720 if (messagePorts) { | 723 if (messagePorts) { |
| 721 for (size_t i = 0; i < messagePorts->size(); i++) | 724 for (size_t i = 0; i < messagePorts->size(); i++) |
| 722 m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get (), m_writer.getIsolate()), i); | 725 m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get (), m_writer.getIsolate()), i); |
| 723 } | 726 } |
| 724 if (arrayBuffers) { | 727 if (arrayBuffers) { |
| 725 for (size_t i = 0; i < arrayBuffers->size(); i++) { | 728 for (size_t i = 0; i < arrayBuffers->size(); i++) { |
| 726 v8::Handle<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers-> at(i).get(), m_writer.getIsolate()); | 729 v8::Handle<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers-> at(i).get(), m_writer.getIsolate()); |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1074 { | 1077 { |
| 1075 v8::Handle<v8::BooleanObject> booleanObject = value.As<v8::BooleanObject >(); | 1078 v8::Handle<v8::BooleanObject> booleanObject = value.As<v8::BooleanObject >(); |
| 1076 m_writer.writeBooleanObject(booleanObject->BooleanValue()); | 1079 m_writer.writeBooleanObject(booleanObject->BooleanValue()); |
| 1077 } | 1080 } |
| 1078 | 1081 |
| 1079 void writeBlob(v8::Handle<v8::Value> value) | 1082 void writeBlob(v8::Handle<v8::Value> value) |
| 1080 { | 1083 { |
| 1081 Blob* blob = V8Blob::toNative(value.As<v8::Object>()); | 1084 Blob* blob = V8Blob::toNative(value.As<v8::Object>()); |
| 1082 if (!blob) | 1085 if (!blob) |
| 1083 return; | 1086 return; |
| 1084 m_writer.writeBlob(blob->url().string(), blob->type(), blob->size()); | 1087 m_writer.writeBlob(blob->uuid(), blob->type(), blob->size()); |
| 1085 m_blobURLs.append(blob->url().string()); | 1088 m_blobDataHandles.add(blob->uuid(), blob->blobDataHandle()); |
| 1086 } | 1089 } |
| 1087 | 1090 |
| 1088 StateBase* writeDOMFileSystem(v8::Handle<v8::Value> value, StateBase* next) | 1091 StateBase* writeDOMFileSystem(v8::Handle<v8::Value> value, StateBase* next) |
| 1089 { | 1092 { |
| 1090 DOMFileSystem* fs = V8DOMFileSystem::toNative(value.As<v8::Object>()); | 1093 DOMFileSystem* fs = V8DOMFileSystem::toNative(value.As<v8::Object>()); |
| 1091 if (!fs) | 1094 if (!fs) |
| 1092 return 0; | 1095 return 0; |
| 1093 if (!fs->clonable()) | 1096 if (!fs->clonable()) |
| 1094 return handleError(DataCloneError, next); | 1097 return handleError(DataCloneError, next); |
| 1095 m_writer.writeDOMFileSystem(fs->type(), fs->name(), fs->rootURL().string ()); | 1098 m_writer.writeDOMFileSystem(fs->type(), fs->name(), fs->rootURL().string ()); |
| 1096 return 0; | 1099 return 0; |
| 1097 } | 1100 } |
| 1098 | 1101 |
| 1099 void writeFile(v8::Handle<v8::Value> value) | 1102 void writeFile(v8::Handle<v8::Value> value) |
| 1100 { | 1103 { |
| 1101 File* file = V8File::toNative(value.As<v8::Object>()); | 1104 File* file = V8File::toNative(value.As<v8::Object>()); |
| 1102 if (!file) | 1105 if (!file) |
| 1103 return; | 1106 return; |
| 1104 m_writer.writeFile(file->path(), file->url().string(), file->type()); | 1107 m_writer.writeFile(*file); |
| 1105 m_blobURLs.append(file->url().string()); | 1108 m_blobDataHandles.add(file->uuid(), file->blobDataHandle()); |
| 1106 } | 1109 } |
| 1107 | 1110 |
| 1108 void writeFileList(v8::Handle<v8::Value> value) | 1111 void writeFileList(v8::Handle<v8::Value> value) |
| 1109 { | 1112 { |
| 1110 FileList* fileList = V8FileList::toNative(value.As<v8::Object>()); | 1113 FileList* fileList = V8FileList::toNative(value.As<v8::Object>()); |
| 1111 if (!fileList) | 1114 if (!fileList) |
| 1112 return; | 1115 return; |
| 1113 m_writer.writeFileList(*fileList); | 1116 m_writer.writeFileList(*fileList); |
| 1114 unsigned length = fileList->length(); | 1117 unsigned length = fileList->length(); |
| 1115 for (unsigned i = 0; i < length; ++i) | 1118 for (unsigned i = 0; i < length; ++i) |
| 1116 m_blobURLs.append(fileList->item(i)->url().string()); | 1119 m_blobDataHandles.add(fileList->item(i)->uuid(), fileList->item(i)-> blobDataHandle()); |
| 1117 } | 1120 } |
| 1118 | 1121 |
| 1119 void writeImageData(v8::Handle<v8::Value> value) | 1122 void writeImageData(v8::Handle<v8::Value> value) |
| 1120 { | 1123 { |
| 1121 ImageData* imageData = V8ImageData::toNative(value.As<v8::Object>()); | 1124 ImageData* imageData = V8ImageData::toNative(value.As<v8::Object>()); |
| 1122 if (!imageData) | 1125 if (!imageData) |
| 1123 return; | 1126 return; |
| 1124 Uint8ClampedArray* pixelArray = imageData->data(); | 1127 Uint8ClampedArray* pixelArray = imageData->data(); |
| 1125 m_writer.writeImageData(imageData->width(), imageData->height(), pixelAr ray->data(), pixelArray->length()); | 1128 m_writer.writeImageData(imageData->width(), imageData->height(), pixelAr ray->data(), pixelArray->length()); |
| 1126 } | 1129 } |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1225 Writer& m_writer; | 1228 Writer& m_writer; |
| 1226 v8::TryCatch& m_tryCatch; | 1229 v8::TryCatch& m_tryCatch; |
| 1227 int m_depth; | 1230 int m_depth; |
| 1228 int m_execDepth; | 1231 int m_execDepth; |
| 1229 Status m_status; | 1232 Status m_status; |
| 1230 typedef V8ObjectMap<v8::Object, uint32_t> ObjectPool; | 1233 typedef V8ObjectMap<v8::Object, uint32_t> ObjectPool; |
| 1231 ObjectPool m_objectPool; | 1234 ObjectPool m_objectPool; |
| 1232 ObjectPool m_transferredMessagePorts; | 1235 ObjectPool m_transferredMessagePorts; |
| 1233 ObjectPool m_transferredArrayBuffers; | 1236 ObjectPool m_transferredArrayBuffers; |
| 1234 uint32_t m_nextObjectReference; | 1237 uint32_t m_nextObjectReference; |
| 1235 Vector<String>& m_blobURLs; | 1238 BlobDataHandleMap& m_blobDataHandles; |
| 1236 v8::Isolate* m_isolate; | 1239 v8::Isolate* m_isolate; |
| 1237 }; | 1240 }; |
| 1238 | 1241 |
| 1239 Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, Stat eBase* next) | 1242 Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, Stat eBase* next) |
| 1240 { | 1243 { |
| 1241 if (m_execDepth + (next ? next->execDepth() : 0) > 1) { | 1244 if (m_execDepth + (next ? next->execDepth() : 0) > 1) { |
| 1242 m_writer.writeNull(); | 1245 m_writer.writeNull(); |
| 1243 return 0; | 1246 return 0; |
| 1244 } | 1247 } |
| 1245 m_writer.writeReferenceCount(m_nextObjectReference); | 1248 m_writer.writeReferenceCount(m_nextObjectReference); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1335 virtual bool newObject() = 0; | 1338 virtual bool newObject() = 0; |
| 1336 virtual bool completeObject(uint32_t numProperties, v8::Handle<v8::Value>*) = 0; | 1339 virtual bool completeObject(uint32_t numProperties, v8::Handle<v8::Value>*) = 0; |
| 1337 virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8 ::Handle<v8::Value>*) = 0; | 1340 virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8 ::Handle<v8::Value>*) = 0; |
| 1338 virtual bool completeDenseArray(uint32_t numProperties, uint32_t length, v8: :Handle<v8::Value>*) = 0; | 1341 virtual bool completeDenseArray(uint32_t numProperties, uint32_t length, v8: :Handle<v8::Value>*) = 0; |
| 1339 }; | 1342 }; |
| 1340 | 1343 |
| 1341 // Reader is responsible for deserializing primitive types and | 1344 // Reader is responsible for deserializing primitive types and |
| 1342 // restoring information about saved objects of composite types. | 1345 // restoring information about saved objects of composite types. |
| 1343 class Reader { | 1346 class Reader { |
| 1344 public: | 1347 public: |
| 1345 Reader(const uint8_t* buffer, int length, v8::Isolate* isolate) | 1348 Reader(const uint8_t* buffer, int length, v8::Isolate* isolate, const BlobD ataHandleMap& blobDataHandles) |
| 1346 : m_buffer(buffer) | 1349 : m_buffer(buffer) |
| 1347 , m_length(length) | 1350 , m_length(length) |
| 1348 , m_position(0) | 1351 , m_position(0) |
| 1349 , m_version(0) | 1352 , m_version(0) |
| 1350 , m_isolate(isolate) | 1353 , m_isolate(isolate) |
| 1354 , m_blobDataHandles(blobDataHandles) | |
| 1351 { | 1355 { |
| 1352 ASSERT(!(reinterpret_cast<size_t>(buffer) & 1)); | 1356 ASSERT(!(reinterpret_cast<size_t>(buffer) & 1)); |
| 1353 ASSERT(length >= 0); | 1357 ASSERT(length >= 0); |
| 1354 } | 1358 } |
| 1355 | 1359 |
| 1356 bool isEof() const { return m_position >= m_length; } | 1360 bool isEof() const { return m_position >= m_length; } |
| 1357 | 1361 |
| 1358 bool read(v8::Handle<v8::Value>* value, CompositeCreator& creator) | 1362 bool read(v8::Handle<v8::Value>* value, CompositeCreator& creator) |
| 1359 { | 1363 { |
| 1360 SerializationTag tag; | 1364 SerializationTag tag; |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1850 return false; | 1854 return false; |
| 1851 uint32_t flags; | 1855 uint32_t flags; |
| 1852 if (!doReadUint32(&flags)) | 1856 if (!doReadUint32(&flags)) |
| 1853 return false; | 1857 return false; |
| 1854 *value = v8::RegExp::New(pattern.As<v8::String>(), static_cast<v8::RegEx p::Flags>(flags)); | 1858 *value = v8::RegExp::New(pattern.As<v8::String>(), static_cast<v8::RegEx p::Flags>(flags)); |
| 1855 return true; | 1859 return true; |
| 1856 } | 1860 } |
| 1857 | 1861 |
| 1858 bool readBlob(v8::Handle<v8::Value>* value) | 1862 bool readBlob(v8::Handle<v8::Value>* value) |
| 1859 { | 1863 { |
| 1860 String url; | 1864 if (m_version < 3) |
| 1865 return false; | |
|
kinuko
2013/09/30 11:31:53
so it's assuming we should always get the same ver
michaeln
2013/09/30 20:50:24
deserialization will fail if we get an older forma
| |
| 1866 String uuid; | |
| 1861 String type; | 1867 String type; |
| 1862 uint64_t size; | 1868 uint64_t size; |
| 1863 if (!readWebCoreString(&url)) | 1869 if (!readWebCoreString(&uuid)) |
| 1864 return false; | 1870 return false; |
| 1865 if (!readWebCoreString(&type)) | 1871 if (!readWebCoreString(&type)) |
| 1866 return false; | 1872 return false; |
| 1867 if (!doReadUint64(&size)) | 1873 if (!doReadUint64(&size)) |
| 1868 return false; | 1874 return false; |
| 1869 PassRefPtr<Blob> blob = Blob::create(KURL(ParsedURLString, url), type, s ize); | 1875 RefPtr<Blob> blob = Blob::create(getOrCreateBlobDataHandle(uuid, type, s ize)); |
| 1870 *value = toV8(blob, v8::Handle<v8::Object>(), m_isolate); | 1876 *value = toV8(blob.release(), v8::Handle<v8::Object>(), m_isolate); |
| 1871 return true; | 1877 return true; |
| 1872 } | 1878 } |
| 1873 | 1879 |
| 1874 bool readDOMFileSystem(v8::Handle<v8::Value>* value) | 1880 bool readDOMFileSystem(v8::Handle<v8::Value>* value) |
| 1875 { | 1881 { |
| 1876 uint32_t type; | 1882 uint32_t type; |
| 1877 String name; | 1883 String name; |
| 1878 String url; | 1884 String url; |
| 1879 if (!doReadUint32(&type)) | 1885 if (!doReadUint32(&type)) |
| 1880 return false; | 1886 return false; |
| 1881 if (!readWebCoreString(&name)) | 1887 if (!readWebCoreString(&name)) |
| 1882 return false; | 1888 return false; |
| 1883 if (!readWebCoreString(&url)) | 1889 if (!readWebCoreString(&url)) |
| 1884 return false; | 1890 return false; |
| 1885 RefPtr<DOMFileSystem> fs = DOMFileSystem::create(getScriptExecutionConte xt(), name, static_cast<WebCore::FileSystemType>(type), KURL(ParsedURLString, ur l)); | 1891 RefPtr<DOMFileSystem> fs = DOMFileSystem::create(getScriptExecutionConte xt(), name, static_cast<WebCore::FileSystemType>(type), KURL(ParsedURLString, ur l)); |
| 1886 *value = toV8(fs.release(), v8::Handle<v8::Object>(), m_isolate); | 1892 *value = toV8(fs.release(), v8::Handle<v8::Object>(), m_isolate); |
| 1887 return true; | 1893 return true; |
| 1888 } | 1894 } |
| 1889 | 1895 |
| 1890 bool readFile(v8::Handle<v8::Value>* value) | 1896 bool readFile(v8::Handle<v8::Value>* value) |
| 1891 { | 1897 { |
| 1892 String path; | 1898 RefPtr<File> file = doReadFileHelper(); |
| 1893 String url; | 1899 if (!file) |
| 1894 String type; | |
| 1895 if (!readWebCoreString(&path)) | |
| 1896 return false; | 1900 return false; |
| 1897 if (!readWebCoreString(&url)) | 1901 *value = toV8(file.release(), v8::Handle<v8::Object>(), m_isolate); |
| 1898 return false; | |
| 1899 if (!readWebCoreString(&type)) | |
| 1900 return false; | |
| 1901 PassRefPtr<File> file = File::create(path, KURL(ParsedURLString, url), t ype); | |
| 1902 *value = toV8(file, v8::Handle<v8::Object>(), m_isolate); | |
| 1903 return true; | 1902 return true; |
| 1904 } | 1903 } |
| 1905 | 1904 |
| 1906 bool readFileList(v8::Handle<v8::Value>* value) | 1905 bool readFileList(v8::Handle<v8::Value>* value) |
| 1907 { | 1906 { |
| 1907 if (m_version < 3) | |
| 1908 return false; | |
| 1908 uint32_t length; | 1909 uint32_t length; |
| 1909 if (!doReadUint32(&length)) | 1910 if (!doReadUint32(&length)) |
| 1910 return false; | 1911 return false; |
| 1911 PassRefPtr<FileList> fileList = FileList::create(); | 1912 RefPtr<FileList> fileList = FileList::create(); |
| 1912 for (unsigned i = 0; i < length; ++i) { | 1913 for (unsigned i = 0; i < length; ++i) |
| 1913 String path; | 1914 fileList->append(doReadFileHelper()); |
| 1914 String urlString; | 1915 *value = toV8(fileList.release(), v8::Handle<v8::Object>(), m_isolate); |
| 1915 String type; | |
| 1916 if (!readWebCoreString(&path)) | |
| 1917 return false; | |
| 1918 if (!readWebCoreString(&urlString)) | |
| 1919 return false; | |
| 1920 if (!readWebCoreString(&type)) | |
| 1921 return false; | |
| 1922 fileList->append(File::create(path, KURL(ParsedURLString, urlString) , type)); | |
| 1923 } | |
| 1924 *value = toV8(fileList, v8::Handle<v8::Object>(), m_isolate); | |
| 1925 return true; | 1916 return true; |
| 1926 } | 1917 } |
| 1927 | 1918 |
| 1919 PassRefPtr<File> doReadFileHelper() | |
| 1920 { | |
| 1921 if (m_version < 3) | |
| 1922 return 0; | |
| 1923 String path; | |
| 1924 String uuid; | |
| 1925 String type; | |
| 1926 if (!readWebCoreString(&path)) | |
| 1927 return 0; | |
| 1928 if (!readWebCoreString(&uuid)) | |
| 1929 return 0; | |
| 1930 if (!readWebCoreString(&type)) | |
| 1931 return 0; | |
| 1932 return File::create(path, getOrCreateBlobDataHandle(uuid, type)); | |
| 1933 } | |
| 1934 | |
| 1928 template<class T> | 1935 template<class T> |
| 1929 bool doReadUintHelper(T* value) | 1936 bool doReadUintHelper(T* value) |
| 1930 { | 1937 { |
| 1931 *value = 0; | 1938 *value = 0; |
| 1932 uint8_t currentByte; | 1939 uint8_t currentByte; |
| 1933 int shift = 0; | 1940 int shift = 0; |
| 1934 do { | 1941 do { |
| 1935 if (m_position >= m_length) | 1942 if (m_position >= m_length) |
| 1936 return false; | 1943 return false; |
| 1937 currentByte = m_buffer[m_position++]; | 1944 currentByte = m_buffer[m_position++]; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1954 bool doReadNumber(double* number) | 1961 bool doReadNumber(double* number) |
| 1955 { | 1962 { |
| 1956 if (m_position + sizeof(double) > m_length) | 1963 if (m_position + sizeof(double) > m_length) |
| 1957 return false; | 1964 return false; |
| 1958 uint8_t* numberAsByteArray = reinterpret_cast<uint8_t*>(number); | 1965 uint8_t* numberAsByteArray = reinterpret_cast<uint8_t*>(number); |
| 1959 for (unsigned i = 0; i < sizeof(double); ++i) | 1966 for (unsigned i = 0; i < sizeof(double); ++i) |
| 1960 numberAsByteArray[i] = m_buffer[m_position++]; | 1967 numberAsByteArray[i] = m_buffer[m_position++]; |
| 1961 return true; | 1968 return true; |
| 1962 } | 1969 } |
| 1963 | 1970 |
| 1971 PassRefPtr<BlobDataHandle> getOrCreateBlobDataHandle(const String& uuid, con st String& type, long long size = -1) | |
| 1972 { | |
| 1973 // The containing ssv may have a BDH for this uuid if this ssv is just b eing | |
| 1974 // passed from main to worker thread (for example). We use those values when creating | |
| 1975 // the new blob instead of cons'ing up a new BDH. | |
| 1976 // | |
| 1977 // FIXME: Maybe we should require that it work that way where the ssv mu st have a BDH for any | |
|
kinuko
2013/09/30 11:31:53
Could we include the bug number to refer this FIXM
michaeln
2013/09/30 20:50:24
Do you think it's a good idea to do whats describe
| |
| 1978 // blobs it comes across during deserialization. Would require callers t o explicitly populate | |
| 1979 // the collection of BDH's for blobs to work, which would encourage life times to be considered | |
| 1980 // when passing ssv's around cross process. At present, we get 'lucky' i n some cases because | |
| 1981 // the blob in the src process happens to still exists at the time the d est process is deserializing. | |
|
kinuko
2013/09/30 11:31:53
nit: exists -> exist
michaeln
2013/09/30 20:50:24
done (or will do on next upload)
| |
| 1982 // For example in sharedWorker.postMesssage(...). | |
| 1983 BlobDataHandleMap::const_iterator it = m_blobDataHandles.find(uuid); | |
| 1984 if (it != m_blobDataHandles.end()) { | |
| 1985 // make assertions about type and size? | |
| 1986 return it->value; | |
| 1987 } | |
| 1988 return BlobDataHandle::create(uuid, type, size); | |
| 1989 } | |
| 1990 | |
| 1964 const uint8_t* m_buffer; | 1991 const uint8_t* m_buffer; |
| 1965 const unsigned m_length; | 1992 const unsigned m_length; |
| 1966 unsigned m_position; | 1993 unsigned m_position; |
| 1967 uint32_t m_version; | 1994 uint32_t m_version; |
| 1968 v8::Isolate* m_isolate; | 1995 v8::Isolate* m_isolate; |
| 1996 const BlobDataHandleMap& m_blobDataHandles; | |
| 1969 }; | 1997 }; |
| 1970 | 1998 |
| 1971 | 1999 |
| 1972 typedef Vector<WTF::ArrayBufferContents, 1> ArrayBufferContentsArray; | 2000 typedef Vector<WTF::ArrayBufferContents, 1> ArrayBufferContentsArray; |
| 1973 | 2001 |
| 1974 class Deserializer : public CompositeCreator { | 2002 class Deserializer : public CompositeCreator { |
| 1975 public: | 2003 public: |
| 1976 Deserializer(Reader& reader, MessagePortArray* messagePorts, ArrayBufferCont entsArray* arrayBufferContents) | 2004 Deserializer(Reader& reader, MessagePortArray* messagePorts, ArrayBufferCont entsArray* arrayBufferContents) |
| 1977 : m_reader(reader) | 2005 : m_reader(reader) |
| 1978 , m_transferredMessagePorts(messagePorts) | 2006 , m_transferredMessagePorts(messagePorts) |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2427 } | 2455 } |
| 2428 | 2456 |
| 2429 SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, Messag ePortArray* messagePorts, ArrayBufferArray* arrayBuffers, bool& didThrow, v8::Is olate* isolate, ExceptionPolicy policy) | 2457 SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, Messag ePortArray* messagePorts, ArrayBufferArray* arrayBuffers, bool& didThrow, v8::Is olate* isolate, ExceptionPolicy policy) |
| 2430 : m_externallyAllocatedMemory(0) | 2458 : m_externallyAllocatedMemory(0) |
| 2431 { | 2459 { |
| 2432 didThrow = false; | 2460 didThrow = false; |
| 2433 Writer writer(isolate); | 2461 Writer writer(isolate); |
| 2434 Serializer::Status status; | 2462 Serializer::Status status; |
| 2435 { | 2463 { |
| 2436 v8::TryCatch tryCatch; | 2464 v8::TryCatch tryCatch; |
| 2437 Serializer serializer(writer, messagePorts, arrayBuffers, m_blobURLs, tr yCatch, isolate); | 2465 Serializer serializer(writer, messagePorts, arrayBuffers, m_blobDataHand les, tryCatch, isolate); |
| 2438 status = serializer.serialize(value); | 2466 status = serializer.serialize(value); |
| 2439 if (status == Serializer::JSException) { | 2467 if (status == Serializer::JSException) { |
| 2440 didThrow = true; | 2468 didThrow = true; |
| 2441 // If there was a JS exception thrown, re-throw it. | 2469 // If there was a JS exception thrown, re-throw it. |
| 2442 if (policy == ThrowExceptions) | 2470 if (policy == ThrowExceptions) |
| 2443 tryCatch.ReThrow(); | 2471 tryCatch.ReThrow(); |
| 2444 return; | 2472 return; |
| 2445 } | 2473 } |
| 2446 } | 2474 } |
| 2447 switch (status) { | 2475 switch (status) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2491 v8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, M essagePortArray* messagePorts) | 2519 v8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, M essagePortArray* messagePorts) |
| 2492 { | 2520 { |
| 2493 if (!m_data.impl()) | 2521 if (!m_data.impl()) |
| 2494 return v8NullWithCheck(isolate); | 2522 return v8NullWithCheck(isolate); |
| 2495 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); | 2523 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); |
| 2496 m_data.ensure16Bit(); | 2524 m_data.ensure16Bit(); |
| 2497 // FIXME: SerializedScriptValue shouldn't use String for its underlying | 2525 // FIXME: SerializedScriptValue shouldn't use String for its underlying |
| 2498 // storage. Instead, it should use SharedBuffer or Vector<uint8_t>. The | 2526 // storage. Instead, it should use SharedBuffer or Vector<uint8_t>. The |
| 2499 // information stored in m_data isn't even encoded in UTF-16. Instead, | 2527 // information stored in m_data isn't even encoded in UTF-16. Instead, |
| 2500 // unicode characters are encoded as UTF-8 with two code units per UChar. | 2528 // unicode characters are encoded as UTF-8 with two code units per UChar. |
| 2501 Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters16() ), 2 * m_data.length(), isolate); | 2529 Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters16() ), 2 * m_data.length(), isolate, m_blobDataHandles); |
| 2502 Deserializer deserializer(reader, messagePorts, m_arrayBufferContentsArray.g et()); | 2530 Deserializer deserializer(reader, messagePorts, m_arrayBufferContentsArray.g et()); |
| 2503 | 2531 |
| 2504 // deserialize() can run arbitrary script (e.g., setters), which could resul t in |this| being destroyed. | 2532 // deserialize() can run arbitrary script (e.g., setters), which could resul t in |this| being destroyed. |
| 2505 // Holding a RefPtr ensures we are alive (along with our internal data) thro ughout the operation. | 2533 // Holding a RefPtr ensures we are alive (along with our internal data) thro ughout the operation. |
| 2506 RefPtr<SerializedScriptValue> protect(this); | 2534 RefPtr<SerializedScriptValue> protect(this); |
| 2507 return deserializer.deserialize(); | 2535 return deserializer.deserialize(); |
| 2508 } | 2536 } |
| 2509 | 2537 |
| 2510 ScriptValue SerializedScriptValue::deserializeForInspector(ScriptState* scriptSt ate) | 2538 ScriptValue SerializedScriptValue::deserializeForInspector(ScriptState* scriptSt ate) |
| 2511 { | 2539 { |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 2534 v8::V8::AdjustAmountOfExternalAllocatedMemory(-m_externallyAllocatedMemo ry); | 2562 v8::V8::AdjustAmountOfExternalAllocatedMemory(-m_externallyAllocatedMemo ry); |
| 2535 } | 2563 } |
| 2536 } | 2564 } |
| 2537 | 2565 |
| 2538 uint32_t SerializedScriptValue::wireFormatVersion() | 2566 uint32_t SerializedScriptValue::wireFormatVersion() |
| 2539 { | 2567 { |
| 2540 return WebCore::wireFormatVersion; | 2568 return WebCore::wireFormatVersion; |
| 2541 } | 2569 } |
| 2542 | 2570 |
| 2543 } // namespace WebCore | 2571 } // namespace WebCore |
| OLD | NEW |