зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1311466 - Part 3: Core changes for WebAssembly module serialization including a test; r=asuth
This commit is contained in:
Родитель
51534c010e
Коммит
00707ba46a
|
@ -27,6 +27,10 @@ enum StructuredCloneTags {
|
|||
SCTAG_DOM_MUTABLEFILE,
|
||||
SCTAG_DOM_FILE,
|
||||
|
||||
SCTAG_DOM_WASM,
|
||||
|
||||
// New IDB tags go here!
|
||||
|
||||
// These tags are used for both main thread and workers.
|
||||
SCTAG_DOM_IMAGEDATA,
|
||||
SCTAG_DOM_MAP_MESSAGEPORT,
|
||||
|
@ -56,6 +60,12 @@ enum StructuredCloneTags {
|
|||
// This tag is used by both main thread and workers.
|
||||
SCTAG_DOM_URLSEARCHPARAMS,
|
||||
|
||||
// When adding a new tag for IDB, please don't add it to the end of the list!
|
||||
// Tags that are supported by IDB must not ever change. See the static assert
|
||||
// in IDBObjectStore.cpp, method CommonStructuredCloneReadCallback.
|
||||
// Adding to the end of the list would make removing of other tags harder in
|
||||
// future.
|
||||
|
||||
SCTAG_DOM_MAX
|
||||
};
|
||||
|
||||
|
|
|
@ -8237,6 +8237,16 @@ struct ObjectStoreAddOrPutRequestOp::StoredFileInfo final
|
|||
aText.AppendInt(id);
|
||||
break;
|
||||
|
||||
case StructuredCloneFile::eWasmBytecode:
|
||||
aText.Append('/');
|
||||
aText.AppendInt(id);
|
||||
break;
|
||||
|
||||
case StructuredCloneFile::eWasmCompiled:
|
||||
aText.Append('\\');
|
||||
aText.AppendInt(id);
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Should never get here!");
|
||||
}
|
||||
|
@ -15097,6 +15107,22 @@ TransactionBase::VerifyRequestParams(const ObjectStoreAddPutParams& aParams)
|
|||
}
|
||||
|
||||
case StructuredCloneFile::eStructuredClone:
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
|
||||
case StructuredCloneFile::eWasmBytecode:
|
||||
case StructuredCloneFile::eWasmCompiled:
|
||||
if (NS_WARN_IF(file.type() !=
|
||||
DatabaseOrMutableFile::TPBackgroundIDBDatabaseFileParent)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
if (NS_WARN_IF(!file.get_PBackgroundIDBDatabaseFileParent())) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case StructuredCloneFile::eEndGuard:
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return false;
|
||||
|
@ -25545,7 +25571,9 @@ ObjectStoreAddOrPutRequestOp::Init(TransactionBase* aTransaction)
|
|||
const FileAddInfo& fileAddInfo = fileAddInfos[index];
|
||||
|
||||
MOZ_ASSERT(fileAddInfo.type() == StructuredCloneFile::eBlob ||
|
||||
fileAddInfo.type() == StructuredCloneFile::eMutableFile);
|
||||
fileAddInfo.type() == StructuredCloneFile::eMutableFile ||
|
||||
fileAddInfo.type() == StructuredCloneFile::eWasmBytecode ||
|
||||
fileAddInfo.type() == StructuredCloneFile::eWasmCompiled);
|
||||
|
||||
const DatabaseOrMutableFile& file = fileAddInfo.file();
|
||||
|
||||
|
@ -25591,6 +25619,29 @@ ObjectStoreAddOrPutRequestOp::Init(TransactionBase* aTransaction)
|
|||
break;
|
||||
}
|
||||
|
||||
case StructuredCloneFile::eWasmBytecode:
|
||||
case StructuredCloneFile::eWasmCompiled: {
|
||||
MOZ_ASSERT(file.type() ==
|
||||
DatabaseOrMutableFile::TPBackgroundIDBDatabaseFileParent);
|
||||
|
||||
storedFileInfo->mFileActor =
|
||||
static_cast<DatabaseFile*>(
|
||||
file.get_PBackgroundIDBDatabaseFileParent());
|
||||
MOZ_ASSERT(storedFileInfo->mFileActor);
|
||||
|
||||
storedFileInfo->mFileInfo = storedFileInfo->mFileActor->GetFileInfo();
|
||||
MOZ_ASSERT(storedFileInfo->mFileInfo);
|
||||
|
||||
storedFileInfo->mInputStream =
|
||||
storedFileInfo->mFileActor->GetInputStream();
|
||||
if (storedFileInfo->mInputStream && !mFileManager) {
|
||||
mFileManager = fileManager;
|
||||
}
|
||||
|
||||
storedFileInfo->mType = fileAddInfo.type();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Should never get here!");
|
||||
}
|
||||
|
|
|
@ -323,6 +323,56 @@ StructuredCloneWriteCallback(JSContext* aCx,
|
|||
}
|
||||
}
|
||||
|
||||
if (JS::IsWasmModuleObject(aObj)) {
|
||||
RefPtr<JS::WasmModule> module = JS::GetWasmModule(aObj);
|
||||
MOZ_ASSERT(module);
|
||||
|
||||
size_t bytecodeSize;
|
||||
size_t compiledSize;
|
||||
module->serializedSize(&bytecodeSize, &compiledSize);
|
||||
|
||||
UniquePtr<uint8_t[]> bytecode(new uint8_t[bytecodeSize]);
|
||||
MOZ_ASSERT(bytecode);
|
||||
|
||||
UniquePtr<uint8_t[]> compiled(new uint8_t[compiledSize]);
|
||||
MOZ_ASSERT(compiled);
|
||||
|
||||
module->serialize(bytecode.get(),
|
||||
bytecodeSize,
|
||||
compiled.get(),
|
||||
compiledSize);
|
||||
|
||||
RefPtr<BlobImpl> blobImpl =
|
||||
new BlobImplMemory(bytecode.release(), bytecodeSize, EmptyString());
|
||||
RefPtr<Blob> bytecodeBlob = Blob::Create(nullptr, blobImpl);
|
||||
|
||||
blobImpl =
|
||||
new BlobImplMemory(compiled.release(), compiledSize, EmptyString());
|
||||
RefPtr<Blob> compiledBlob = Blob::Create(nullptr, blobImpl);
|
||||
|
||||
if (cloneWriteInfo->mFiles.Length() + 1 > size_t(UINT32_MAX)) {
|
||||
MOZ_ASSERT(false, "Fix the structured clone data to use a bigger type!");
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint32_t index = cloneWriteInfo->mFiles.Length();
|
||||
|
||||
if (!JS_WriteUint32Pair(aWriter, SCTAG_DOM_WASM, /* flags */ 0) ||
|
||||
!JS_WriteUint32Pair(aWriter, index, index + 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
StructuredCloneFile* newFile = cloneWriteInfo->mFiles.AppendElement();
|
||||
newFile->mBlob = bytecodeBlob;
|
||||
newFile->mType = StructuredCloneFile::eWasmBytecode;
|
||||
|
||||
newFile = cloneWriteInfo->mFiles.AppendElement();
|
||||
newFile->mBlob = compiledBlob;
|
||||
newFile->mType = StructuredCloneFile::eWasmCompiled;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return StructuredCloneHolder::WriteFullySerializableObjects(aCx, aWriter, aObj);
|
||||
}
|
||||
|
||||
|
@ -797,7 +847,8 @@ CommonStructuredCloneReadCallback(JSContext* aCx,
|
|||
static_assert(SCTAG_DOM_BLOB == 0xffff8001 &&
|
||||
SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE == 0xffff8002 &&
|
||||
SCTAG_DOM_MUTABLEFILE == 0xffff8004 &&
|
||||
SCTAG_DOM_FILE == 0xffff8005,
|
||||
SCTAG_DOM_FILE == 0xffff8005 &&
|
||||
SCTAG_DOM_WASM == 0xffff8006,
|
||||
"You changed our structured clone tag values and just ate "
|
||||
"everyone's IndexedDB data. I hope you are happy.");
|
||||
|
||||
|
@ -1320,6 +1371,25 @@ IDBObjectStore::AddOrPut(JSContext* aCx,
|
|||
break;
|
||||
}
|
||||
|
||||
case StructuredCloneFile::eWasmBytecode:
|
||||
case StructuredCloneFile::eWasmCompiled: {
|
||||
MOZ_ASSERT(file.mBlob);
|
||||
MOZ_ASSERT(!file.mMutableFile);
|
||||
|
||||
PBackgroundIDBDatabaseFileChild* fileActor =
|
||||
database->GetOrCreateFileActorForBlob(file.mBlob);
|
||||
if (NS_WARN_IF(!fileActor)) {
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
aRv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
fileAddInfo->file() = fileActor;
|
||||
fileAddInfo->type() = file.mType;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Should never get here!");
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ struct StructuredCloneFile
|
|||
eBlob,
|
||||
eMutableFile,
|
||||
eStructuredClone,
|
||||
eWasmBytecode,
|
||||
eWasmCompiled,
|
||||
eEndGuard
|
||||
};
|
||||
|
||||
|
|
|
@ -85,6 +85,21 @@ function getNullFile(name, size)
|
|||
return getFile(name, "binary/null", getView(size));
|
||||
}
|
||||
|
||||
function isWasmSupported()
|
||||
{
|
||||
let testingFunctions = SpecialPowers.Cu.getJSTestingFunctions();
|
||||
return testingFunctions.wasmIsSupported();
|
||||
}
|
||||
|
||||
function getWasmModule(text)
|
||||
{
|
||||
let testingFunctions = SpecialPowers.Cu.getJSTestingFunctions();
|
||||
let wasmTextToBinary = SpecialPowers.unwrap(testingFunctions.wasmTextToBinary);
|
||||
let binary = wasmTextToBinary(text);
|
||||
let module = new WebAssembly.Module(binary);
|
||||
return module;
|
||||
}
|
||||
|
||||
function verifyBuffers(buffer1, buffer2)
|
||||
{
|
||||
ok(compareBuffers(buffer1, buffer2), "Correct buffer data");
|
||||
|
|
|
@ -113,6 +113,7 @@ support-files =
|
|||
unit/test_transaction_ordering.js
|
||||
unit/test_unique_index_update.js
|
||||
unit/test_view_put_get_values.js
|
||||
unit/test_wasm_put_get_values.js
|
||||
unit/test_writer_starvation.js
|
||||
|
||||
[test_abort_deleted_index.html]
|
||||
|
@ -390,5 +391,7 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
|||
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
|
||||
[test_serviceworker.html]
|
||||
skip-if = buildapp == 'b2g'
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Indexed Database Property Test</title>
|
||||
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
<script type="text/javascript;version=1.7" src="unit/test_wasm_put_get_values.js"></script>
|
||||
<script type="text/javascript;version=1.7" src="file.js"></script>
|
||||
<script type="text/javascript;version=1.7" src="helpers.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="runTest();"></body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,68 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var disableWorkerTest = "Need a way to set temporary prefs from a worker";
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const name =
|
||||
this.window ? window.location.pathname : "test_wasm_put_get_values.js";
|
||||
|
||||
const objectStoreName = "Wasm";
|
||||
|
||||
const wasmData = { key: 1, wasm: null };
|
||||
|
||||
if (this.window) {
|
||||
SpecialPowers.pushPrefEnv({ "set": [["javascript.options.wasm", true]] },
|
||||
continueToNextStep);
|
||||
yield undefined;
|
||||
} else {
|
||||
enableWasm();
|
||||
}
|
||||
|
||||
if (!isWasmSupported()) {
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
info("Opening database");
|
||||
|
||||
let request = indexedDB.open(name);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = continueToNextStepSync;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
yield undefined;
|
||||
|
||||
// upgradeneeded
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = continueToNextStepSync;
|
||||
|
||||
info("Creating objectStore");
|
||||
|
||||
request.result.createObjectStore(objectStoreName);
|
||||
|
||||
yield undefined;
|
||||
|
||||
// success
|
||||
let db = request.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
info("Storing wasm");
|
||||
|
||||
wasmData.wasm = getWasmModule('(module (func (nop)))');
|
||||
|
||||
let objectStore = db.transaction([objectStoreName], "readwrite")
|
||||
.objectStore(objectStoreName);
|
||||
request = objectStore.add(wasmData.wasm, wasmData.key);
|
||||
request.onsuccess = continueToNextStepSync;
|
||||
yield undefined;
|
||||
|
||||
is(request.result, wasmData.key, "Got correct key");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
|
@ -209,6 +209,11 @@ function resetTesting()
|
|||
SpecialPowers.clearUserPref("dom.indexedDB.testing");
|
||||
}
|
||||
|
||||
function enableWasm()
|
||||
{
|
||||
SpecialPowers.setBoolPref("javascript.options.wasm", true);
|
||||
}
|
||||
|
||||
function gc()
|
||||
{
|
||||
Cu.forceGC();
|
||||
|
@ -363,6 +368,20 @@ function getFile(name, type, str)
|
|||
return new File([str], name, {type: type});
|
||||
}
|
||||
|
||||
function isWasmSupported()
|
||||
{
|
||||
let testingFunctions = Cu.getJSTestingFunctions();
|
||||
return testingFunctions.wasmIsSupported();
|
||||
}
|
||||
|
||||
function getWasmModule(text)
|
||||
{
|
||||
let testingFunctions = Cu.getJSTestingFunctions();
|
||||
let binary = testingFunctions.wasmTextToBinary(text);
|
||||
let module = new WebAssembly.Module(binary);
|
||||
return module;
|
||||
}
|
||||
|
||||
function compareBuffers(buffer1, buffer2)
|
||||
{
|
||||
if (buffer1.byteLength != buffer2.byteLength) {
|
||||
|
|
|
@ -59,3 +59,4 @@ skip-if = true
|
|||
# bug 951017: intermittent failure on Android x86 emulator
|
||||
skip-if = os == "android" && processor == "x86"
|
||||
[test_view_put_get_values.js]
|
||||
[test_wasm_put_get_values.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче