| Index: Source/bindings/v8/SerializedScriptValue.cpp
|
| diff --git a/Source/bindings/v8/SerializedScriptValue.cpp b/Source/bindings/v8/SerializedScriptValue.cpp
|
| index de2275a94ef23fc4ef8a78bff899bac666328947..e034c830ec4df0f9ebde381fe49a98b4f2c7598c 100644
|
| --- a/Source/bindings/v8/SerializedScriptValue.cpp
|
| +++ b/Source/bindings/v8/SerializedScriptValue.cpp
|
| @@ -407,6 +407,12 @@ public:
|
| doWriteUint64(size);
|
| }
|
|
|
| + void writeBlob(int blobIndex)
|
| + {
|
| + append(BlobTag);
|
| + doWriteUint32(blobIndex);
|
| + }
|
| +
|
| void writeDOMFileSystem(int type, const String& name, const String& url)
|
| {
|
| append(DOMFileSystemTag);
|
| @@ -423,6 +429,14 @@ public:
|
| doWriteWebCoreString(type);
|
| }
|
|
|
| + void writeFile(int blobIndex)
|
| + {
|
| + append(FileTag);
|
| + doWriteUint32(blobIndex);
|
| + }
|
| +
|
| + // Note: We could dedupe the files in this list, but it's probably
|
| + // pretty rare that there are any duplicates.
|
| void writeFileList(const FileList& fileList)
|
| {
|
| append(FileListTag);
|
| @@ -435,6 +449,16 @@ public:
|
| }
|
| }
|
|
|
| + void writeFileList(const Vector<int>& blobIndices)
|
| + {
|
| + append(FileListTag);
|
| + uint32_t length = blobIndices.size();
|
| + doWriteUint32(length);
|
| + for (unsigned i = 0; i < length; ++i) {
|
| + doWriteUint32(blobIndices[i]);
|
| + }
|
| + }
|
| +
|
| void writeArrayBuffer(const ArrayBuffer& arrayBuffer)
|
| {
|
| append(ArrayBufferTag);
|
| @@ -706,14 +730,14 @@ public:
|
| JSFailure
|
| };
|
|
|
| - Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, Vector<String>& blobURLs, v8::TryCatch& tryCatch, v8::Isolate* isolate)
|
| + Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, Vector<BlobInfo>* blobInfo, v8::TryCatch& tryCatch, v8::Isolate* isolate)
|
| : m_writer(writer)
|
| , m_tryCatch(tryCatch)
|
| , m_depth(0)
|
| , m_execDepth(0)
|
| , m_status(Success)
|
| , m_nextObjectReference(0)
|
| - , m_blobURLs(blobURLs)
|
| + , m_blobInfo(blobInfo)
|
| , m_isolate(isolate)
|
| {
|
| ASSERT(!tryCatch.HasCaught());
|
| @@ -1081,8 +1105,13 @@ private:
|
| Blob* blob = V8Blob::toNative(value.As<v8::Object>());
|
| if (!blob)
|
| return;
|
| - m_writer.writeBlob(blob->url().string(), blob->type(), blob->size());
|
| - m_blobURLs.append(blob->url().string());
|
| + int blobIndex = -1;
|
| + if (appendBlobInfo(blob->url().string(), blob->type(), blob->size(), &blobIndex)) {
|
| + ASSERT(blobIndex >= 0);
|
| + m_writer.writeBlob(blobIndex);
|
| + } else {
|
| + m_writer.writeBlob(blob->url().string(), blob->type(), blob->size());
|
| + }
|
| }
|
|
|
| StateBase* writeDOMFileSystem(v8::Handle<v8::Value> value, StateBase* next)
|
| @@ -1101,8 +1130,13 @@ private:
|
| File* file = V8File::toNative(value.As<v8::Object>());
|
| if (!file)
|
| return;
|
| - m_writer.writeFile(file->path(), file->url().string(), file->type());
|
| - m_blobURLs.append(file->url().string());
|
| + int blobIndex = -1;
|
| + if (appendFileInfo(file->path(), file->name(), file->type(), &blobIndex)) {
|
| + ASSERT(blobIndex >= 0);
|
| + m_writer.writeFile(blobIndex);
|
| + } else {
|
| + m_writer.writeFile(file->path(), file->url().string(), file->type());
|
| + }
|
| }
|
|
|
| void writeFileList(v8::Handle<v8::Value> value)
|
| @@ -1110,10 +1144,24 @@ private:
|
| FileList* fileList = V8FileList::toNative(value.As<v8::Object>());
|
| if (!fileList)
|
| return;
|
| - m_writer.writeFileList(*fileList);
|
| unsigned length = fileList->length();
|
| - for (unsigned i = 0; i < length; ++i)
|
| - m_blobURLs.append(fileList->item(i)->url().string());
|
| + Vector<int> blobIndices;
|
| + bool useBlobIndices = false;
|
| + for (unsigned i = 0; i < length; ++i) {
|
| + int blobIndex = -1;
|
| + const File* file = fileList->item(i);
|
| + if (appendFileInfo(file->path(), file->name(), file->type(), &blobIndex)) {
|
| + ASSERT(!i || useBlobIndices);
|
| + ASSERT(blobIndex >= 0);
|
| + useBlobIndices = true;
|
| + blobIndices.append(blobIndex);
|
| + }
|
| + }
|
| + if (useBlobIndices) {
|
| + m_writer.writeFileList(blobIndices);
|
| + } else {
|
| + m_writer.writeFileList(*fileList);
|
| + }
|
| }
|
|
|
| void writeImageData(v8::Handle<v8::Value> value)
|
| @@ -1222,6 +1270,24 @@ private:
|
| m_objectPool.set(object, objectReference);
|
| }
|
|
|
| + bool appendBlobInfo(const String& url, const String& type, unsigned long long size, int* index)
|
| + {
|
| + if (!m_blobInfo)
|
| + return false;
|
| + *index = m_blobInfo->size();
|
| + m_blobInfo->append(BlobInfo(url, type, size));
|
| + return true;
|
| + }
|
| +
|
| + bool appendFileInfo(const String& filePath, const String& fileName, const String& type, int* index)
|
| + {
|
| + if (!m_blobInfo)
|
| + return false;
|
| + *index = m_blobInfo->size();
|
| + m_blobInfo->append(BlobInfo(filePath, fileName, type));
|
| + return true;
|
| + }
|
| +
|
| Writer& m_writer;
|
| v8::TryCatch& m_tryCatch;
|
| int m_depth;
|
| @@ -1232,7 +1298,7 @@ private:
|
| ObjectPool m_transferredMessagePorts;
|
| ObjectPool m_transferredArrayBuffers;
|
| uint32_t m_nextObjectReference;
|
| - Vector<String>& m_blobURLs;
|
| + Vector<BlobInfo>* m_blobInfo;
|
| v8::Isolate* m_isolate;
|
| };
|
|
|
| @@ -1342,12 +1408,13 @@ public:
|
| // restoring information about saved objects of composite types.
|
| class Reader {
|
| public:
|
| - Reader(const uint8_t* buffer, int length, v8::Isolate* isolate)
|
| + Reader(const uint8_t* buffer, int length, v8::Isolate* isolate, const Vector<BlobInfo>* blobInfo)
|
| : m_buffer(buffer)
|
| , m_length(length)
|
| , m_position(0)
|
| , m_version(0)
|
| , m_isolate(isolate)
|
| + , m_blobInfo(blobInfo)
|
| {
|
| ASSERT(!(reinterpret_cast<size_t>(buffer) & 1));
|
| ASSERT(length >= 0);
|
| @@ -1861,14 +1928,24 @@ private:
|
| String url;
|
| String type;
|
| uint64_t size;
|
| - if (!readWebCoreString(&url))
|
| - return false;
|
| - if (!readWebCoreString(&type))
|
| - return false;
|
| - if (!doReadUint64(&size))
|
| - return false;
|
| - PassRefPtr<Blob> blob = Blob::create(KURL(ParsedURLString, url), type, size);
|
| - *value = toV8(blob, v8::Handle<v8::Object>(), m_isolate);
|
| + if (m_blobInfo) {
|
| + uint32_t index;
|
| + if (!doReadUint32(&index) || index >= m_blobInfo->size())
|
| + return false;
|
| + const BlobInfo& info = (*m_blobInfo)[index];
|
| + url = info.url();
|
| + type = info.type();
|
| + size = info.size();
|
| + } else {
|
| + if (!readWebCoreString(&url))
|
| + return false;
|
| + if (!readWebCoreString(&type))
|
| + return false;
|
| + if (!doReadUint64(&size))
|
| + return false;
|
| + }
|
| + RefPtr<Blob> blob = Blob::create(KURL(ParsedURLString, url), type, size);
|
| + *value = toV8(blob.release(), v8::Handle<v8::Object>(), m_isolate);
|
| return true;
|
| }
|
|
|
| @@ -1888,19 +1965,36 @@ private:
|
| return true;
|
| }
|
|
|
| - bool readFile(v8::Handle<v8::Value>* value)
|
| + PassRefPtr<File> readSingleFile()
|
| {
|
| + RefPtr<File> file;
|
| + if (m_blobInfo) {
|
| + uint32_t index;
|
| + if (!doReadUint32(&index) || index >= m_blobInfo->size())
|
| + return file;
|
| + const BlobInfo& info = (*m_blobInfo)[index];
|
| + file = File::create(info.filePath(), info.fileName(), KURL(ParsedURLString, info.url()), info.type(), info.lastModified(), info.size());
|
| + return file;
|
| + }
|
| String path;
|
| String url;
|
| String type;
|
| if (!readWebCoreString(&path))
|
| - return false;
|
| + return file;
|
| if (!readWebCoreString(&url))
|
| - return false;
|
| + return file;
|
| if (!readWebCoreString(&type))
|
| + return file;
|
| + return File::create(path, KURL(ParsedURLString, url), type);
|
| + }
|
| +
|
| + bool readFile(v8::Handle<v8::Value>* value)
|
| + {
|
| + RefPtr<File> file = readSingleFile();
|
| + if (!file.get())
|
| return false;
|
| - PassRefPtr<File> file = File::create(path, KURL(ParsedURLString, url), type);
|
| - *value = toV8(file, v8::Handle<v8::Object>(), m_isolate);
|
| +
|
| + *value = toV8(file.release(), v8::Handle<v8::Object>(), m_isolate);
|
| return true;
|
| }
|
|
|
| @@ -1909,20 +2003,14 @@ private:
|
| uint32_t length;
|
| if (!doReadUint32(&length))
|
| return false;
|
| - PassRefPtr<FileList> fileList = FileList::create();
|
| + RefPtr<FileList> fileList = FileList::create();
|
| for (unsigned i = 0; i < length; ++i) {
|
| - String path;
|
| - String urlString;
|
| - String type;
|
| - if (!readWebCoreString(&path))
|
| - return false;
|
| - if (!readWebCoreString(&urlString))
|
| + RefPtr<File> file = readSingleFile();
|
| + if (!file.get())
|
| return false;
|
| - if (!readWebCoreString(&type))
|
| - return false;
|
| - fileList->append(File::create(path, KURL(ParsedURLString, urlString), type));
|
| + fileList->append(file.get());
|
| }
|
| - *value = toV8(fileList, v8::Handle<v8::Object>(), m_isolate);
|
| + *value = toV8(fileList.release(), v8::Handle<v8::Object>(), m_isolate);
|
| return true;
|
| }
|
|
|
| @@ -1967,6 +2055,7 @@ private:
|
| unsigned m_position;
|
| uint32_t m_version;
|
| v8::Isolate* m_isolate;
|
| + const Vector<BlobInfo>* m_blobInfo;
|
| };
|
|
|
|
|
| @@ -2227,21 +2316,31 @@ private:
|
|
|
| } // namespace
|
|
|
| +PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::Value> value, Vector<BlobInfo>* blobInfo, bool& didThrow)
|
| +{
|
| + return create(value, 0, 0, blobInfo, didThrow, v8::Isolate::GetCurrent());
|
| +}
|
| +
|
| PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::Value> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, bool& didThrow, v8::Isolate* isolate)
|
| {
|
| - return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers, didThrow, isolate));
|
| + return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers, 0, didThrow, isolate));
|
| +}
|
| +
|
| +PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::Value> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, Vector<BlobInfo>* blobInfo, bool& didThrow, v8::Isolate* isolate)
|
| +{
|
| + return adoptRef(new SerializedScriptValue(value, messagePorts, arrayBuffers, blobInfo, didThrow, isolate));
|
| }
|
|
|
| PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(v8::Handle<v8::Value> value, v8::Isolate* isolate)
|
| {
|
| bool didThrow;
|
| - return adoptRef(new SerializedScriptValue(value, 0, 0, didThrow, isolate));
|
| + return adoptRef(new SerializedScriptValue(value, 0, 0, 0, didThrow, isolate));
|
| }
|
|
|
| PassRefPtr<SerializedScriptValue> SerializedScriptValue::createAndSwallowExceptions(v8::Handle<v8::Value> value, v8::Isolate* isolate)
|
| {
|
| bool didThrow;
|
| - return adoptRef(new SerializedScriptValue(value, 0, 0, didThrow, isolate, DoNotThrowExceptions));
|
| + return adoptRef(new SerializedScriptValue(value, 0, 0, 0, didThrow, isolate, DoNotThrowExceptions));
|
| }
|
|
|
| PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(const String& data)
|
| @@ -2427,15 +2526,16 @@ PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValu
|
| return contents.release();
|
| }
|
|
|
| -SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, bool& didThrow, v8::Isolate* isolate, ExceptionPolicy policy)
|
| - : m_externallyAllocatedMemory(0)
|
| +SerializedScriptValue::SerializedScriptValue(v8::Handle<v8::Value> value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, Vector<BlobInfo>* blobInfo, bool& didThrow, v8::Isolate* isolate, ExceptionPolicy policy)
|
| + : m_blobInfo(blobInfo)
|
| + , m_externallyAllocatedMemory(0)
|
| {
|
| didThrow = false;
|
| Writer writer(isolate);
|
| Serializer::Status status;
|
| {
|
| v8::TryCatch tryCatch;
|
| - Serializer serializer(writer, messagePorts, arrayBuffers, m_blobURLs, tryCatch, isolate);
|
| + Serializer serializer(writer, messagePorts, arrayBuffers, m_blobInfo, tryCatch, isolate);
|
| status = serializer.serialize(value);
|
| if (status == Serializer::JSException) {
|
| didThrow = true;
|
| @@ -2486,10 +2586,15 @@ SerializedScriptValue::SerializedScriptValue(const String& wireData)
|
|
|
| v8::Handle<v8::Value> SerializedScriptValue::deserialize(MessagePortArray* messagePorts)
|
| {
|
| - return deserialize(v8::Isolate::GetCurrent(), messagePorts);
|
| + return deserialize(v8::Isolate::GetCurrent(), messagePorts, 0);
|
| +}
|
| +
|
| +v8::Handle<v8::Value> SerializedScriptValue::deserialize(const Vector<BlobInfo>* blobInfo)
|
| +{
|
| + return deserialize(v8::Isolate::GetCurrent(), 0, blobInfo);
|
| }
|
|
|
| -v8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, MessagePortArray* messagePorts)
|
| +v8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, MessagePortArray* messagePorts, const Vector<BlobInfo>* blobInfo)
|
| {
|
| if (!m_data.impl())
|
| return v8NullWithCheck(isolate);
|
| @@ -2499,7 +2604,7 @@ v8::Handle<v8::Value> SerializedScriptValue::deserialize(v8::Isolate* isolate, M
|
| // storage. Instead, it should use SharedBuffer or Vector<uint8_t>. The
|
| // information stored in m_data isn't even encoded in UTF-16. Instead,
|
| // unicode characters are encoded as UTF-8 with two code units per UChar.
|
| - Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters16()), 2 * m_data.length(), isolate);
|
| + Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters16()), 2 * m_data.length(), isolate, blobInfo);
|
| Deserializer deserializer(reader, messagePorts, m_arrayBufferContentsArray.get());
|
|
|
| // deserialize() can run arbitrary script (e.g., setters), which could result in |this| being destroyed.
|
|
|