mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-09 09:18:42 +09:00
Issue #2387 - Collection of fixes related to a crash while canceling a dynamic import. Add AddRef/Release hooks for embedding's script or module private value and set this script source object where appropriate. https://bugzilla.mozilla.org/show_bug.cgi?id=1519140 Partial, no Value passing changes. Clear the list of dynamic import requests after cancelling them in ScriptLoader::ParsingComplete as we do for other requests. https://bugzilla.mozilla.org/show_bug.cgi?id=1291535 ScriptLoader::OnStreamComplete never returns a failure. https://bugzilla.mozilla.org/show_bug.cgi?id=1627275 Also cancel the correct kind of parser for Modules.
This commit is contained in:
parent
56bcdf7ca0
commit
eef37b2cd5
10 changed files with 100 additions and 54 deletions
|
|
@ -62,20 +62,33 @@ void LoadedScript::AssociateWithScript(JSScript* aScript) {
|
|||
AddRef();
|
||||
}
|
||||
|
||||
void HostFinalizeTopLevelScript(JSFreeOp* aFop, const JS::Value& aPrivate) {
|
||||
// Decrement the reference count of a LoadedScript object that is
|
||||
// pointed to by a dying JSScript. The reference count was
|
||||
// originally incremented by AssociateWithScript() above.
|
||||
|
||||
auto script = static_cast<LoadedScript*>(aPrivate.toPrivate());
|
||||
|
||||
inline void CheckModuleScriptPrivate(LoadedScript* script,
|
||||
const JS::Value& aPrivate) {
|
||||
#ifdef DEBUG
|
||||
if (script->IsModuleScript()) {
|
||||
JSObject* module = script->AsModuleScript()->mModuleRecord.unbarrieredGet();
|
||||
MOZ_ASSERT_IF(module, JS::GetModulePrivate(module) == aPrivate);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void HostAddRefTopLevelScript(const JS::Value& aPrivate) {
|
||||
// Increment the reference count of a LoadedScript object that is now pointed
|
||||
// to by a JSScript. The reference count is decremented by
|
||||
// HostReleaseTopLevelScript() below.
|
||||
|
||||
auto script = static_cast<LoadedScript*>(aPrivate.toPrivate());
|
||||
CheckModuleScriptPrivate(script, aPrivate);
|
||||
script->AddRef();
|
||||
}
|
||||
|
||||
void HostReleaseTopLevelScript(const JS::Value& aPrivate) {
|
||||
// Decrement the reference count of a LoadedScript object that was pointed to
|
||||
// by a JSScript. The reference count was originally incremented by
|
||||
// HostAddRefTopLevelScript() above.
|
||||
|
||||
auto script = static_cast<LoadedScript*>(aPrivate.toPrivate());
|
||||
CheckModuleScriptPrivate(script, aPrivate);
|
||||
script->Release();
|
||||
}
|
||||
|
||||
|
|
@ -132,7 +145,6 @@ ModuleScript::UnlinkModuleRecord()
|
|||
this);
|
||||
JS::SetModulePrivate(mModuleRecord, JS::UndefinedValue());
|
||||
mModuleRecord = nullptr;
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -157,7 +169,6 @@ ModuleScript::SetModuleRecord(JS::Handle<JSObject*> aModuleRecord)
|
|||
MOZ_ASSERT(JS::GetModulePrivate(mModuleRecord).isUndefined());
|
||||
JS::SetModulePrivate(mModuleRecord, JS::PrivateValue(this));
|
||||
HoldJSObjects(this);
|
||||
AddRef();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ namespace dom {
|
|||
|
||||
class ScriptLoader;
|
||||
|
||||
void HostFinalizeTopLevelScript(JSFreeOp* aFop, const JS::Value& aPrivate);
|
||||
void HostAddRefTopLevelScript(const JS::Value& aPrivate);
|
||||
void HostReleaseTopLevelScript(const JS::Value& aPrivate);
|
||||
|
||||
class ClassicScript;
|
||||
class ModuleScript;
|
||||
|
|
@ -63,7 +64,6 @@ class ClassicScript final : public LoadedScript
|
|||
|
||||
class ModuleScript final : public LoadedScript
|
||||
{
|
||||
JS::Heap<JSObject*> mModuleRecord;
|
||||
JS::Heap<JS::Value> mParseError;
|
||||
JS::Heap<JS::Value> mErrorToRethrow;
|
||||
|
||||
|
|
@ -74,6 +74,8 @@ public:
|
|||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ModuleScript,
|
||||
LoadedScript)
|
||||
|
||||
JS::Heap<JSObject*> mModuleRecord;
|
||||
|
||||
ModuleScript(ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL);
|
||||
|
||||
void SetModuleRecord(JS::Handle<JSObject*> aModuleRecord);
|
||||
|
|
@ -89,7 +91,7 @@ public:
|
|||
|
||||
void UnlinkModuleRecord();
|
||||
|
||||
friend void HostFinalizeTopLevelScript(JSFreeOp*, const JS::Value&);
|
||||
friend void CheckModuleScriptPrivate(LoadedScript*, const JS::Value&);
|
||||
};
|
||||
|
||||
ClassicScript* LoadedScript::AsClassicScript() {
|
||||
|
|
|
|||
|
|
@ -185,7 +185,11 @@ ScriptLoadRequest::MaybeCancelOffThreadScript()
|
|||
}
|
||||
|
||||
JSContext* cx = danger::GetJSContext();
|
||||
JS::CancelOffThreadScript(cx, mOffThreadToken);
|
||||
if (IsModuleRequest()) {
|
||||
JS::CancelOffThreadModule(cx, mOffThreadToken);
|
||||
} else {
|
||||
JS::CancelOffThreadScript(cx, mOffThreadToken);
|
||||
}
|
||||
mOffThreadToken = nullptr;
|
||||
}
|
||||
|
||||
|
|
@ -1109,8 +1113,9 @@ void ScriptLoader::EnsureModuleHooksInitialized() {
|
|||
|
||||
JS::SetModuleResolveHook(rt, HostResolveImportedModule);
|
||||
JS::SetModuleMetadataHook(jsapi.cx(), HostPopulateImportMeta);
|
||||
JS::SetScriptPrivateFinalizeHook(jsapi.cx(), HostFinalizeTopLevelScript);
|
||||
|
||||
JS::SetScriptPrivateReferenceHooks(jsapi.cx(), HostAddRefTopLevelScript,
|
||||
HostReleaseTopLevelScript);
|
||||
|
||||
Preferences::RegisterCallbackAndCall(DynamicImportPrefChangedCallback,
|
||||
"javascript.options.dynamicImport",
|
||||
(void*)nullptr);
|
||||
|
|
@ -2648,7 +2653,7 @@ ScriptLoader::OnStreamComplete(nsIIncrementalStreamLoader* aLoader,
|
|||
// Process our request and/or any pending ones
|
||||
ProcessPendingRequests();
|
||||
|
||||
return NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
@ -2758,6 +2763,9 @@ ScriptLoader::HandleLoadError(ScriptLoadRequest *aRequest, nsresult aResult) {
|
|||
if (aRequest->isInList()) {
|
||||
RefPtr<ScriptLoadRequest> req = mDynamicImportRequests.Steal(aRequest);
|
||||
modReq->Cancel();
|
||||
// FinishDynamicImport must happen exactly once for each dynamic import
|
||||
// request. If the load is aborted we do it when we remove the request
|
||||
// from mDynamicImportRequests.
|
||||
FinishDynamicImport(modReq, aResult);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -2979,8 +2987,12 @@ ScriptLoader::ParsingComplete(bool aTerminated)
|
|||
for (ScriptLoadRequest* req = mDynamicImportRequests.getFirst(); req;
|
||||
req = req->getNext()) {
|
||||
req->Cancel();
|
||||
// FinishDynamicImport must happen exactly once for each dynamic import
|
||||
// request. If the load is aborted we do it when we remove the request
|
||||
// from mDynamicImportRequests.
|
||||
FinishDynamicImport(req->AsModuleRequest(), NS_ERROR_ABORT);
|
||||
}
|
||||
mDynamicImportRequests.Clear();
|
||||
|
||||
if (mParserBlockingRequest) {
|
||||
mParserBlockingRequest->Cancel();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue