Bug 1264642 - Part 5. Make SerializedStructuredClone{Read,Write}Info use SerializedStructuredCloneBuffer. r=baku
MozReview-Commit-ID: KUz3E5Sw5W3
--- a/dom/indexedDB/ActorsChild.cpp
+++ b/dom/indexedDB/ActorsChild.cpp
@@ -425,18 +425,16 @@ private:
nsresult
GetResult(JSContext* aCx,
StructuredCloneReadInfo* aCloneInfo,
JS::MutableHandle<JS::Value> aResult)
{
bool ok = IDBObjectStore::DeserializeValue(aCx, *aCloneInfo, aResult);
- aCloneInfo->mCloneBuffer.clear();
-
if (NS_WARN_IF(!ok)) {
return NS_ERROR_DOM_DATA_CLONE_ERR;
}
return NS_OK;
}
nsresult
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -14835,38 +14835,38 @@ TransactionBase::VerifyRequestParams(con
RefPtr<FullObjectStoreMetadata> objMetadata =
GetMetadataForObjectStoreId(aParams.objectStoreId());
if (NS_WARN_IF(!objMetadata)) {
ASSERT_UNLESS_FUZZING();
return false;
}
- if (NS_WARN_IF(aParams.cloneInfo().data().IsEmpty())) {
+ if (NS_WARN_IF(!aParams.cloneInfo().data().data.Size())) {
ASSERT_UNLESS_FUZZING();
return false;
}
if (objMetadata->mCommonMetadata.autoIncrement() &&
objMetadata->mCommonMetadata.keyPath().IsValid() &&
aParams.key().IsUnset()) {
const SerializedStructuredCloneWriteInfo cloneInfo = aParams.cloneInfo();
if (NS_WARN_IF(!cloneInfo.offsetToKeyProp())) {
ASSERT_UNLESS_FUZZING();
return false;
}
- if (NS_WARN_IF(cloneInfo.data().Length() < sizeof(uint64_t))) {
+ if (NS_WARN_IF(cloneInfo.data().data.Size() < sizeof(uint64_t))) {
ASSERT_UNLESS_FUZZING();
return false;
}
if (NS_WARN_IF(cloneInfo.offsetToKeyProp() >
- (cloneInfo.data().Length() - sizeof(uint64_t)))) {
+ (cloneInfo.data().data.Size() - sizeof(uint64_t)))) {
ASSERT_UNLESS_FUZZING();
return false;
}
} else if (NS_WARN_IF(aParams.cloneInfo().offsetToKeyProp())) {
ASSERT_UNLESS_FUZZING();
return false;
}
@@ -19060,17 +19060,19 @@ DatabaseOperationBase::GetStructuredClon
char* uncompressedBuffer = reinterpret_cast<char*>(uncompressed.Elements());
if (NS_WARN_IF(!snappy::RawUncompress(compressed, compressedLength,
uncompressedBuffer))) {
return NS_ERROR_FILE_CORRUPTED;
}
- aInfo->mData.SwapElements(uncompressed);
+ if (!aInfo->mData.WriteBytes(uncompressedBuffer, uncompressed.Length())) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
if (!aFileIds.IsVoid()) {
AutoTArray<int64_t, 10> array;
nsresult rv = ConvertFileIdsToArray(aFileIds, array);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -25422,16 +25424,23 @@ ObjectStoreAddOrPutRequestOp::DoDatabase
rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("osid"), osid);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
MOZ_ASSERT(!keyUnset || mMetadata->mCommonMetadata.autoIncrement(),
"Should have key unless autoIncrement");
+ const JSStructuredCloneData& data = mParams.cloneInfo().data().data;
+ size_t cloneDataSize = data.Size();
+ nsCString cloneData;
+ cloneData.SetLength(cloneDataSize);
+ auto iter = data.Iter();
+ data.ReadBytes(iter, cloneData.BeginWriting(), cloneDataSize);
+
int64_t autoIncrementNum = 0;
if (mMetadata->mCommonMetadata.autoIncrement()) {
if (keyUnset) {
autoIncrementNum = mMetadata->mNextAutoIncrementId;
MOZ_ASSERT(autoIncrementNum > 0);
@@ -25443,39 +25452,36 @@ ObjectStoreAddOrPutRequestOp::DoDatabase
} else if (key.IsFloat() &&
key.ToFloat() >= mMetadata->mNextAutoIncrementId) {
autoIncrementNum = floor(key.ToFloat());
}
if (keyUnset && keyPath.IsValid()) {
const SerializedStructuredCloneWriteInfo& cloneInfo = mParams.cloneInfo();
MOZ_ASSERT(cloneInfo.offsetToKeyProp());
- MOZ_ASSERT(cloneInfo.data().Length() > sizeof(uint64_t));
+ MOZ_ASSERT(cloneDataSize > sizeof(uint64_t));
MOZ_ASSERT(cloneInfo.offsetToKeyProp() <=
- (cloneInfo.data().Length() - sizeof(uint64_t)));
+ (cloneDataSize - sizeof(uint64_t)));
// Special case where someone put an object into an autoIncrement'ing
// objectStore with no key in its keyPath set. We needed to figure out
// which row id we would get above before we could set that properly.
- uint8_t* keyPropPointer =
- const_cast<uint8_t*>(cloneInfo.data().Elements() +
- cloneInfo.offsetToKeyProp());
+ char* keyPropPointer = cloneData.BeginWriting() + cloneInfo.offsetToKeyProp();
uint64_t keyPropValue =
ReinterpretDoubleAsUInt64(static_cast<double>(autoIncrementNum));
LittleEndian::writeUint64(keyPropPointer, keyPropValue);
}
}
key.BindToStatement(stmt, NS_LITERAL_CSTRING("key"));
// Compress the bytes before adding into the database.
- const char* uncompressed =
- reinterpret_cast<const char*>(mParams.cloneInfo().data().Elements());
- size_t uncompressedLength = mParams.cloneInfo().data().Length();
+ const char* uncompressed = cloneData.BeginReading();
+ size_t uncompressedLength = cloneDataSize;
// We don't have a smart pointer class that calls free, so we need to
// manage | compressed | manually.
{
size_t compressedLength = snappy::MaxCompressedLength(uncompressedLength);
char* compressed = static_cast<char*>(malloc(compressedLength));
if (NS_WARN_IF(!compressed)) {
@@ -25797,17 +25803,17 @@ nsresult
ObjectStoreGetRequestOp::ConvertResponse(
uint32_t aIndex,
SerializedStructuredCloneReadInfo& aSerializedInfo)
{
MOZ_ASSERT(aIndex < mResponse.Length());
StructuredCloneReadInfo& info = mResponse[aIndex];
- info.mData.SwapElements(aSerializedInfo.data());
+ aSerializedInfo.data().data = Move(info.mData);
FallibleTArray<BlobOrMutableFile> blobs;
nsresult rv = ConvertBlobsToActors(mBackgroundParent,
mDatabase,
info.mFiles,
blobs);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@@ -26520,17 +26526,17 @@ IndexGetRequestOp::GetResponse(RequestRe
for (uint32_t count = mResponse.Length(), index = 0;
index < count;
index++) {
StructuredCloneReadInfo& info = mResponse[index];
SerializedStructuredCloneReadInfo& serializedInfo =
fallibleCloneInfos[index];
- info.mData.SwapElements(serializedInfo.data());
+ serializedInfo.data().data = Move(info.mData);
FallibleTArray<BlobOrMutableFile> blobs;
nsresult rv = ConvertBlobsToActors(mBackgroundParent,
mDatabase,
info.mFiles,
blobs);
if (NS_WARN_IF(NS_FAILED(rv))) {
aResponse = rv;
@@ -26554,17 +26560,17 @@ IndexGetRequestOp::GetResponse(RequestRe
aResponse = IndexGetResponse();
if (!mResponse.IsEmpty()) {
StructuredCloneReadInfo& info = mResponse[0];
SerializedStructuredCloneReadInfo& serializedInfo =
aResponse.get_IndexGetResponse().cloneInfo();
- info.mData.SwapElements(serializedInfo.data());
+ serializedInfo.data().data = Move(info.mData);
FallibleTArray<BlobOrMutableFile> blobs;
nsresult rv =
ConvertBlobsToActors(mBackgroundParent,
mDatabase,
info.mFiles,
blobs);
if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -26868,17 +26874,17 @@ CursorOpBase::PopulateResponseFromStatem
mResponse = nsTArray<ObjectStoreCursorResponse>();
} else {
MOZ_ASSERT(mResponse.type() ==
CursorResponse::TArrayOfObjectStoreCursorResponse);
}
auto& responses = mResponse.get_ArrayOfObjectStoreCursorResponse();
auto& response = *responses.AppendElement();
- response.cloneInfo().data().SwapElements(cloneInfo.mData);
+ response.cloneInfo().data().data = Move(cloneInfo.mData);
response.key() = mCursor->mKey;
mFiles.AppendElement(Move(cloneInfo.mFiles));
break;
}
case OpenCursorParams::TObjectStoreOpenKeyCursorParams: {
MOZ_ASSERT(aInitializeResponse);
@@ -26906,17 +26912,17 @@ CursorOpBase::PopulateResponseFromStatem
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
MOZ_ASSERT(aInitializeResponse);
mResponse = IndexCursorResponse();
auto& response = mResponse.get_IndexCursorResponse();
- response.cloneInfo().data().SwapElements(cloneInfo.mData);
+ response.cloneInfo().data().data = Move(cloneInfo.mData);
response.key() = mCursor->mKey;
response.sortKey() = mCursor->mSortKey;
response.objectKey() = mCursor->mObjectKey;
mFiles.AppendElement(Move(cloneInfo.mFiles));
break;
}
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -862,25 +862,16 @@ CommonStructuredCloneReadCallback(JSCont
return result;
}
return StructuredCloneHolder::ReadFullySerializableObjects(aCx, aReader,
aTag);
}
-// static
-void
-ClearStructuredCloneBuffer(JSAutoStructuredCloneBuffer& aBuffer)
-{
- if (!aBuffer.empty()) {
- aBuffer.clear();
- }
-}
-
} // namespace
const JSClass IDBObjectStore::sDummyPropJSClass = {
"IDBObjectStore Dummy",
0 /* flags */
};
IDBObjectStore::IDBObjectStore(IDBTransaction* aTransaction,
@@ -1037,61 +1028,52 @@ IDBObjectStore::AppendIndexUpdateInfo(
// static
void
IDBObjectStore::ClearCloneReadInfo(StructuredCloneReadInfo& aReadInfo)
{
// This is kind of tricky, we only want to release stuff on the main thread,
// but we can end up being called on other threads if we have already been
// cleared on the main thread.
- if (aReadInfo.mCloneBuffer.empty() && !aReadInfo.mFiles.Length()) {
+ if (!aReadInfo.mFiles.Length()) {
return;
}
- ClearStructuredCloneBuffer(aReadInfo.mCloneBuffer);
aReadInfo.mFiles.Clear();
}
// static
bool
IDBObjectStore::DeserializeValue(JSContext* aCx,
StructuredCloneReadInfo& aCloneReadInfo,
JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(aCx);
- if (aCloneReadInfo.mData.IsEmpty()) {
+ if (!aCloneReadInfo.mData.Size()) {
aValue.setUndefined();
return true;
}
- char* data = reinterpret_cast<char*>(aCloneReadInfo.mData.Elements());
- size_t dataLen = aCloneReadInfo.mData.Length();
-
- MOZ_ASSERT(!(dataLen % sizeof(uint64_t)));
+ MOZ_ASSERT(!(aCloneReadInfo.mData.Size() % sizeof(uint64_t)));
JSAutoRequest ar(aCx);
- JSStructuredCloneData buf;
- if (!buf.WriteBytes(data, dataLen)) {
- return false;
- }
-
static const JSStructuredCloneCallbacks callbacks = {
CommonStructuredCloneReadCallback<ValueDeserializationHelper>,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr
};
// FIXME: Consider to use StructuredCloneHolder here and in other
// deserializing methods.
- if (!JS_ReadStructuredClone(aCx, buf, JS_STRUCTURED_CLONE_VERSION,
+ if (!JS_ReadStructuredClone(aCx, aCloneReadInfo.mData, JS_STRUCTURED_CLONE_VERSION,
JS::StructuredCloneScope::SameProcessSameThread,
aValue, &callbacks, &aCloneReadInfo)) {
return false;
}
return true;
}
@@ -1099,40 +1081,32 @@ IDBObjectStore::DeserializeValue(JSConte
bool
IDBObjectStore::DeserializeIndexValue(JSContext* aCx,
StructuredCloneReadInfo& aCloneReadInfo,
JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aCx);
- if (aCloneReadInfo.mData.IsEmpty()) {
+ if (!aCloneReadInfo.mData.Size()) {
aValue.setUndefined();
return true;
}
- size_t dataLen = aCloneReadInfo.mData.Length();
- char* data = reinterpret_cast<char*>(aCloneReadInfo.mData.Elements());
-
- MOZ_ASSERT(!(dataLen % sizeof(uint64_t)));
+ MOZ_ASSERT(!(aCloneReadInfo.mData.Size() % sizeof(uint64_t)));
JSAutoRequest ar(aCx);
- JSStructuredCloneData buf;
- if (!buf.WriteBytes(data, dataLen)) {
- return false;
- }
-
static const JSStructuredCloneCallbacks callbacks = {
CommonStructuredCloneReadCallback<IndexDeserializationHelper>,
nullptr,
nullptr
};
- if (!JS_ReadStructuredClone(aCx, buf, JS_STRUCTURED_CLONE_VERSION,
+ if (!JS_ReadStructuredClone(aCx, aCloneReadInfo.mData, JS_STRUCTURED_CLONE_VERSION,
JS::StructuredCloneScope::SameProcessSameThread,
aValue, &callbacks, &aCloneReadInfo)) {
return false;
}
return true;
}
@@ -1142,44 +1116,35 @@ IDBObjectStore::DeserializeIndexValue(JS
bool
IDBObjectStore::DeserializeUpgradeValue(JSContext* aCx,
StructuredCloneReadInfo& aCloneReadInfo,
JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aCx);
- if (aCloneReadInfo.mData.IsEmpty()) {
+ if (!aCloneReadInfo.mData.Size()) {
aValue.setUndefined();
return true;
}
-
- size_t dataLen = aCloneReadInfo.mData.Length();
- char* data = reinterpret_cast<char*>(aCloneReadInfo.mData.Elements());
-
- MOZ_ASSERT(!(dataLen % sizeof(uint64_t)));
+ MOZ_ASSERT(!(aCloneReadInfo.mData.Size() % sizeof(uint64_t)));
JSAutoRequest ar(aCx);
- JSStructuredCloneData buf;
- if (!buf.WriteBytes(data, dataLen)) {
- return false;
- }
-
static JSStructuredCloneCallbacks callbacks = {
CommonStructuredCloneReadCallback<UpgradeDeserializationHelper>,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr
};
- if (!JS_ReadStructuredClone(aCx, buf, JS_STRUCTURED_CLONE_VERSION,
+ if (!JS_ReadStructuredClone(aCx, aCloneReadInfo.mData, JS_STRUCTURED_CLONE_VERSION,
JS::StructuredCloneScope::SameProcessSameThread,
aValue, &callbacks, &aCloneReadInfo)) {
return false;
}
return true;
}
@@ -1301,38 +1266,19 @@ IDBObjectStore::AddOrPut(JSContext* aCx,
StructuredCloneWriteInfo cloneWriteInfo(mTransaction->Database());
nsTArray<IndexUpdateInfo> updateInfo;
aRv = GetAddInfo(aCx, value, aKey, cloneWriteInfo, key, updateInfo);
if (aRv.Failed()) {
return nullptr;
}
- FallibleTArray<uint8_t> cloneData;
- size_t size = cloneWriteInfo.mCloneBuffer.data().Size();
-
- if (NS_WARN_IF(!cloneData.SetLength(size, fallible))) {
- aRv = NS_ERROR_OUT_OF_MEMORY;
- return nullptr;
- }
-
- const char* buf;
- auto iter = cloneWriteInfo.mCloneBuffer.data().Iter();
- cloneWriteInfo.mCloneBuffer.data().FlattenBytes(iter, &buf, size);
-
- // FIXME Bug XXXXXX Change SerializedStructuredCloneReadInfo and
- // SerializedStructuredCloneWriteInfo to use JSStructuredCloneData
- // instead of raw buffer.
- memcpy(cloneData.Elements(), buf, size);
-
- cloneWriteInfo.mCloneBuffer.clear();
-
ObjectStoreAddPutParams commonParams;
commonParams.objectStoreId() = Id();
- commonParams.cloneInfo().data().SwapElements(cloneData);
+ commonParams.cloneInfo().data().data = Move(cloneWriteInfo.mCloneBuffer.data());
commonParams.cloneInfo().offsetToKeyProp() = cloneWriteInfo.mOffsetToKeyProp;
commonParams.key() = key;
commonParams.indexUpdateInfos().SwapElements(updateInfo);
// Convert any blobs or mutable files into DatabaseOrMutableFile.
nsTArray<StructuredCloneWriteInfo::BlobOrMutableFile>& blobOrMutableFiles =
cloneWriteInfo.mBlobOrMutableFiles;
--- a/dom/indexedDB/IndexedDatabase.h
+++ b/dom/indexedDB/IndexedDatabase.h
@@ -40,23 +40,20 @@ struct StructuredCloneFile
// In IndexedDatabaseInlines.h
inline bool
operator==(const StructuredCloneFile& aOther) const;
};
struct StructuredCloneReadInfo
{
- nsTArray<uint8_t> mData;
+ JSStructuredCloneData mData;
nsTArray<StructuredCloneFile> mFiles;
IDBDatabase* mDatabase;
- // XXX Remove!
- JSAutoStructuredCloneBuffer mCloneBuffer;
-
// In IndexedDatabaseInlines.h
inline
StructuredCloneReadInfo();
// In IndexedDatabaseInlines.h
inline
~StructuredCloneReadInfo();
--- a/dom/indexedDB/IndexedDatabaseInlines.h
+++ b/dom/indexedDB/IndexedDatabaseInlines.h
@@ -49,17 +49,17 @@ StructuredCloneReadInfo::StructuredClone
: mDatabase(nullptr)
{
MOZ_COUNT_CTOR(StructuredCloneReadInfo);
}
inline
StructuredCloneReadInfo::StructuredCloneReadInfo(
SerializedStructuredCloneReadInfo&& aCloneReadInfo)
- : mData(Move(aCloneReadInfo.data()))
+ : mData(Move(aCloneReadInfo.data().data))
, mDatabase(nullptr)
{
MOZ_COUNT_CTOR(StructuredCloneReadInfo);
}
inline
StructuredCloneReadInfo::~StructuredCloneReadInfo()
{
@@ -67,17 +67,16 @@ StructuredCloneReadInfo::~StructuredClon
}
inline StructuredCloneReadInfo&
StructuredCloneReadInfo::operator=(StructuredCloneReadInfo&& aCloneReadInfo)
{
MOZ_ASSERT(&aCloneReadInfo != this);
mData = Move(aCloneReadInfo.mData);
- mCloneBuffer = Move(aCloneReadInfo.mCloneBuffer);
mFiles.Clear();
mFiles.SwapElements(aCloneReadInfo.mFiles);
mDatabase = aCloneReadInfo.mDatabase;
aCloneReadInfo.mDatabase = nullptr;
return *this;
}
} // namespace indexedDB
--- a/dom/indexedDB/PBackgroundIDBSharedTypes.ipdlh
+++ b/dom/indexedDB/PBackgroundIDBSharedTypes.ipdlh
@@ -25,16 +25,19 @@ using class mozilla::dom::indexedDB::Key
from "mozilla/dom/indexedDB/Key.h";
using class mozilla::dom::indexedDB::KeyPath
from "mozilla/dom/indexedDB/KeyPath.h";
using mozilla::dom::quota::PersistenceType
from "mozilla/dom/quota/PersistenceType.h";
+using mozilla::SerializedStructuredCloneBuffer
+ from "ipc/IPCMessageUtils.h";
+
namespace mozilla {
namespace dom {
namespace indexedDB {
struct SerializedKeyRange
{
Key lower;
Key upper;
@@ -52,23 +55,23 @@ union NullableMutableFile
union BlobOrMutableFile
{
PBlob;
NullableMutableFile;
};
struct SerializedStructuredCloneReadInfo
{
- uint8_t[] data;
+ SerializedStructuredCloneBuffer data;
BlobOrMutableFile[] blobs;
};
struct SerializedStructuredCloneWriteInfo
{
- uint8_t[] data;
+ SerializedStructuredCloneBuffer data;
uint64_t offsetToKeyProp;
};
struct IndexUpdateInfo
{
int64_t indexId;
Key value;
Key localizedValue;