зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1311466 - Part 6: Core changes for WebAssembly module deserialization (works only in xpcshell); r=asuth
This commit is contained in:
Родитель
2962fac045
Коммит
8fef5e4a97
|
@ -686,6 +686,71 @@ DeserializeStructuredCloneFiles(
|
|||
break;
|
||||
}
|
||||
|
||||
case StructuredCloneFile::eWasmBytecode: {
|
||||
MOZ_ASSERT(blobOrMutableFile.type() ==
|
||||
BlobOrMutableFile::TPBlobChild);
|
||||
|
||||
auto* actor =
|
||||
static_cast<BlobChild*>(blobOrMutableFile.get_PBlobChild());
|
||||
|
||||
RefPtr<BlobImpl> blobImpl = actor->GetBlobImpl();
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
RefPtr<Blob> blob = Blob::Create(aDatabase->GetOwner(), blobImpl);
|
||||
|
||||
aDatabase->NoteReceivedBlob(blob);
|
||||
|
||||
StructuredCloneFile* file = aFiles.AppendElement();
|
||||
MOZ_ASSERT(file);
|
||||
|
||||
file->mType = StructuredCloneFile::eWasmBytecode;
|
||||
file->mBlob.swap(blob);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case StructuredCloneFile::eWasmCompiled: {
|
||||
MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::Tnull_t ||
|
||||
blobOrMutableFile.type() ==
|
||||
BlobOrMutableFile::TPBlobChild);
|
||||
|
||||
switch (blobOrMutableFile.type()) {
|
||||
case BlobOrMutableFile::Tnull_t: {
|
||||
StructuredCloneFile* file = aFiles.AppendElement();
|
||||
MOZ_ASSERT(file);
|
||||
|
||||
file->mType = StructuredCloneFile::eWasmCompiled;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case BlobOrMutableFile::TPBlobChild: {
|
||||
auto* actor =
|
||||
static_cast<BlobChild*>(blobOrMutableFile.get_PBlobChild());
|
||||
|
||||
RefPtr<BlobImpl> blobImpl = actor->GetBlobImpl();
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
RefPtr<Blob> blob = Blob::Create(aDatabase->GetOwner(), blobImpl);
|
||||
|
||||
aDatabase->NoteReceivedBlob(blob);
|
||||
|
||||
StructuredCloneFile* file = aFiles.AppendElement();
|
||||
MOZ_ASSERT(file);
|
||||
|
||||
file->mType = StructuredCloneFile::eWasmCompiled;
|
||||
file->mBlob.swap(blob);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Should never get here!");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Should never get here!");
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "mozilla/ipc/InputStreamParams.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "mozilla/ipc/PBackground.h"
|
||||
#include "mozilla/Scoped.h"
|
||||
#include "mozilla/storage/Variant.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
|
@ -124,6 +125,11 @@
|
|||
{0x6b505c84, 0x2c60, 0x4ffb, {0x8b, 0x91, 0xfe, 0x22, 0xb1, 0xec, 0x75, 0xe2}}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRFileDesc,
|
||||
PRFileDesc,
|
||||
PR_Close);
|
||||
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
|
@ -9592,32 +9598,41 @@ DeserializeStructuredCloneFile(FileManager* aFileManager,
|
|||
MOZ_ASSERT(!aText.IsEmpty());
|
||||
MOZ_ASSERT(aFile);
|
||||
|
||||
nsresult rv;
|
||||
int32_t id;
|
||||
StructuredCloneFile::FileType type;
|
||||
|
||||
bool isDot = false;
|
||||
if ((isDot = aText.First() == '.') ||
|
||||
aText.First() == '-') {
|
||||
switch (aText.First()) {
|
||||
case char16_t('-'):
|
||||
type = StructuredCloneFile::eMutableFile;
|
||||
break;
|
||||
|
||||
case char16_t('.'):
|
||||
type = StructuredCloneFile::eStructuredClone;
|
||||
break;
|
||||
|
||||
case char16_t('/'):
|
||||
type = StructuredCloneFile::eWasmBytecode;
|
||||
break;
|
||||
|
||||
case char16_t('\\'):
|
||||
type = StructuredCloneFile::eWasmCompiled;
|
||||
break;
|
||||
|
||||
default:
|
||||
type = StructuredCloneFile::eBlob;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
int32_t id;
|
||||
|
||||
if (type == StructuredCloneFile::eBlob) {
|
||||
id = aText.ToInteger(&rv);
|
||||
} else {
|
||||
nsString text(Substring(aText, 1));
|
||||
|
||||
id = text.ToInteger(&rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (isDot) {
|
||||
type = StructuredCloneFile::eStructuredClone;
|
||||
} else {
|
||||
type = StructuredCloneFile::eMutableFile;
|
||||
}
|
||||
} else {
|
||||
id = aText.ToInteger(&rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
type = StructuredCloneFile::eBlob;
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
RefPtr<FileInfo> fileInfo = aFileManager->GetFileInfo(id);
|
||||
|
@ -9634,11 +9649,14 @@ DeserializeStructuredCloneFiles(FileManager* aFileManager,
|
|||
const nsAString& aText,
|
||||
nsTArray<StructuredCloneFile>& aResult)
|
||||
{
|
||||
MOZ_ASSERT(!IsOnBackgroundThread());
|
||||
|
||||
nsCharSeparatedTokenizerTemplate<TokenizerIgnoreNothing>
|
||||
tokenizer(aText, ' ');
|
||||
|
||||
nsAutoString token;
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> directory;
|
||||
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
token = tokenizer.nextToken();
|
||||
|
@ -9649,6 +9667,40 @@ DeserializeStructuredCloneFiles(FileManager* aFileManager,
|
|||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (file->mType == StructuredCloneFile::eWasmCompiled) {
|
||||
if (!directory) {
|
||||
directory = aFileManager->GetCheckedDirectory();
|
||||
if (NS_WARN_IF(!directory)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
const int64_t fileId = file->mFileInfo->Id();
|
||||
MOZ_ASSERT(fileId > 0);
|
||||
|
||||
nsCOMPtr<nsIFile> nativeFile =
|
||||
aFileManager->GetCheckedFileForId(directory, fileId);
|
||||
if (NS_WARN_IF(!nativeFile)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
ScopedPRFileDesc fileDesc;
|
||||
rv = nativeFile->OpenNSPRFileDesc(PR_RDONLY, 0644, &fileDesc.rwget());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
JS::BuildIdCharVector buildId;
|
||||
bool ok = GetBuildId(&buildId);
|
||||
if (NS_WARN_IF(!ok)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(file->mValid);
|
||||
file->mValid = JS::CompiledWasmModuleAssumptionsMatch(fileDesc,
|
||||
Move(buildId));
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -9694,20 +9746,12 @@ SerializeStructuredCloneFiles(
|
|||
|
||||
FileManager* fileManager = aDatabase->GetFileManager();
|
||||
|
||||
nsCOMPtr<nsIFile> directory = fileManager->GetDirectory();
|
||||
nsCOMPtr<nsIFile> directory = fileManager->GetCheckedDirectory();
|
||||
if (NS_WARN_IF(!directory)) {
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
DebugOnly<bool> exists;
|
||||
MOZ_ASSERT(NS_SUCCEEDED(directory->Exists(&exists)));
|
||||
MOZ_ASSERT(exists);
|
||||
|
||||
DebugOnly<bool> isDirectory;
|
||||
MOZ_ASSERT(NS_SUCCEEDED(directory->IsDirectory(&isDirectory)));
|
||||
MOZ_ASSERT(isDirectory);
|
||||
|
||||
const uint32_t count = aFiles.Length();
|
||||
|
||||
if (NS_WARN_IF(!aResult.SetCapacity(count, fallible))) {
|
||||
|
@ -9721,19 +9765,12 @@ SerializeStructuredCloneFiles(
|
|||
MOZ_ASSERT(fileId > 0);
|
||||
|
||||
nsCOMPtr<nsIFile> nativeFile =
|
||||
fileManager->GetFileForId(directory, fileId);
|
||||
fileManager->GetCheckedFileForId(directory, fileId);
|
||||
if (NS_WARN_IF(!nativeFile)) {
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(NS_SUCCEEDED(nativeFile->Exists(&exists)));
|
||||
MOZ_ASSERT(exists);
|
||||
|
||||
DebugOnly<bool> isFile;
|
||||
MOZ_ASSERT(NS_SUCCEEDED(nativeFile->IsFile(&isFile)));
|
||||
MOZ_ASSERT(isFile);
|
||||
|
||||
switch (file.mType) {
|
||||
case StructuredCloneFile::eBlob: {
|
||||
RefPtr<BlobImpl> impl = new BlobImplStoredFile(nativeFile,
|
||||
|
@ -9803,6 +9840,40 @@ SerializeStructuredCloneFiles(
|
|||
break;
|
||||
}
|
||||
|
||||
case StructuredCloneFile::eWasmBytecode:
|
||||
case StructuredCloneFile::eWasmCompiled: {
|
||||
if (file.mType == StructuredCloneFile::eWasmCompiled && !file.mValid) {
|
||||
SerializedStructuredCloneFile* serializedFile =
|
||||
aResult.AppendElement(fallible);
|
||||
MOZ_ASSERT(serializedFile);
|
||||
|
||||
serializedFile->file() = null_t();
|
||||
serializedFile->type() = StructuredCloneFile::eWasmCompiled;
|
||||
} else {
|
||||
RefPtr<BlobImpl> impl = new BlobImplStoredFile(nativeFile,
|
||||
file.mFileInfo,
|
||||
/* aSnapshot */ false);
|
||||
|
||||
PBlobParent* actor =
|
||||
BackgroundParent::GetOrCreateActorForBlobImpl(aBackgroundActor,
|
||||
impl);
|
||||
if (!actor) {
|
||||
// This can only fail if the child has crashed.
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
SerializedStructuredCloneFile* serializedFile =
|
||||
aResult.AppendElement(fallible);
|
||||
MOZ_ASSERT(serializedFile);
|
||||
|
||||
serializedFile->file() = actor;
|
||||
serializedFile->type() = file.mType;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Should never get here!");
|
||||
}
|
||||
|
@ -16804,6 +16875,25 @@ FileManager::GetDirectory()
|
|||
return GetFileForPath(mDirectoryPath);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIFile>
|
||||
FileManager::GetCheckedDirectory()
|
||||
{
|
||||
nsCOMPtr<nsIFile> directory = GetDirectory();
|
||||
if (NS_WARN_IF(!directory)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DebugOnly<bool> exists;
|
||||
MOZ_ASSERT(NS_SUCCEEDED(directory->Exists(&exists)));
|
||||
MOZ_ASSERT(exists);
|
||||
|
||||
DebugOnly<bool> isDirectory;
|
||||
MOZ_ASSERT(NS_SUCCEEDED(directory->IsDirectory(&isDirectory)));
|
||||
MOZ_ASSERT(isDirectory);
|
||||
|
||||
return directory.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIFile>
|
||||
FileManager::GetJournalDirectory()
|
||||
{
|
||||
|
@ -16911,6 +17001,26 @@ FileManager::GetFileForId(nsIFile* aDirectory, int64_t aId)
|
|||
return file.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<nsIFile>
|
||||
FileManager::GetCheckedFileForId(nsIFile* aDirectory, int64_t aId)
|
||||
{
|
||||
nsCOMPtr<nsIFile> file = GetFileForId(aDirectory, aId);
|
||||
if (NS_WARN_IF(!file)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DebugOnly<bool> exists;
|
||||
MOZ_ASSERT(NS_SUCCEEDED(file->Exists(&exists)));
|
||||
MOZ_ASSERT(exists);
|
||||
|
||||
DebugOnly<bool> isFile;
|
||||
MOZ_ASSERT(NS_SUCCEEDED(file->IsFile(&isFile)));
|
||||
MOZ_ASSERT(isFile);
|
||||
|
||||
return file.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
FileManager::InitDirectory(nsIFile* aDirectory,
|
||||
|
|
|
@ -50,6 +50,9 @@ public:
|
|||
static already_AddRefed<nsIFile>
|
||||
GetFileForId(nsIFile* aDirectory, int64_t aId);
|
||||
|
||||
static already_AddRefed<nsIFile>
|
||||
GetCheckedFileForId(nsIFile* aDirectory, int64_t aId);
|
||||
|
||||
static nsresult
|
||||
InitDirectory(nsIFile* aDirectory,
|
||||
nsIFile* aDatabaseFile,
|
||||
|
@ -119,6 +122,9 @@ public:
|
|||
already_AddRefed<nsIFile>
|
||||
GetDirectory();
|
||||
|
||||
already_AddRefed<nsIFile>
|
||||
GetCheckedDirectory();
|
||||
|
||||
already_AddRefed<nsIFile>
|
||||
GetJournalDirectory();
|
||||
|
||||
|
|
|
@ -136,6 +136,26 @@ struct MOZ_STACK_CLASS BlobOrFileData final
|
|||
}
|
||||
};
|
||||
|
||||
struct MOZ_STACK_CLASS WasmModuleData final
|
||||
{
|
||||
uint32_t bytecodeIndex;
|
||||
uint32_t compiledIndex;
|
||||
uint32_t flags;
|
||||
|
||||
explicit WasmModuleData(uint32_t aFlags)
|
||||
: bytecodeIndex(0)
|
||||
, compiledIndex(0)
|
||||
, flags(aFlags)
|
||||
{
|
||||
MOZ_COUNT_CTOR(WasmModuleData);
|
||||
}
|
||||
|
||||
~WasmModuleData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(WasmModuleData);
|
||||
}
|
||||
};
|
||||
|
||||
struct MOZ_STACK_CLASS GetAddInfoClosure final
|
||||
{
|
||||
IDBObjectStore::StructuredCloneWriteInfo& mCloneWriteInfo;
|
||||
|
@ -170,6 +190,25 @@ GenerateRequest(JSContext* aCx, IDBObjectStore* aObjectStore)
|
|||
return request.forget();
|
||||
}
|
||||
|
||||
PRFileDesc*
|
||||
GetFileDescriptorFromStream(nsIInputStream* aStream)
|
||||
{
|
||||
nsCOMPtr<nsIFileMetadata> fileMetadata = do_QueryInterface(aStream);
|
||||
if (NS_WARN_IF(!fileMetadata)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PRFileDesc* fileDesc;
|
||||
nsresult rv = fileMetadata->GetFileDescriptor(&fileDesc);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(fileDesc);
|
||||
|
||||
return fileDesc;
|
||||
}
|
||||
|
||||
bool
|
||||
StructuredCloneWriteCallback(JSContext* aCx,
|
||||
JSStructuredCloneWriter* aWriter,
|
||||
|
@ -578,6 +617,27 @@ ReadBlobOrFile(JSStructuredCloneReader* aReader,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ReadWasmModule(JSStructuredCloneReader* aReader,
|
||||
WasmModuleData* aRetval)
|
||||
{
|
||||
static_assert(SCTAG_DOM_WASM == 0xFFFF8006, "Update me!");
|
||||
MOZ_ASSERT(aReader && aRetval);
|
||||
|
||||
uint32_t bytecodeIndex;
|
||||
uint32_t compiledIndex;
|
||||
if (NS_WARN_IF(!JS_ReadUint32Pair(aReader,
|
||||
&bytecodeIndex,
|
||||
&compiledIndex))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aRetval->bytecodeIndex = bytecodeIndex;
|
||||
aRetval->compiledIndex = compiledIndex;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class ValueDeserializationHelper
|
||||
{
|
||||
public:
|
||||
|
@ -682,6 +742,76 @@ public:
|
|||
aResult.set(&wrappedFile.toObject());
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
CreateAndWrapWasmModule(JSContext* aCx,
|
||||
StructuredCloneFile& aBytecodeFile,
|
||||
StructuredCloneFile& aCompiledFile,
|
||||
const WasmModuleData& aData,
|
||||
JS::MutableHandle<JSObject*> aResult)
|
||||
{
|
||||
MOZ_ASSERT(aCx);
|
||||
MOZ_ASSERT(aBytecodeFile.mType == StructuredCloneFile::eWasmBytecode);
|
||||
MOZ_ASSERT(aBytecodeFile.mBlob);
|
||||
MOZ_ASSERT(aCompiledFile.mType == StructuredCloneFile::eWasmCompiled);
|
||||
|
||||
ErrorResult errorResult;
|
||||
|
||||
nsCOMPtr<nsIInputStream> bytecodeStream;
|
||||
aBytecodeFile.mBlob->GetInternalStream(getter_AddRefs(bytecodeStream),
|
||||
errorResult);
|
||||
if (NS_WARN_IF(errorResult.Failed())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PRFileDesc* bytecodeFileDesc = GetFileDescriptorFromStream(bytecodeStream);
|
||||
if (NS_WARN_IF(!bytecodeFileDesc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The compiled stream must scoped here!
|
||||
nsCOMPtr<nsIInputStream> compiledStream;
|
||||
|
||||
PRFileDesc* compiledFileDesc;
|
||||
if (aCompiledFile.mBlob) {
|
||||
aCompiledFile.mBlob->GetInternalStream(getter_AddRefs(compiledStream),
|
||||
errorResult);
|
||||
if (NS_WARN_IF(errorResult.Failed())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
compiledFileDesc = GetFileDescriptorFromStream(compiledStream);
|
||||
if (NS_WARN_IF(!compiledFileDesc)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
compiledFileDesc = nullptr;
|
||||
}
|
||||
|
||||
JS::BuildIdCharVector buildId;
|
||||
bool ok = GetBuildId(&buildId);
|
||||
if (NS_WARN_IF(!ok)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<JS::WasmModule> module = JS::DeserializeWasmModule(bytecodeFileDesc,
|
||||
compiledFileDesc,
|
||||
Move(buildId),
|
||||
nullptr,
|
||||
0,
|
||||
0);
|
||||
if (NS_WARN_IF(!module)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> moduleObj(aCx, module->createObject(aCx));
|
||||
if (NS_WARN_IF(!moduleObj)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aResult.set(moduleObj);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class IndexDeserializationHelper
|
||||
|
@ -774,6 +904,23 @@ public:
|
|||
aResult.set(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
CreateAndWrapWasmModule(JSContext* aCx,
|
||||
StructuredCloneFile& aBytecodeFile,
|
||||
StructuredCloneFile& aCompiledFile,
|
||||
const WasmModuleData& aData,
|
||||
JS::MutableHandle<JSObject*> aResult)
|
||||
{
|
||||
// Wasm module can't be used in index creation, so just make a dummy object.
|
||||
JS::Rooted<JSObject*> obj(aCx, JS_NewPlainObject(aCx));
|
||||
if (NS_WARN_IF(!obj)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aResult.set(obj);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// We don't need to upgrade database on B2G. See the comment in ActorsParent.cpp,
|
||||
|
@ -830,6 +977,22 @@ public:
|
|||
aResult.set(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
CreateAndWrapWasmModule(JSContext* aCx,
|
||||
StructuredCloneFile& aBytecodeFile,
|
||||
StructuredCloneFile& aCompiledFile,
|
||||
const WasmModuleData& aData,
|
||||
JS::MutableHandle<JSObject*> aResult)
|
||||
{
|
||||
MOZ_ASSERT(aCx);
|
||||
MOZ_ASSERT(aBytecodeFile.mType == StructuredCloneFile::eBlob);
|
||||
MOZ_ASSERT(aCompiledFile.mType == StructuredCloneFile::eBlob);
|
||||
|
||||
MOZ_ASSERT(false, "This should never be possible!");
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // MOZ_B2G
|
||||
|
@ -855,9 +1018,43 @@ CommonStructuredCloneReadCallback(JSContext* aCx,
|
|||
if (aTag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE ||
|
||||
aTag == SCTAG_DOM_BLOB ||
|
||||
aTag == SCTAG_DOM_FILE ||
|
||||
aTag == SCTAG_DOM_MUTABLEFILE) {
|
||||
aTag == SCTAG_DOM_MUTABLEFILE ||
|
||||
aTag == SCTAG_DOM_WASM) {
|
||||
auto* cloneReadInfo = static_cast<StructuredCloneReadInfo*>(aClosure);
|
||||
|
||||
JS::Rooted<JSObject*> result(aCx);
|
||||
|
||||
if (aTag == SCTAG_DOM_WASM) {
|
||||
WasmModuleData data(aData);
|
||||
if (NS_WARN_IF(!ReadWasmModule(aReader, &data))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(data.compiledIndex == data.bytecodeIndex + 1);
|
||||
MOZ_ASSERT(!data.flags);
|
||||
|
||||
if (data.bytecodeIndex >= cloneReadInfo->mFiles.Length() ||
|
||||
data.compiledIndex >= cloneReadInfo->mFiles.Length()) {
|
||||
MOZ_ASSERT(false, "Bad index value!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StructuredCloneFile& bytecodeFile =
|
||||
cloneReadInfo->mFiles[data.bytecodeIndex];
|
||||
StructuredCloneFile& compiledFile =
|
||||
cloneReadInfo->mFiles[data.compiledIndex];
|
||||
|
||||
if (NS_WARN_IF(!Traits::CreateAndWrapWasmModule(aCx,
|
||||
bytecodeFile,
|
||||
compiledFile,
|
||||
data,
|
||||
&result))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
if (aData >= cloneReadInfo->mFiles.Length()) {
|
||||
MOZ_ASSERT(false, "Bad index value!");
|
||||
return nullptr;
|
||||
|
@ -865,8 +1062,6 @@ CommonStructuredCloneReadCallback(JSContext* aCx,
|
|||
|
||||
StructuredCloneFile& file = cloneReadInfo->mFiles[aData];
|
||||
|
||||
JS::Rooted<JSObject*> result(aCx);
|
||||
|
||||
if (aTag == SCTAG_DOM_MUTABLEFILE) {
|
||||
MutableFileData data;
|
||||
if (NS_WARN_IF(!ReadFileHandle(aReader, &data))) {
|
||||
|
|
|
@ -38,6 +38,8 @@ struct StructuredCloneFile
|
|||
RefPtr<IDBMutableFile> mMutableFile;
|
||||
RefPtr<FileInfo> mFileInfo;
|
||||
FileType mType;
|
||||
// This is currently specific to eWasmCompiled files.
|
||||
bool mValid;
|
||||
|
||||
// In IndexedDatabaseInlines.h
|
||||
inline
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace indexedDB {
|
|||
inline
|
||||
StructuredCloneFile::StructuredCloneFile()
|
||||
: mType(eBlob)
|
||||
, mValid(true)
|
||||
{
|
||||
MOZ_COUNT_CTOR(StructuredCloneFile);
|
||||
}
|
||||
|
@ -41,7 +42,8 @@ StructuredCloneFile::operator==(const StructuredCloneFile& aOther) const
|
|||
return this->mBlob == aOther.mBlob &&
|
||||
this->mMutableFile == aOther.mMutableFile &&
|
||||
this->mFileInfo == aOther.mFileInfo &&
|
||||
this->mType == aOther.mType;
|
||||
this->mType == aOther.mType &&
|
||||
this->mValid == aOther.mValid;
|
||||
}
|
||||
|
||||
inline
|
||||
|
|
|
@ -45,8 +45,8 @@ function compareBuffers(buffer1, buffer2)
|
|||
if (buffer1.byteLength != buffer2.byteLength) {
|
||||
return false;
|
||||
}
|
||||
let view1 = new Uint8Array(buffer1);
|
||||
let view2 = new Uint8Array(buffer2);
|
||||
let view1 = buffer1 instanceof Uint8Array ? buffer1 : new Uint8Array(buffer1);
|
||||
let view2 = buffer2 instanceof Uint8Array ? buffer2 : new Uint8Array(buffer2);
|
||||
for (let i = 0; i < buffer1.byteLength; i++) {
|
||||
if (view1[i] != view2[i]) {
|
||||
return false;
|
||||
|
@ -202,6 +202,20 @@ function verifyView(view1, view2)
|
|||
continueToNextStep();
|
||||
}
|
||||
|
||||
function verifyWasmModule(module1, module2)
|
||||
{
|
||||
let testingFunctions = SpecialPowers.Cu.getJSTestingFunctions();
|
||||
let wasmExtractCode = SpecialPowers.unwrap(testingFunctions.wasmExtractCode);
|
||||
let exp1 = wasmExtractCode(module1);
|
||||
let exp2 = wasmExtractCode(module2);
|
||||
let code1 = exp1.code;
|
||||
let code2 = exp2.code;
|
||||
ok(code1 instanceof Uint8Array, "Instance of Uint8Array");
|
||||
ok(code1.length == code2.length, "Correct length");
|
||||
verifyBuffers(code1, code2);
|
||||
continueToNextStep();
|
||||
}
|
||||
|
||||
function grabFileUsageAndContinueHandler(request)
|
||||
{
|
||||
testGenerator.send(request.fileUsage);
|
||||
|
|
|
@ -392,6 +392,7 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
|||
[test_view_put_get_values.html]
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
[test_wasm_put_get_values.html]
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
#skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
skip-if = true
|
||||
[test_serviceworker.html]
|
||||
skip-if = buildapp == 'b2g'
|
||||
|
|
|
@ -63,6 +63,25 @@ function testSteps()
|
|||
|
||||
is(request.result, wasmData.key, "Got correct key");
|
||||
|
||||
info("Getting wasm");
|
||||
|
||||
request = objectStore.get(wasmData.key);
|
||||
request.onsuccess = continueToNextStepSync;
|
||||
yield undefined;
|
||||
|
||||
verifyWasmModule(request.result, wasmData.wasm);
|
||||
yield undefined;
|
||||
|
||||
info("Getting wasm in new transaction");
|
||||
|
||||
request = db.transaction([objectStoreName])
|
||||
.objectStore(objectStoreName).get(wasmData.key);
|
||||
request.onsuccess = continueToNextStepSync;
|
||||
yield undefined;
|
||||
|
||||
verifyWasmModule(request.result, wasmData.wasm);
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
|
|
@ -387,8 +387,9 @@ function compareBuffers(buffer1, buffer2)
|
|||
if (buffer1.byteLength != buffer2.byteLength) {
|
||||
return false;
|
||||
}
|
||||
let view1 = new Uint8Array(buffer1);
|
||||
let view2 = new Uint8Array(buffer2);
|
||||
|
||||
let view1 = buffer1 instanceof Uint8Array ? buffer1 : new Uint8Array(buffer1);
|
||||
let view2 = buffer2 instanceof Uint8Array ? buffer2 : new Uint8Array(buffer2);
|
||||
for (let i = 0; i < buffer1.byteLength; i++) {
|
||||
if (view1[i] != view2[i]) {
|
||||
return false;
|
||||
|
@ -464,6 +465,19 @@ function verifyView(view1, view2)
|
|||
continueToNextStep();
|
||||
}
|
||||
|
||||
function verifyWasmModule(module1, module2)
|
||||
{
|
||||
let testingFunctions = Cu.getJSTestingFunctions();
|
||||
let exp1 = testingFunctions.wasmExtractCode(module1);
|
||||
let exp2 = testingFunctions.wasmExtractCode(module2);
|
||||
let code1 = exp1.code;
|
||||
let code2 = exp2.code;
|
||||
ok(code1 instanceof Uint8Array, "Instance of Uint8Array");
|
||||
ok(code1.length == code2.length, "Correct length");
|
||||
verifyBuffers(code1, code2);
|
||||
continueToNextStep();
|
||||
}
|
||||
|
||||
function grabFileUsageAndContinueHandler(request)
|
||||
{
|
||||
testGenerator.send(request.fileUsage);
|
||||
|
|
Загрузка…
Ссылка в новой задаче