зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1264642 - Part 5. Make SerializedStructuredClone{Read,Write}Info use SerializedStructuredCloneBuffer. r=baku
MozReview-Commit-ID: KUz3E5Sw5W3
This commit is contained in:
Родитель
506dfe6ea3
Коммит
0dbfe2dbcc
|
@ -430,8 +430,6 @@ private:
|
|||
{
|
||||
bool ok = IDBObjectStore::DeserializeValue(aCx, *aCloneInfo, aResult);
|
||||
|
||||
aCloneInfo->mCloneBuffer.clear();
|
||||
|
||||
if (NS_WARN_IF(!ok)) {
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
|
|
|
@ -14840,7 +14840,7 @@ TransactionBase::VerifyRequestParams(const ObjectStoreAddPutParams& aParams)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(aParams.cloneInfo().data().IsEmpty())) {
|
||||
if (NS_WARN_IF(!aParams.cloneInfo().data().data.Size())) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
|
@ -14855,13 +14855,13 @@ TransactionBase::VerifyRequestParams(const ObjectStoreAddPutParams& aParams)
|
|||
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;
|
||||
}
|
||||
|
@ -19065,7 +19065,9 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromBlob(
|
|||
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;
|
||||
|
@ -25427,6 +25429,13 @@ ObjectStoreAddOrPutRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
|
|||
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()) {
|
||||
|
@ -25448,16 +25457,14 @@ ObjectStoreAddOrPutRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
|
|||
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));
|
||||
|
||||
|
@ -25468,9 +25475,8 @@ ObjectStoreAddOrPutRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
|
|||
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.
|
||||
|
@ -25802,7 +25808,7 @@ ObjectStoreGetRequestOp::ConvertResponse(
|
|||
|
||||
StructuredCloneReadInfo& info = mResponse[aIndex];
|
||||
|
||||
info.mData.SwapElements(aSerializedInfo.data());
|
||||
aSerializedInfo.data().data = Move(info.mData);
|
||||
|
||||
FallibleTArray<BlobOrMutableFile> blobs;
|
||||
nsresult rv = ConvertBlobsToActors(mBackgroundParent,
|
||||
|
@ -26525,7 +26531,7 @@ IndexGetRequestOp::GetResponse(RequestResponse& aResponse)
|
|||
SerializedStructuredCloneReadInfo& serializedInfo =
|
||||
fallibleCloneInfos[index];
|
||||
|
||||
info.mData.SwapElements(serializedInfo.data());
|
||||
serializedInfo.data().data = Move(info.mData);
|
||||
|
||||
FallibleTArray<BlobOrMutableFile> blobs;
|
||||
nsresult rv = ConvertBlobsToActors(mBackgroundParent,
|
||||
|
@ -26559,7 +26565,7 @@ IndexGetRequestOp::GetResponse(RequestResponse& aResponse)
|
|||
SerializedStructuredCloneReadInfo& serializedInfo =
|
||||
aResponse.get_IndexGetResponse().cloneInfo();
|
||||
|
||||
info.mData.SwapElements(serializedInfo.data());
|
||||
serializedInfo.data().data = Move(info.mData);
|
||||
|
||||
FallibleTArray<BlobOrMutableFile> blobs;
|
||||
nsresult rv =
|
||||
|
@ -26873,7 +26879,7 @@ CursorOpBase::PopulateResponseFromStatement(
|
|||
|
||||
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));
|
||||
|
@ -26911,7 +26917,7 @@ CursorOpBase::PopulateResponseFromStatement(
|
|||
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;
|
||||
|
|
|
@ -867,15 +867,6 @@ CommonStructuredCloneReadCallback(JSContext* aCx,
|
|||
aTag);
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
ClearStructuredCloneBuffer(JSAutoStructuredCloneBuffer& aBuffer)
|
||||
{
|
||||
if (!aBuffer.empty()) {
|
||||
aBuffer.clear();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
const JSClass IDBObjectStore::sDummyPropJSClass = {
|
||||
|
@ -1042,11 +1033,10 @@ 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();
|
||||
}
|
||||
|
||||
|
@ -1058,23 +1048,15 @@ IDBObjectStore::DeserializeValue(JSContext* aCx,
|
|||
{
|
||||
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,
|
||||
|
@ -1086,7 +1068,7 @@ IDBObjectStore::DeserializeValue(JSContext* aCx,
|
|||
|
||||
// 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;
|
||||
|
@ -1104,30 +1086,22 @@ IDBObjectStore::DeserializeIndexValue(JSContext* aCx,
|
|||
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;
|
||||
|
@ -1147,24 +1121,15 @@ IDBObjectStore::DeserializeUpgradeValue(JSContext* aCx,
|
|||
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,
|
||||
|
@ -1174,7 +1139,7 @@ IDBObjectStore::DeserializeUpgradeValue(JSContext* aCx,
|
|||
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;
|
||||
|
@ -1306,28 +1271,9 @@ IDBObjectStore::AddOrPut(JSContext* aCx,
|
|||
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);
|
||||
|
|
|
@ -45,13 +45,10 @@ struct StructuredCloneFile
|
|||
|
||||
struct StructuredCloneReadInfo
|
||||
{
|
||||
nsTArray<uint8_t> mData;
|
||||
JSStructuredCloneData mData;
|
||||
nsTArray<StructuredCloneFile> mFiles;
|
||||
IDBDatabase* mDatabase;
|
||||
|
||||
// XXX Remove!
|
||||
JSAutoStructuredCloneBuffer mCloneBuffer;
|
||||
|
||||
// In IndexedDatabaseInlines.h
|
||||
inline
|
||||
StructuredCloneReadInfo();
|
||||
|
|
|
@ -54,7 +54,7 @@ StructuredCloneReadInfo::StructuredCloneReadInfo()
|
|||
inline
|
||||
StructuredCloneReadInfo::StructuredCloneReadInfo(
|
||||
SerializedStructuredCloneReadInfo&& aCloneReadInfo)
|
||||
: mData(Move(aCloneReadInfo.data()))
|
||||
: mData(Move(aCloneReadInfo.data().data))
|
||||
, mDatabase(nullptr)
|
||||
{
|
||||
MOZ_COUNT_CTOR(StructuredCloneReadInfo);
|
||||
|
@ -72,7 +72,6 @@ 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;
|
||||
|
|
|
@ -30,6 +30,9 @@ using class mozilla::dom::indexedDB::KeyPath
|
|||
using mozilla::dom::quota::PersistenceType
|
||||
from "mozilla/dom/quota/PersistenceType.h";
|
||||
|
||||
using mozilla::SerializedStructuredCloneBuffer
|
||||
from "ipc/IPCMessageUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
@ -57,13 +60,13 @@ union BlobOrMutableFile
|
|||
|
||||
struct SerializedStructuredCloneReadInfo
|
||||
{
|
||||
uint8_t[] data;
|
||||
SerializedStructuredCloneBuffer data;
|
||||
BlobOrMutableFile[] blobs;
|
||||
};
|
||||
|
||||
struct SerializedStructuredCloneWriteInfo
|
||||
{
|
||||
uint8_t[] data;
|
||||
SerializedStructuredCloneBuffer data;
|
||||
uint64_t offsetToKeyProp;
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче