mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-14 03:07:31 +09:00
Issue #1691 - Part 7d: Allow dynamic import in cases where there's no referencing script or module. Support dynamic import from classic scripts by creating ClassicScript objects and associating them with the compiled. https://bugzilla.mozilla.org/show_bug.cgi?id=1342012 This patch is incomplete, some code in ScriptLoader::EvaluateScript() could not be applied for missing dependencies. Part 7e will apply the missing dependencies and finish the patch.
(cherry picked from commit ce31a906e801b72f06385b0755710317ccf3658b)
This commit is contained in:
parent
41eda05e57
commit
d5d7bb5e47
6 changed files with 188 additions and 88 deletions
|
|
@ -20,13 +20,13 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(ModuleLoadRequest)
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ModuleLoadRequest,
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ModuleLoadRequest,
|
||||||
ScriptLoadRequest)
|
ScriptLoadRequest)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBaseURL, mLoader, mModuleScript, mImports)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoader, mModuleScript, mImports)
|
||||||
tmp->ClearDynamicImport();
|
tmp->ClearDynamicImport();
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ModuleLoadRequest,
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ModuleLoadRequest,
|
||||||
ScriptLoadRequest)
|
ScriptLoadRequest)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBaseURL, mLoader, mModuleScript, mImports)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoader, mModuleScript, mImports)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ModuleLoadRequest,
|
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ModuleLoadRequest,
|
||||||
|
|
@ -69,17 +69,18 @@ static VisitedURLSet* NewVisitedSetForTopLevelImport(nsIURI* aURI) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ ModuleLoadRequest* ModuleLoadRequest::CreateDynamicImport(
|
/* static */ ModuleLoadRequest* ModuleLoadRequest::CreateDynamicImport(
|
||||||
nsIURI* aURI, ModuleScript* aScript,
|
nsIURI* aURI, ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL,
|
||||||
JS::Handle<JS::Value> aReferencingPrivate, JS::Handle<JSString*> aSpecifier,
|
ScriptLoader* aLoader, JS::Handle<JS::Value> aReferencingPrivate,
|
||||||
JS::Handle<JSObject*> aPromise) {
|
JS::Handle<JSString*> aSpecifier, JS::Handle<JSObject*> aPromise)
|
||||||
|
{
|
||||||
MOZ_ASSERT(aSpecifier);
|
MOZ_ASSERT(aSpecifier);
|
||||||
MOZ_ASSERT(aPromise);
|
MOZ_ASSERT(aPromise);
|
||||||
|
|
||||||
auto request = new ModuleLoadRequest(
|
auto request = new ModuleLoadRequest(
|
||||||
aURI, aScript->FetchOptions(), SRIMetadata(), aScript->BaseURL(),
|
aURI, aFetchOptions, SRIMetadata(), aBaseURL,
|
||||||
true, /* is top level */
|
true, /* is top level */
|
||||||
true, /* is dynamic import */
|
true, /* is dynamic import */
|
||||||
aScript->Loader(), NewVisitedSetForTopLevelImport(aURI));
|
aLoader, NewVisitedSetForTopLevelImport(aURI));
|
||||||
|
|
||||||
request->mIsInline = false;
|
request->mIsInline = false;
|
||||||
request->mScriptMode = ScriptMode::eAsync;
|
request->mScriptMode = ScriptMode::eAsync;
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,8 @@ public:
|
||||||
|
|
||||||
// Create a module load request for dynamic module import.
|
// Create a module load request for dynamic module import.
|
||||||
static ModuleLoadRequest* CreateDynamicImport(
|
static ModuleLoadRequest* CreateDynamicImport(
|
||||||
nsIURI* aURI, ModuleScript* aScript,
|
nsIURI* aURI, ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL,
|
||||||
JS::Handle<JS::Value> aReferencingPrivate,
|
ScriptLoader* aLoader, JS::Handle<JS::Value> aReferencingPrivate,
|
||||||
JS::Handle<JSString*> aSpecifier, JS::Handle<JSObject*> aPromise);
|
JS::Handle<JSString*> aSpecifier, JS::Handle<JSObject*> aPromise);
|
||||||
|
|
||||||
bool IsTopLevel() const override {
|
bool IsTopLevel() const override {
|
||||||
|
|
@ -90,9 +90,6 @@ public:
|
||||||
// Is this the top level request for a dynamic module import?
|
// Is this the top level request for a dynamic module import?
|
||||||
const bool mIsDynamicImport;
|
const bool mIsDynamicImport;
|
||||||
|
|
||||||
// The base URL used for resolving relative module imports.
|
|
||||||
nsCOMPtr<nsIURI> mBaseURL;
|
|
||||||
|
|
||||||
// Pointer to the script loader, used to trigger actions when the module load
|
// Pointer to the script loader, used to trigger actions when the module load
|
||||||
// finishes.
|
// finishes.
|
||||||
RefPtr<ScriptLoader> mLoader;
|
RefPtr<ScriptLoader> mLoader;
|
||||||
|
|
|
||||||
|
|
@ -26,13 +26,11 @@ NS_INTERFACE_MAP_END
|
||||||
NS_IMPL_CYCLE_COLLECTION_CLASS(LoadedScript)
|
NS_IMPL_CYCLE_COLLECTION_CLASS(LoadedScript)
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(LoadedScript)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(LoadedScript)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoader)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFetchOptions)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFetchOptions)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBaseURL)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBaseURL)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(LoadedScript)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(LoadedScript)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoader)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFetchOptions)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFetchOptions)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
|
|
@ -42,28 +40,52 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(LoadedScript)
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(LoadedScript)
|
||||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(LoadedScript)
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(LoadedScript)
|
||||||
|
|
||||||
LoadedScript::LoadedScript(ScriptKind aKind, ScriptLoader* aLoader,
|
LoadedScript::LoadedScript(ScriptKind aKind,
|
||||||
ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL)
|
ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL)
|
||||||
: mKind(aKind),
|
: mKind(aKind),
|
||||||
mLoader(aLoader),
|
|
||||||
mFetchOptions(aFetchOptions),
|
mFetchOptions(aFetchOptions),
|
||||||
mBaseURL(aBaseURL)
|
mBaseURL(aBaseURL)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mLoader);
|
|
||||||
MOZ_ASSERT(mFetchOptions);
|
MOZ_ASSERT(mFetchOptions);
|
||||||
MOZ_ASSERT(mBaseURL);
|
MOZ_ASSERT(mBaseURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadedScript::~LoadedScript() { DropJSObjects(this); }
|
LoadedScript::~LoadedScript() { DropJSObjects(this); }
|
||||||
|
|
||||||
|
void LoadedScript::AssociateWithScript(JSScript* aScript) {
|
||||||
|
// Set a JSScript's private value to point to this object and
|
||||||
|
// increment our reference count. This is decremented by
|
||||||
|
// HostFinalizeTopLevelScript() below when the JSScript dies.
|
||||||
|
|
||||||
|
MOZ_ASSERT(JS::GetScriptPrivate(aScript).isUndefined());
|
||||||
|
JS::SetScriptPrivate(aScript, JS::PrivateValue(this));
|
||||||
|
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());
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (script->IsModuleScript()) {
|
||||||
|
JSObject* module = script->AsModuleScript()->mModuleRecord.unbarrieredGet();
|
||||||
|
MOZ_ASSERT(JS::GetModulePrivate(module) == aPrivate);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
script->Release();
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
// ClassicScript
|
// ClassicScript
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ClassicScript::ClassicScript(ScriptLoader* aLoader,
|
ClassicScript::ClassicScript(ScriptFetchOptions* aFetchOptions,
|
||||||
ScriptFetchOptions* aFetchOptions,
|
|
||||||
nsIURI* aBaseURL)
|
nsIURI* aBaseURL)
|
||||||
: LoadedScript(ScriptKind::Classic, aLoader, aFetchOptions, aBaseURL) {}
|
: LoadedScript(ScriptKind::Classic, aFetchOptions, aBaseURL) {}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
// ModuleScript
|
// ModuleScript
|
||||||
|
|
@ -92,9 +114,8 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||||
NS_IMPL_ADDREF_INHERITED(ModuleScript, LoadedScript)
|
NS_IMPL_ADDREF_INHERITED(ModuleScript, LoadedScript)
|
||||||
NS_IMPL_RELEASE_INHERITED(ModuleScript, LoadedScript)
|
NS_IMPL_RELEASE_INHERITED(ModuleScript, LoadedScript)
|
||||||
|
|
||||||
ModuleScript::ModuleScript(ScriptLoader* aLoader,
|
ModuleScript::ModuleScript(ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL)
|
||||||
ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL)
|
: LoadedScript(ScriptKind::Module, aFetchOptions, aBaseURL) {
|
||||||
: LoadedScript(ScriptKind::Module, aLoader, aFetchOptions, aBaseURL) {
|
|
||||||
MOZ_ASSERT(!ModuleRecord());
|
MOZ_ASSERT(!ModuleRecord());
|
||||||
MOZ_ASSERT(!HasParseError());
|
MOZ_ASSERT(!HasParseError());
|
||||||
MOZ_ASSERT(!HasErrorToRethrow());
|
MOZ_ASSERT(!HasErrorToRethrow());
|
||||||
|
|
@ -150,15 +171,6 @@ ModuleScript::SetParseError(const JS::Value& aError)
|
||||||
AddRef();
|
AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostFinalizeTopLevelScript(JSFreeOp* aFop, const JS::Value& aPrivate) {
|
|
||||||
auto script = static_cast<ModuleScript*>(aPrivate.toPrivate());
|
|
||||||
if (script) {
|
|
||||||
MOZ_ASSERT(JS::GetModulePrivate(script->mModuleRecord.unbarrieredGet()) ==
|
|
||||||
aPrivate);
|
|
||||||
script->UnlinkModuleRecord();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ModuleScript::SetErrorToRethrow(const JS::Value& aError)
|
ModuleScript::SetErrorToRethrow(const JS::Value& aError)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,8 @@ class LoadedScript : public nsISupports
|
||||||
nsCOMPtr<nsIURI> mBaseURL;
|
nsCOMPtr<nsIURI> mBaseURL;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
LoadedScript(ScriptKind aKind, ScriptLoader* aLoader,
|
LoadedScript(ScriptKind aKind,
|
||||||
ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL);
|
ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL);
|
||||||
|
|
||||||
virtual ~LoadedScript();
|
virtual ~LoadedScript();
|
||||||
|
|
||||||
|
|
@ -45,9 +45,10 @@ class LoadedScript : public nsISupports
|
||||||
inline ClassicScript* AsClassicScript();
|
inline ClassicScript* AsClassicScript();
|
||||||
inline ModuleScript* AsModuleScript();
|
inline ModuleScript* AsModuleScript();
|
||||||
|
|
||||||
ScriptLoader* Loader() const { return mLoader; }
|
|
||||||
ScriptFetchOptions* FetchOptions() const { return mFetchOptions; }
|
ScriptFetchOptions* FetchOptions() const { return mFetchOptions; }
|
||||||
nsIURI* BaseURL() const { return mBaseURL; }
|
nsIURI* BaseURL() const { return mBaseURL; }
|
||||||
|
|
||||||
|
void AssociateWithScript(JSScript* aScript);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ClassicScript final : public LoadedScript
|
class ClassicScript final : public LoadedScript
|
||||||
|
|
@ -55,8 +56,7 @@ class ClassicScript final : public LoadedScript
|
||||||
~ClassicScript() = default;
|
~ClassicScript() = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ClassicScript(ScriptLoader* aLoader, ScriptFetchOptions* aFetchOptions,
|
ClassicScript(ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL);
|
||||||
nsIURI* aBaseURL);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// A single module script. May be used to satisfy multiple load requests.
|
// A single module script. May be used to satisfy multiple load requests.
|
||||||
|
|
@ -74,8 +74,7 @@ public:
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ModuleScript,
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ModuleScript,
|
||||||
LoadedScript)
|
LoadedScript)
|
||||||
|
|
||||||
ModuleScript(ScriptLoader* aLoader, ScriptFetchOptions* aFetchOptions,
|
ModuleScript(ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL);
|
||||||
nsIURI* aBaseURL);
|
|
||||||
|
|
||||||
void SetModuleRecord(JS::Handle<JSObject*> aModuleRecord);
|
void SetModuleRecord(JS::Handle<JSObject*> aModuleRecord);
|
||||||
void SetParseError(const JS::Value& aError);
|
void SetParseError(const JS::Value& aError);
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
#include "mozilla/dom/SRILogHelper.h"
|
#include "mozilla/dom/SRILogHelper.h"
|
||||||
#include "nsGkAtoms.h"
|
#include "nsGkAtoms.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
|
#include "nsGlobalWindow.h"
|
||||||
#include "nsIScriptGlobalObject.h"
|
#include "nsIScriptGlobalObject.h"
|
||||||
#include "nsIScriptContext.h"
|
#include "nsIScriptContext.h"
|
||||||
#include "nsIScriptSecurityManager.h"
|
#include "nsIScriptSecurityManager.h"
|
||||||
|
|
@ -638,7 +639,7 @@ ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest)
|
||||||
MOZ_ASSERT(NS_SUCCEEDED(rv) == (module != nullptr));
|
MOZ_ASSERT(NS_SUCCEEDED(rv) == (module != nullptr));
|
||||||
|
|
||||||
RefPtr<ModuleScript> moduleScript =
|
RefPtr<ModuleScript> moduleScript =
|
||||||
new ModuleScript(this, aRequest->mFetchOptions, aRequest->mBaseURL);
|
new ModuleScript(aRequest->mFetchOptions, aRequest->mBaseURL);
|
||||||
aRequest->mModuleScript = moduleScript;
|
aRequest->mModuleScript = moduleScript;
|
||||||
|
|
||||||
if (!module) {
|
if (!module) {
|
||||||
|
|
@ -711,8 +712,7 @@ HandleResolveFailure(JSContext* aCx, ModuleScript* aScript,
|
||||||
}
|
}
|
||||||
|
|
||||||
static already_AddRefed<nsIURI>
|
static already_AddRefed<nsIURI>
|
||||||
ResolveModuleSpecifier(ModuleScript* aScript,
|
ResolveModuleSpecifier(ScriptLoader* aLoader, LoadedScript* aScript, const nsAString& aSpecifier)
|
||||||
const nsAString& aSpecifier)
|
|
||||||
{
|
{
|
||||||
// The following module specifiers are allowed by the spec:
|
// The following module specifiers are allowed by the spec:
|
||||||
// - a valid absolute URL
|
// - a valid absolute URL
|
||||||
|
|
@ -737,7 +737,15 @@ ResolveModuleSpecifier(ModuleScript* aScript,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = NS_NewURI(getter_AddRefs(uri), aSpecifier, nullptr, aScript->BaseURL());
|
// Get the document's base URL if we don't have a referencing script here.
|
||||||
|
nsCOMPtr<nsIURI> baseURL;
|
||||||
|
if (aScript) {
|
||||||
|
baseURL = aScript->BaseURL();
|
||||||
|
} else {
|
||||||
|
baseURL = aLoader->GetDocument()->GetDocBaseURI();
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = NS_NewURI(getter_AddRefs(uri), aSpecifier, nullptr, baseURL);
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
return uri.forget();
|
return uri.forget();
|
||||||
}
|
}
|
||||||
|
|
@ -776,7 +784,8 @@ ResolveRequestedModules(ModuleLoadRequest* aRequest, nsCOMArray<nsIURI>* aUrlsOu
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let url be the result of resolving a module specifier given module script and requested.
|
// Let url be the result of resolving a module specifier given module script and requested.
|
||||||
nsCOMPtr<nsIURI> uri = ResolveModuleSpecifier(ms, specifier);
|
nsCOMPtr<nsIURI> uri =
|
||||||
|
ResolveModuleSpecifier(aRequest->mLoader, ms, specifier);
|
||||||
if (!uri) {
|
if (!uri) {
|
||||||
nsresult rv = HandleResolveFailure(cx, ms, specifier);
|
nsresult rv = HandleResolveFailure(cx, ms, specifier);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
@ -869,34 +878,83 @@ ScriptLoader::StartFetchingModuleAndDependencies(ModuleLoadRequest* aParent,
|
||||||
return ready;
|
return ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ScriptLoader* GetCurrentScriptLoader(JSContext* aCx) {
|
||||||
|
JSObject* object = JS::CurrentGlobalOrNull(aCx);
|
||||||
|
if (!object) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIGlobalObject* global = xpc::NativeGlobal(object);
|
||||||
|
if (!global) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(global);
|
||||||
|
nsGlobalWindow* window = nsGlobalWindow::Cast(win);
|
||||||
|
if (!window) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIDocument* document = window->GetDocument();
|
||||||
|
if (!document) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptLoader* loader = document->ScriptLoader();
|
||||||
|
if (!loader) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return loader;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LoadedScript* GetLoadedScriptOrNull(
|
||||||
|
JSContext* aCx, JS::Handle<JS::Value> aReferencingPrivate) {
|
||||||
|
if (aReferencingPrivate.isUndefined()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto script = static_cast<LoadedScript*>(aReferencingPrivate.toPrivate());
|
||||||
|
MOZ_ASSERT_IF(
|
||||||
|
script->IsModuleScript(),
|
||||||
|
JS::GetModulePrivate(script->AsModuleScript()->ModuleRecord()) ==
|
||||||
|
aReferencingPrivate);
|
||||||
|
|
||||||
|
return script;
|
||||||
|
}
|
||||||
|
|
||||||
// 8.1.3.8.1 HostResolveImportedModule(referencingModule, specifier)
|
// 8.1.3.8.1 HostResolveImportedModule(referencingModule, specifier)
|
||||||
JSObject*
|
JSObject*
|
||||||
HostResolveImportedModule(JSContext* aCx,
|
HostResolveImportedModule(JSContext* aCx,
|
||||||
JS::Handle<JS::Value> aReferencingPrivate,
|
JS::Handle<JS::Value> aReferencingPrivate,
|
||||||
JS::Handle<JSString*> aSpecifier)
|
JS::Handle<JSString*> aSpecifier)
|
||||||
{
|
{
|
||||||
// Let referencing module script be referencingModule.[[HostDefined]].
|
JS::Rooted<JSObject*> module(aCx);
|
||||||
if (aReferencingPrivate.isUndefined()) {
|
ScriptLoader::ResolveImportedModule(aCx, aReferencingPrivate, aSpecifier,
|
||||||
JS_ReportErrorNumberUC(aCx, js::GetErrorMessage, nullptr,
|
&module);
|
||||||
JSMSG_IMPORT_SCRIPT_NOT_FOUND);
|
return module;
|
||||||
return nullptr;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
auto script = static_cast<ModuleScript*>(aReferencingPrivate.toPrivate());
|
/* static */ void ScriptLoader::ResolveImportedModule(
|
||||||
MOZ_ASSERT(JS::GetModulePrivate(script->ModuleRecord()) == aReferencingPrivate);
|
JSContext* aCx, JS::Handle<JS::Value> aReferencingPrivate,
|
||||||
|
JS::Handle<JSString*> aSpecifier, JS::MutableHandle<JSObject*> aModuleOut) {
|
||||||
|
MOZ_ASSERT(!aModuleOut);
|
||||||
|
|
||||||
|
RefPtr<LoadedScript> script(GetLoadedScriptOrNull(aCx, aReferencingPrivate));
|
||||||
|
|
||||||
// Let url be the result of resolving a module specifier given referencing
|
// Let url be the result of resolving a module specifier given referencing
|
||||||
// module script and specifier.
|
// module script and specifier.
|
||||||
nsAutoJSString string;
|
nsAutoJSString string;
|
||||||
if (!string.init(aCx, aSpecifier)) {
|
if (!string.init(aCx, aSpecifier)) {
|
||||||
return nullptr;
|
return;
|
||||||
}
|
|
||||||
if (!script || !aCx) {
|
|
||||||
// Our module context was ripped out from under us...
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> uri = ResolveModuleSpecifier(script, string);
|
RefPtr<ScriptLoader> loader = GetCurrentScriptLoader(aCx);
|
||||||
|
if (!loader) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIURI> uri = ResolveModuleSpecifier(loader, script, string);
|
||||||
|
|
||||||
// This cannot fail because resolving a module specifier must have been
|
// This cannot fail because resolving a module specifier must have been
|
||||||
// previously successful with these same two arguments.
|
// previously successful with these same two arguments.
|
||||||
|
|
@ -905,17 +963,13 @@ HostResolveImportedModule(JSContext* aCx,
|
||||||
// Let resolved module script be moduleMap[url]. (This entry must exist for us
|
// Let resolved module script be moduleMap[url]. (This entry must exist for us
|
||||||
// to have gotten to this point.)
|
// to have gotten to this point.)
|
||||||
|
|
||||||
ModuleScript* ms = script->Loader()->GetFetchedModule(uri);
|
ModuleScript* ms = loader->GetFetchedModule(uri);
|
||||||
MOZ_ASSERT(ms, "Resolved module not found in module map");
|
MOZ_ASSERT(ms, "Resolved module not found in module map");
|
||||||
if (!ms) {
|
|
||||||
// Already-resolved module has been removed from the map/unloaded...
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT(!ms->HasParseError());
|
MOZ_ASSERT(!ms->HasParseError());
|
||||||
MOZ_ASSERT(ms->ModuleRecord());
|
MOZ_ASSERT(ms->ModuleRecord());
|
||||||
|
|
||||||
return ms->ModuleRecord();
|
aModuleOut.set(ms->ModuleRecord());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -950,15 +1004,7 @@ bool HostImportModuleDynamically(JSContext* aCx,
|
||||||
JS::Handle<JS::Value> aReferencingPrivate,
|
JS::Handle<JS::Value> aReferencingPrivate,
|
||||||
JS::Handle<JSString*> aSpecifier,
|
JS::Handle<JSString*> aSpecifier,
|
||||||
JS::Handle<JSObject*> aPromise) {
|
JS::Handle<JSObject*> aPromise) {
|
||||||
if (aReferencingPrivate.isUndefined()) {
|
RefPtr<LoadedScript> script(GetLoadedScriptOrNull(aCx, aReferencingPrivate));
|
||||||
JS_ReportErrorNumberUC(aCx, js::GetErrorMessage, nullptr,
|
|
||||||
JSMSG_IMPORT_SCRIPT_NOT_FOUND);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto script = static_cast<ModuleScript*>(aReferencingPrivate.toPrivate());
|
|
||||||
MOZ_ASSERT(JS::GetModulePrivate(script->ModuleRecord()) ==
|
|
||||||
aReferencingPrivate);
|
|
||||||
|
|
||||||
// Attempt to resolve the module specifier.
|
// Attempt to resolve the module specifier.
|
||||||
nsAutoJSString string;
|
nsAutoJSString string;
|
||||||
|
|
@ -966,7 +1012,12 @@ bool HostImportModuleDynamically(JSContext* aCx,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> uri = ResolveModuleSpecifier(script, string);
|
RefPtr<ScriptLoader> loader = GetCurrentScriptLoader(aCx);
|
||||||
|
if (!loader) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIURI> uri = ResolveModuleSpecifier(loader, script, string);
|
||||||
if (!uri) {
|
if (!uri) {
|
||||||
JS_ReportErrorNumberUC(aCx, js::GetErrorMessage, nullptr,
|
JS_ReportErrorNumberUC(aCx, js::GetErrorMessage, nullptr,
|
||||||
JSMSG_BAD_MODULE_SPECIFIER, string.get());
|
JSMSG_BAD_MODULE_SPECIFIER, string.get());
|
||||||
|
|
@ -974,10 +1025,27 @@ bool HostImportModuleDynamically(JSContext* aCx,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new top-level load request.
|
// Create a new top-level load request.
|
||||||
RefPtr<ModuleLoadRequest> request = ModuleLoadRequest::CreateDynamicImport(
|
ScriptFetchOptions* options;
|
||||||
uri, script, aReferencingPrivate, aSpecifier, aPromise);
|
nsIURI* baseURL;
|
||||||
|
if (script) {
|
||||||
|
options = script->FetchOptions();
|
||||||
|
baseURL = script->BaseURL();
|
||||||
|
} else {
|
||||||
|
// We don't have a referencing script so fall back on using
|
||||||
|
// options from the document. This can happen when the user
|
||||||
|
// triggers an inline event handler, as there is no active script
|
||||||
|
// there.
|
||||||
|
nsIDocument* document = loader->GetDocument();
|
||||||
|
options = new ScriptFetchOptions(mozilla::CORS_NONE,
|
||||||
|
document->GetReferrerPolicy(), nullptr,
|
||||||
|
document->NodePrincipal());
|
||||||
|
baseURL = document->GetDocBaseURI();
|
||||||
|
}
|
||||||
|
|
||||||
script->Loader()->StartDynamicImport(request);
|
RefPtr<ModuleLoadRequest> request = ModuleLoadRequest::CreateDynamicImport(
|
||||||
|
uri, options, baseURL, loader, aReferencingPrivate, aSpecifier, aPromise);
|
||||||
|
|
||||||
|
loader->StartDynamicImport(request);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1700,7 +1768,8 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||||
|
|
||||||
if (request->IsModuleRequest()) {
|
if (request->IsModuleRequest()) {
|
||||||
ModuleLoadRequest* modReq = request->AsModuleRequest();
|
ModuleLoadRequest* modReq = request->AsModuleRequest();
|
||||||
modReq->mBaseURL = mDocument->GetDocBaseURI();
|
|
||||||
|
request->mBaseURL = mDocument->GetDocBaseURI();
|
||||||
|
|
||||||
if (aElement->GetScriptAsync()) {
|
if (aElement->GetScriptAsync()) {
|
||||||
AddAsyncRequest(modReq);
|
AddAsyncRequest(modReq);
|
||||||
|
|
@ -2801,6 +2870,18 @@ ScriptLoader::PrepareLoadedRequest(ScriptLoadRequest* aRequest,
|
||||||
mParserBlockingRequest == aRequest,
|
mParserBlockingRequest == aRequest,
|
||||||
"aRequest should be pending!");
|
"aRequest should be pending!");
|
||||||
|
|
||||||
|
nsCOMPtr<nsIURI> uri;
|
||||||
|
rv = channel->GetOriginalURI(getter_AddRefs(uri));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// Fixup moz-extension: and resource: URIs, because the channel URI will
|
||||||
|
// point to file:, which won't be allowed to load.
|
||||||
|
if (uri && IsInternalURIScheme(uri)) {
|
||||||
|
aRequest->mBaseURL = uri;
|
||||||
|
} else {
|
||||||
|
channel->GetURI(getter_AddRefs(aRequest->mBaseURL));
|
||||||
|
}
|
||||||
|
|
||||||
if (aRequest->IsModuleRequest()) {
|
if (aRequest->IsModuleRequest()) {
|
||||||
ModuleLoadRequest* request = aRequest->AsModuleRequest();
|
ModuleLoadRequest* request = aRequest->AsModuleRequest();
|
||||||
|
|
||||||
|
|
@ -2813,18 +2894,6 @@ ScriptLoader::PrepareLoadedRequest(ScriptLoadRequest* aRequest,
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> uri;
|
|
||||||
rv = channel->GetOriginalURI(getter_AddRefs(uri));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// Fixup internal scheme URIs like resource:, because the channel URI
|
|
||||||
// will point to file: which won't be allowed to load.
|
|
||||||
if (uri && IsInternalURIScheme(uri)) {
|
|
||||||
request->mBaseURL = uri;
|
|
||||||
} else {
|
|
||||||
channel->GetURI(getter_AddRefs(request->mBaseURL));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to compile off main thread.
|
// Attempt to compile off main thread.
|
||||||
rv = AttemptAsyncScriptCompile(request);
|
rv = AttemptAsyncScriptCompile(request);
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
|
|
||||||
|
|
@ -258,6 +258,9 @@ public:
|
||||||
// Holds the top-level JSScript that corresponds to the current source, once
|
// Holds the top-level JSScript that corresponds to the current source, once
|
||||||
// it is parsed, and planned to be saved in the bytecode cache.
|
// it is parsed, and planned to be saved in the bytecode cache.
|
||||||
JS::Heap<JSScript*> mScript;
|
JS::Heap<JSScript*> mScript;
|
||||||
|
|
||||||
|
// The base URL used for resolving relative module imports.
|
||||||
|
nsCOMPtr<nsIURI> mBaseURL;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ScriptLoadRequestList : private mozilla::LinkedList<ScriptLoadRequest>
|
class ScriptLoadRequestList : private mozilla::LinkedList<ScriptLoadRequest>
|
||||||
|
|
@ -561,11 +564,30 @@ public:
|
||||||
*/
|
*/
|
||||||
void ClearModuleMap();
|
void ClearModuleMap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement the HostResolveImportedModule abstract operation.
|
||||||
|
*
|
||||||
|
* Resolve a module specifier string and look this up in the module
|
||||||
|
* map, returning the result. This is only called for previously
|
||||||
|
* loaded modules and always succeeds.
|
||||||
|
*
|
||||||
|
* @param aReferencingPrivate A JS::Value which is either undefined
|
||||||
|
* or contains a LoadedScript private pointer.
|
||||||
|
* @param aSpecifier The module specifier.
|
||||||
|
* @param aModuleOut This is set to the module found.
|
||||||
|
*/
|
||||||
|
static void ResolveImportedModule(JSContext* aCx,
|
||||||
|
JS::Handle<JS::Value> aReferencingPrivate,
|
||||||
|
JS::Handle<JSString*> aSpecifier,
|
||||||
|
JS::MutableHandle<JSObject*> aModuleOut);
|
||||||
|
|
||||||
void StartDynamicImport(ModuleLoadRequest* aRequest);
|
void StartDynamicImport(ModuleLoadRequest* aRequest);
|
||||||
void FinishDynamicImport(ModuleLoadRequest* aRequest, nsresult aResult);
|
void FinishDynamicImport(ModuleLoadRequest* aRequest, nsresult aResult);
|
||||||
void FinishDynamicImport(JSContext* aCx, ModuleLoadRequest* aRequest,
|
void FinishDynamicImport(JSContext* aCx, ModuleLoadRequest* aRequest,
|
||||||
nsresult aResult);
|
nsresult aResult);
|
||||||
|
|
||||||
|
nsIDocument* GetDocument() const { return mDocument; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual ~ScriptLoader();
|
virtual ~ScriptLoader();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue