зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1342012 - Initial browser support for dynamic import from module scripts r=smaug
This commit is contained in:
Родитель
20a91427ef
Коммит
ce265eb48d
|
@ -5,6 +5,9 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ModuleLoadRequest.h"
|
||||
|
||||
#include "mozilla/HoldDropJSObjects.h"
|
||||
|
||||
#include "ModuleScript.h"
|
||||
#include "ScriptLoader.h"
|
||||
|
||||
|
@ -18,35 +21,92 @@ namespace dom {
|
|||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ModuleLoadRequest)
|
||||
NS_INTERFACE_MAP_END_INHERITING(ScriptLoadRequest)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(ModuleLoadRequest, ScriptLoadRequest,
|
||||
mBaseURL, mLoader, mModuleScript, mImports)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(ModuleLoadRequest)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ModuleLoadRequest,
|
||||
ScriptLoadRequest)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBaseURL, mLoader, mModuleScript, mImports)
|
||||
tmp->ClearDynamicImport();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ModuleLoadRequest,
|
||||
ScriptLoadRequest)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBaseURL, mLoader, mModuleScript, mImports)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ModuleLoadRequest,
|
||||
ScriptLoadRequest)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDynamicReferencingPrivate)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDynamicSpecifier)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDynamicPromise)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(ModuleLoadRequest, ScriptLoadRequest)
|
||||
NS_IMPL_RELEASE_INHERITED(ModuleLoadRequest, ScriptLoadRequest)
|
||||
|
||||
ModuleLoadRequest::ModuleLoadRequest(nsIURI* aURI,
|
||||
ScriptFetchOptions* aFetchOptions,
|
||||
const SRIMetadata& aIntegrity,
|
||||
nsIURI* aReferrer, ScriptLoader* aLoader)
|
||||
static VisitedURLSet* NewVisitedSetForTopLevelImport(nsIURI* aURI) {
|
||||
auto set = new VisitedURLSet();
|
||||
set->PutEntry(aURI);
|
||||
return set;
|
||||
}
|
||||
|
||||
/* static */ ModuleLoadRequest* ModuleLoadRequest::CreateTopLevel(
|
||||
nsIURI* aURI, ScriptFetchOptions* aFetchOptions,
|
||||
const SRIMetadata& aIntegrity, nsIURI* aReferrer, ScriptLoader* aLoader) {
|
||||
return new ModuleLoadRequest(aURI, aFetchOptions, aIntegrity, aReferrer,
|
||||
true, /* is top level */
|
||||
false, /* is dynamic import */
|
||||
aLoader, NewVisitedSetForTopLevelImport(aURI));
|
||||
}
|
||||
|
||||
/* static */ ModuleLoadRequest* ModuleLoadRequest::CreateStaticImport(
|
||||
nsIURI* aURI, ModuleLoadRequest* aParent) {
|
||||
auto request =
|
||||
new ModuleLoadRequest(aURI, aParent->mFetchOptions, SRIMetadata(),
|
||||
aParent->mURI, false, /* is top level */
|
||||
false, /* is dynamic import */
|
||||
aParent->mLoader, aParent->mVisitedSet);
|
||||
|
||||
request->mIsInline = false;
|
||||
request->mScriptMode = aParent->mScriptMode;
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
/* static */ ModuleLoadRequest* ModuleLoadRequest::CreateDynamicImport(
|
||||
nsIURI* aURI, ModuleScript* aScript,
|
||||
JS::Handle<JS::Value> aReferencingPrivate, JS::Handle<JSString*> aSpecifier,
|
||||
JS::Handle<JSObject*> aPromise) {
|
||||
MOZ_ASSERT(aSpecifier);
|
||||
MOZ_ASSERT(aPromise);
|
||||
|
||||
auto request = new ModuleLoadRequest(
|
||||
aURI, aScript->FetchOptions(), SRIMetadata(), aScript->BaseURL(),
|
||||
true, /* is top level */
|
||||
true, /* is dynamic import */
|
||||
aScript->Loader(), NewVisitedSetForTopLevelImport(aURI));
|
||||
|
||||
request->mIsInline = false;
|
||||
request->mScriptMode = ScriptMode::eAsync;
|
||||
request->mDynamicReferencingPrivate = aReferencingPrivate;
|
||||
request->mDynamicSpecifier = aSpecifier;
|
||||
request->mDynamicPromise = aPromise;
|
||||
|
||||
HoldJSObjects(request);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
ModuleLoadRequest::ModuleLoadRequest(
|
||||
nsIURI* aURI, ScriptFetchOptions* aFetchOptions,
|
||||
const SRIMetadata& aIntegrity, nsIURI* aReferrer, bool aIsTopLevel,
|
||||
bool aIsDynamicImport, ScriptLoader* aLoader, VisitedURLSet* aVisitedSet)
|
||||
: ScriptLoadRequest(ScriptKind::eModule, aURI, aFetchOptions, aIntegrity,
|
||||
aReferrer),
|
||||
mIsTopLevel(true),
|
||||
mIsTopLevel(aIsTopLevel),
|
||||
mIsDynamicImport(aIsDynamicImport),
|
||||
mLoader(aLoader),
|
||||
mVisitedSet(new VisitedURLSet()) {
|
||||
mVisitedSet->PutEntry(aURI);
|
||||
}
|
||||
|
||||
ModuleLoadRequest::ModuleLoadRequest(nsIURI* aURI, ModuleLoadRequest* aParent)
|
||||
: ScriptLoadRequest(ScriptKind::eModule, aURI, aParent->mFetchOptions,
|
||||
SRIMetadata(), aParent->mURI),
|
||||
mIsTopLevel(false),
|
||||
mLoader(aParent->mLoader),
|
||||
mVisitedSet(aParent->mVisitedSet) {
|
||||
MOZ_ASSERT(mVisitedSet->Contains(aURI));
|
||||
|
||||
mIsInline = false;
|
||||
mScriptMode = aParent->mScriptMode;
|
||||
}
|
||||
mVisitedSet(aVisitedSet) {}
|
||||
|
||||
void ModuleLoadRequest::Cancel() {
|
||||
ScriptLoadRequest::Cancel();
|
||||
|
@ -138,5 +198,11 @@ void ModuleLoadRequest::LoadFinished() {
|
|||
mLoader = nullptr;
|
||||
}
|
||||
|
||||
void ModuleLoadRequest::ClearDynamicImport() {
|
||||
mDynamicReferencingPrivate = JS::UndefinedValue();
|
||||
mDynamicSpecifier = nullptr;
|
||||
mDynamicPromise = nullptr;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -36,22 +36,40 @@ class ModuleLoadRequest final : public ScriptLoadRequest {
|
|||
ModuleLoadRequest(const ModuleLoadRequest& aOther) = delete;
|
||||
ModuleLoadRequest(ModuleLoadRequest&& aOther) = delete;
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ModuleLoadRequest, ScriptLoadRequest)
|
||||
|
||||
// Create a top-level module load request.
|
||||
ModuleLoadRequest(nsIURI* aURI, ScriptFetchOptions* aFetchOptions,
|
||||
const SRIMetadata& aIntegrity, nsIURI* aReferrer,
|
||||
ScriptLoader* aLoader);
|
||||
bool aIsTopLevel, bool aIsDynamicImport,
|
||||
ScriptLoader* aLoader, VisitedURLSet* aVisitedSet);
|
||||
|
||||
// Create a module load request for an imported module.
|
||||
ModuleLoadRequest(nsIURI* aURI, ModuleLoadRequest* aParent);
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ModuleLoadRequest,
|
||||
ScriptLoadRequest)
|
||||
|
||||
// Create a top-level module load request.
|
||||
static ModuleLoadRequest* CreateTopLevel(nsIURI* aURI,
|
||||
ScriptFetchOptions* aFetchOptions,
|
||||
const SRIMetadata& aIntegrity,
|
||||
nsIURI* aReferrer,
|
||||
ScriptLoader* aLoader);
|
||||
|
||||
// Create a module load request for a static module import.
|
||||
static ModuleLoadRequest* CreateStaticImport(nsIURI* aURI,
|
||||
ModuleLoadRequest* aParent);
|
||||
|
||||
// Create a module load request for dynamic module import.
|
||||
static ModuleLoadRequest* CreateDynamicImport(
|
||||
nsIURI* aURI, ModuleScript* aScript,
|
||||
JS::Handle<JS::Value> aReferencingPrivate,
|
||||
JS::Handle<JSString*> aSpecifier, JS::Handle<JSObject*> aPromise);
|
||||
|
||||
bool IsTopLevel() const override { return mIsTopLevel; }
|
||||
|
||||
bool IsDynamicImport() const { return mIsDynamicImport; }
|
||||
|
||||
void SetReady() override;
|
||||
void Cancel() override;
|
||||
void ClearDynamicImport();
|
||||
|
||||
void ModuleLoaded();
|
||||
void ModuleErrored();
|
||||
|
@ -66,6 +84,9 @@ class ModuleLoadRequest final : public ScriptLoadRequest {
|
|||
// Is this a request for a top level module script or an import?
|
||||
const bool mIsTopLevel;
|
||||
|
||||
// Is this the top level request for a dynamic module import?
|
||||
const bool mIsDynamicImport;
|
||||
|
||||
// The base URL used for resolving relative module imports.
|
||||
nsCOMPtr<nsIURI> mBaseURL;
|
||||
|
||||
|
@ -88,6 +109,11 @@ class ModuleLoadRequest final : public ScriptLoadRequest {
|
|||
// Set of module URLs visited while fetching the module graph this request is
|
||||
// part of.
|
||||
RefPtr<VisitedURLSet> mVisitedSet;
|
||||
|
||||
// For dynamic imports, the details to pass to FinishDynamicImport.
|
||||
JS::Heap<JS::Value> mDynamicReferencingPrivate;
|
||||
JS::Heap<JSString*> mDynamicSpecifier;
|
||||
JS::Heap<JSObject*> mDynamicPromise;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -5,7 +5,10 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ModuleScript.h"
|
||||
|
||||
#include "mozilla/HoldDropJSObjects.h"
|
||||
|
||||
#include "jsfriendapi.h"
|
||||
#include "ScriptLoader.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -20,6 +23,7 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(ModuleScript)
|
|||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ModuleScript)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoader)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFetchOptions)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBaseURL)
|
||||
tmp->UnlinkModuleRecord();
|
||||
tmp->mParseError.setUndefined();
|
||||
|
@ -28,6 +32,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ModuleScript)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoader)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFetchOptions)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ModuleScript)
|
||||
|
@ -39,9 +44,14 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
|||
NS_IMPL_CYCLE_COLLECTING_ADDREF(ModuleScript)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(ModuleScript)
|
||||
|
||||
ModuleScript::ModuleScript(ScriptLoader* aLoader, nsIURI* aBaseURL)
|
||||
: mLoader(aLoader), mBaseURL(aBaseURL), mSourceElementAssociated(false) {
|
||||
ModuleScript::ModuleScript(ScriptLoader* aLoader,
|
||||
ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL)
|
||||
: mLoader(aLoader),
|
||||
mFetchOptions(aFetchOptions),
|
||||
mBaseURL(aBaseURL),
|
||||
mSourceElementAssociated(false) {
|
||||
MOZ_ASSERT(mLoader);
|
||||
MOZ_ASSERT(mFetchOptions);
|
||||
MOZ_ASSERT(mBaseURL);
|
||||
MOZ_ASSERT(!mModuleRecord);
|
||||
MOZ_ASSERT(!HasParseError());
|
||||
|
@ -49,11 +59,14 @@ ModuleScript::ModuleScript(ScriptLoader* aLoader, nsIURI* aBaseURL)
|
|||
}
|
||||
|
||||
void ModuleScript::UnlinkModuleRecord() {
|
||||
// Remove module's back reference to this object request if present.
|
||||
// Remove the module record's pointer to this object if present and
|
||||
// decrement our reference count. The reference is added by
|
||||
// SetModuleRecord() below.
|
||||
if (mModuleRecord) {
|
||||
MOZ_ASSERT(JS::GetModulePrivate(mModuleRecord).toPrivate() == this);
|
||||
JS::SetModulePrivate(mModuleRecord, JS::UndefinedValue());
|
||||
mModuleRecord = nullptr;
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,10 +83,21 @@ void ModuleScript::SetModuleRecord(JS::Handle<JSObject*> aModuleRecord) {
|
|||
|
||||
mModuleRecord = aModuleRecord;
|
||||
|
||||
// Make module's host defined field point to this module script object.
|
||||
// This is cleared in the UnlinkModuleRecord().
|
||||
// Make module's host defined field point to this object and
|
||||
// increment our reference count. This is decremented by
|
||||
// UnlinkModuleRecord() above.
|
||||
JS::SetModulePrivate(mModuleRecord, JS::PrivateValue(this));
|
||||
HoldJSObjects(this);
|
||||
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 ModuleScript::SetParseError(const JS::Value& aError) {
|
||||
|
@ -88,7 +112,6 @@ void ModuleScript::SetParseError(const JS::Value& aError) {
|
|||
|
||||
void ModuleScript::SetErrorToRethrow(const JS::Value& aError) {
|
||||
MOZ_ASSERT(!aError.isUndefined());
|
||||
MOZ_ASSERT(!HasErrorToRethrow());
|
||||
|
||||
// This is only called after SetModuleRecord() or SetParseError() so we don't
|
||||
// need to call HoldJSObjects() here.
|
||||
|
|
|
@ -18,8 +18,11 @@ namespace dom {
|
|||
|
||||
class ScriptLoader;
|
||||
|
||||
void HostFinalizeTopLevelScript(JSFreeOp* aFop, const JS::Value& aPrivate);
|
||||
|
||||
class ModuleScript final : public nsISupports {
|
||||
RefPtr<ScriptLoader> mLoader;
|
||||
RefPtr<ScriptFetchOptions> mFetchOptions;
|
||||
nsCOMPtr<nsIURI> mBaseURL;
|
||||
JS::Heap<JSObject*> mModuleRecord;
|
||||
JS::Heap<JS::Value> mParseError;
|
||||
|
@ -32,7 +35,8 @@ class ModuleScript final : public nsISupports {
|
|||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ModuleScript)
|
||||
|
||||
ModuleScript(ScriptLoader* aLoader, nsIURI* aBaseURL);
|
||||
ModuleScript(ScriptLoader* aLoader, ScriptFetchOptions* aFetchOptions,
|
||||
nsIURI* aBaseURL);
|
||||
|
||||
void SetModuleRecord(JS::Handle<JSObject*> aModuleRecord);
|
||||
void SetParseError(const JS::Value& aError);
|
||||
|
@ -40,6 +44,7 @@ class ModuleScript final : public nsISupports {
|
|||
void SetSourceElementAssociated();
|
||||
|
||||
ScriptLoader* Loader() const { return mLoader; }
|
||||
ScriptFetchOptions* FetchOptions() const { return mFetchOptions; }
|
||||
JSObject* ModuleRecord() const { return mModuleRecord; }
|
||||
nsIURI* BaseURL() const { return mBaseURL; }
|
||||
JS::Value ParseError() const { return mParseError; }
|
||||
|
@ -49,6 +54,8 @@ class ModuleScript final : public nsISupports {
|
|||
bool SourceElementAssociated() const { return mSourceElementAssociated; }
|
||||
|
||||
void UnlinkModuleRecord();
|
||||
|
||||
friend void HostFinalizeTopLevelScript(JSFreeOp*, const JS::Value&);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ModuleLoadRequest.h"
|
||||
#include "ScriptLoadRequest.h"
|
||||
|
||||
#include "mozilla/HoldDropJSObjects.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
@ -52,6 +52,7 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(ScriptLoadRequest)
|
|||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ScriptLoadRequest)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFetchOptions)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheInfo)
|
||||
tmp->mScript = nullptr;
|
||||
tmp->DropBytecodeCacheReferences();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
|
@ -105,6 +106,8 @@ ScriptLoadRequest::~ScriptLoadRequest() {
|
|||
if (mScript) {
|
||||
DropBytecodeCacheReferences();
|
||||
}
|
||||
|
||||
DropJSObjects(this);
|
||||
}
|
||||
|
||||
void ScriptLoadRequest::SetReady() {
|
||||
|
@ -207,6 +210,12 @@ void ScriptLoadRequest::ClearScriptSource() {
|
|||
}
|
||||
}
|
||||
|
||||
void ScriptLoadRequest::SetScript(JSScript* aScript) {
|
||||
MOZ_ASSERT(!mScript);
|
||||
mScript = aScript;
|
||||
HoldJSObjects(this);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// ScriptLoadRequestList
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -210,6 +210,8 @@ class ScriptLoadRequest
|
|||
|
||||
void ClearScriptSource();
|
||||
|
||||
void SetScript(JSScript* aScript);
|
||||
|
||||
void MaybeCancelOffThreadScript();
|
||||
void DropBytecodeCacheReferences();
|
||||
|
||||
|
|
|
@ -113,9 +113,9 @@ NS_INTERFACE_MAP_END
|
|||
|
||||
NS_IMPL_CYCLE_COLLECTION(ScriptLoader, mNonAsyncExternalScriptInsertedRequests,
|
||||
mLoadingAsyncRequests, mLoadedAsyncRequests,
|
||||
mDeferRequests, mXSLTRequests, mParserBlockingRequest,
|
||||
mBytecodeEncodingQueue, mPreloads,
|
||||
mPendingChildLoaders, mFetchedModules)
|
||||
mDeferRequests, mXSLTRequests, mDynamicImportRequests,
|
||||
mParserBlockingRequest, mBytecodeEncodingQueue,
|
||||
mPreloads, mPendingChildLoaders, mFetchedModules)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(ScriptLoader)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(ScriptLoader)
|
||||
|
@ -133,6 +133,7 @@ ScriptLoader::ScriptLoader(nsIDocument* aDocument)
|
|||
mGiveUpEncoding(false),
|
||||
mReporter(new ConsoleReportCollector()) {
|
||||
LOG(("ScriptLoader::ScriptLoader %p", this));
|
||||
EnsureModuleHooksInitialized();
|
||||
}
|
||||
|
||||
ScriptLoader::~ScriptLoader() {
|
||||
|
@ -164,6 +165,11 @@ ScriptLoader::~ScriptLoader() {
|
|||
req->FireScriptAvailable(NS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
for (ScriptLoadRequest* req = mDynamicImportRequests.getFirst(); req;
|
||||
req = req->getNext()) {
|
||||
FinishDynamicImport(req->AsModuleRequest(), NS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
for (ScriptLoadRequest* req =
|
||||
mNonAsyncExternalScriptInsertedRequests.getFirst();
|
||||
req; req = req->getNext()) {
|
||||
|
@ -471,7 +477,7 @@ nsresult ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest) {
|
|||
MOZ_ASSERT(NS_SUCCEEDED(rv) == (module != nullptr));
|
||||
|
||||
RefPtr<ModuleScript> moduleScript =
|
||||
new ModuleScript(this, aRequest->mBaseURL);
|
||||
new ModuleScript(this, aRequest->mFetchOptions, aRequest->mBaseURL);
|
||||
aRequest->mModuleScript = moduleScript;
|
||||
|
||||
if (!module) {
|
||||
|
@ -689,7 +695,8 @@ RefPtr<GenericPromise> ScriptLoader::StartFetchingModuleAndDependencies(
|
|||
ModuleLoadRequest* aParent, nsIURI* aURI) {
|
||||
MOZ_ASSERT(aURI);
|
||||
|
||||
RefPtr<ModuleLoadRequest> childRequest = new ModuleLoadRequest(aURI, aParent);
|
||||
RefPtr<ModuleLoadRequest> childRequest =
|
||||
ModuleLoadRequest::CreateStaticImport(aURI, aParent);
|
||||
|
||||
aParent->mImports.AppendElement(childRequest);
|
||||
|
||||
|
@ -725,6 +732,12 @@ JSObject* HostResolveImportedModule(JSContext* aCx,
|
|||
JS::Handle<JS::Value> aReferencingPrivate,
|
||||
JS::Handle<JSString*> aSpecifier) {
|
||||
// Let referencing module script be referencingModule.[[HostDefined]].
|
||||
if (aReferencingPrivate.isUndefined()) {
|
||||
JS_ReportErrorNumberUC(aCx, js::GetErrorMessage, nullptr,
|
||||
JSMSG_IMPORT_SCRIPT_NOT_FOUND);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto script = static_cast<ModuleScript*>(aReferencingPrivate.toPrivate());
|
||||
MOZ_ASSERT(JS::GetModulePrivate(script->ModuleRecord()) ==
|
||||
aReferencingPrivate);
|
||||
|
@ -774,14 +787,114 @@ bool HostPopulateImportMeta(JSContext* aCx,
|
|||
JSPROP_ENUMERATE);
|
||||
}
|
||||
|
||||
static void EnsureModuleResolveHook(JSContext* aCx) {
|
||||
JSRuntime* rt = JS_GetRuntime(aCx);
|
||||
bool HostImportModuleDynamically(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aReferencingPrivate,
|
||||
JS::Handle<JSString*> aSpecifier,
|
||||
JS::Handle<JSObject*> aPromise) {
|
||||
if (aReferencingPrivate.isUndefined()) {
|
||||
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.
|
||||
nsAutoJSString string;
|
||||
if (!string.init(aCx, aSpecifier)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri = ResolveModuleSpecifier(script, string);
|
||||
if (!uri) {
|
||||
JS_ReportErrorNumberUC(aCx, js::GetErrorMessage, nullptr,
|
||||
JSMSG_BAD_MODULE_SPECIFIER, string.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a new top-level load request.
|
||||
RefPtr<ModuleLoadRequest> request = ModuleLoadRequest::CreateDynamicImport(
|
||||
uri, script, aReferencingPrivate, aSpecifier, aPromise);
|
||||
|
||||
script->Loader()->StartDynamicImport(request);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptLoader::StartDynamicImport(ModuleLoadRequest* aRequest) {
|
||||
LOG(("ScriptLoadRequest (%p): Start dynamic import", aRequest));
|
||||
|
||||
mDynamicImportRequests.AppendElement(aRequest);
|
||||
|
||||
nsresult rv = StartLoad(aRequest);
|
||||
if (NS_FAILED(rv)) {
|
||||
FinishDynamicImport(aRequest, rv);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptLoader::FinishDynamicImport(ModuleLoadRequest* aRequest,
|
||||
nsresult aResult) {
|
||||
AutoJSAPI jsapi;
|
||||
MOZ_ALWAYS_TRUE(jsapi.Init(aRequest->mDynamicPromise));
|
||||
FinishDynamicImport(jsapi.cx(), aRequest, aResult);
|
||||
}
|
||||
|
||||
void ScriptLoader::FinishDynamicImport(JSContext* aCx,
|
||||
ModuleLoadRequest* aRequest,
|
||||
nsresult aResult) {
|
||||
LOG(("ScriptLoadRequest (%p): Finish dynamic import %d %d", aRequest,
|
||||
unsigned(aResult), JS_IsExceptionPending(aCx)));
|
||||
|
||||
// Complete the dynamic import, report failures indicated by aResult or as a
|
||||
// pending exception on the context.
|
||||
|
||||
if (NS_FAILED(aResult)) {
|
||||
MOZ_ASSERT(!JS_IsExceptionPending(aCx));
|
||||
JS_ReportErrorNumberUC(aCx, js::GetErrorMessage, nullptr,
|
||||
JSMSG_IMPORT_SCRIPT_NOT_FOUND);
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> referencingScript(aCx,
|
||||
aRequest->mDynamicReferencingPrivate);
|
||||
JS::Rooted<JSString*> specifier(aCx, aRequest->mDynamicSpecifier);
|
||||
JS::Rooted<JSObject*> promise(aCx, aRequest->mDynamicPromise);
|
||||
|
||||
JS::FinishDynamicModuleImport(aCx, referencingScript, specifier, promise);
|
||||
|
||||
// FinishDynamicModuleImport clears any pending exception.
|
||||
MOZ_ASSERT(!JS_IsExceptionPending(aCx));
|
||||
|
||||
aRequest->ClearDynamicImport();
|
||||
}
|
||||
|
||||
static void DynamicImportPrefChangedCallback(const char* aPrefName,
|
||||
void* aClosure) {
|
||||
bool enabled = Preferences::GetBool(aPrefName);
|
||||
JS::ModuleDynamicImportHook hook =
|
||||
enabled ? HostImportModuleDynamically : nullptr;
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
JSRuntime* rt = JS_GetRuntime(jsapi.cx());
|
||||
JS::SetModuleDynamicImportHook(rt, hook);
|
||||
}
|
||||
|
||||
void ScriptLoader::EnsureModuleHooksInitialized() {
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
JSRuntime* rt = JS_GetRuntime(jsapi.cx());
|
||||
if (JS::GetModuleResolveHook(rt)) {
|
||||
return;
|
||||
}
|
||||
|
||||
JS::SetModuleResolveHook(rt, HostResolveImportedModule);
|
||||
JS::SetModuleMetadataHook(rt, HostPopulateImportMeta);
|
||||
JS::SetScriptPrivateFinalizeHook(rt, HostFinalizeTopLevelScript);
|
||||
|
||||
Preferences::RegisterCallbackAndCall(DynamicImportPrefChangedCallback,
|
||||
"javascript.options.dynamicImport",
|
||||
(void*)nullptr);
|
||||
}
|
||||
|
||||
void ScriptLoader::CheckModuleDependenciesLoaded(ModuleLoadRequest* aRequest) {
|
||||
|
@ -815,18 +928,34 @@ class ScriptRequestProcessor : public Runnable {
|
|||
: Runnable("dom::ScriptRequestProcessor"),
|
||||
mLoader(aLoader),
|
||||
mRequest(aRequest) {}
|
||||
NS_IMETHOD Run() override { return mLoader->ProcessRequest(mRequest); }
|
||||
NS_IMETHOD Run() override {
|
||||
if (mRequest->IsModuleRequest() &&
|
||||
mRequest->AsModuleRequest()->IsDynamicImport()) {
|
||||
mLoader->ProcessDynamicImport(mRequest->AsModuleRequest());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return mLoader->ProcessRequest(mRequest);
|
||||
}
|
||||
};
|
||||
|
||||
void ScriptLoader::RunScriptWhenSafe(ScriptLoadRequest* aRequest) {
|
||||
auto runnable = new ScriptRequestProcessor(this, aRequest);
|
||||
nsContentUtils::AddScriptRunner(runnable);
|
||||
}
|
||||
|
||||
void ScriptLoader::ProcessLoadedModuleTree(ModuleLoadRequest* aRequest) {
|
||||
MOZ_ASSERT(aRequest->IsReadyToRun());
|
||||
|
||||
if (aRequest->IsTopLevel()) {
|
||||
if (aRequest->mIsInline &&
|
||||
aRequest->Element()->GetParserCreated() == NOT_FROM_PARSER) {
|
||||
if (aRequest->IsDynamicImport()) {
|
||||
MOZ_ASSERT(aRequest->isInList());
|
||||
RefPtr<ScriptLoadRequest> req = mDynamicImportRequests.Steal(aRequest);
|
||||
RunScriptWhenSafe(req);
|
||||
} else if (aRequest->mIsInline &&
|
||||
aRequest->Element()->GetParserCreated() == NOT_FROM_PARSER) {
|
||||
MOZ_ASSERT(!aRequest->isInList());
|
||||
nsContentUtils::AddScriptRunner(
|
||||
new ScriptRequestProcessor(this, aRequest));
|
||||
RunScriptWhenSafe(aRequest);
|
||||
} else {
|
||||
MaybeMoveToLoadedList(aRequest);
|
||||
ProcessPendingRequests();
|
||||
|
@ -884,8 +1013,6 @@ bool ScriptLoader::InstantiateModuleTree(ModuleLoadRequest* aRequest) {
|
|||
return false;
|
||||
}
|
||||
|
||||
EnsureModuleResolveHook(jsapi.cx());
|
||||
|
||||
JS::Rooted<JSObject*> module(jsapi.cx(), moduleScript->ModuleRecord());
|
||||
bool ok = NS_SUCCEEDED(nsJSUtils::ModuleInstantiate(jsapi.cx(), module));
|
||||
|
||||
|
@ -1210,7 +1337,8 @@ ScriptLoadRequest* ScriptLoader::CreateLoadRequest(
|
|||
}
|
||||
|
||||
MOZ_ASSERT(aKind == ScriptKind::eModule);
|
||||
return new ModuleLoadRequest(aURI, fetchOptions, aIntegrity, referrer, this);
|
||||
return ModuleLoadRequest::CreateTopLevel(aURI, fetchOptions, aIntegrity,
|
||||
referrer, this);
|
||||
}
|
||||
|
||||
bool ScriptLoader::ProcessScriptElement(nsIScriptElement* aElement) {
|
||||
|
@ -1538,7 +1666,7 @@ bool ScriptLoader::ProcessInlineScript(nsIScriptElement* aElement,
|
|||
NS_ASSERTION(
|
||||
!nsContentUtils::IsSafeToRunScript(),
|
||||
"A script-inserted script is inserted without an update batch?");
|
||||
nsContentUtils::AddScriptRunner(new ScriptRequestProcessor(this, request));
|
||||
RunScriptWhenSafe(request);
|
||||
return false;
|
||||
}
|
||||
if (aElement->GetParserCreated() == FROM_PARSER_NETWORK &&
|
||||
|
@ -1915,8 +2043,7 @@ nsresult ScriptLoader::ProcessRequest(ScriptLoadRequest* aRequest) {
|
|||
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
ModuleLoadRequest* request = aRequest->AsModuleRequest();
|
||||
if (request->mModuleScript &&
|
||||
!request->mModuleScript->HasErrorToRethrow()) {
|
||||
if (request->mModuleScript) {
|
||||
if (!InstantiateModuleTree(request)) {
|
||||
request->mModuleScript = nullptr;
|
||||
}
|
||||
|
@ -2018,6 +2145,25 @@ nsresult ScriptLoader::ProcessRequest(ScriptLoadRequest* aRequest) {
|
|||
return rv;
|
||||
}
|
||||
|
||||
void ScriptLoader::ProcessDynamicImport(ModuleLoadRequest* aRequest) {
|
||||
if (aRequest->mModuleScript) {
|
||||
if (!InstantiateModuleTree(aRequest)) {
|
||||
aRequest->mModuleScript = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
if (aRequest->mModuleScript) {
|
||||
rv = EvaluateScript(aRequest);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
FinishDynamicImport(aRequest, rv);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ScriptLoader::FireScriptAvailable(nsresult aResult,
|
||||
ScriptLoadRequest* aRequest) {
|
||||
for (int32_t i = 0; i < mObservers.Count(); i++) {
|
||||
|
@ -2062,7 +2208,7 @@ already_AddRefed<nsIScriptGlobalObject> ScriptLoader::GetScriptGlobalObject() {
|
|||
}
|
||||
|
||||
nsresult ScriptLoader::FillCompileOptionsForRequest(
|
||||
const AutoJSAPI& jsapi, ScriptLoadRequest* aRequest,
|
||||
const mozilla::dom::AutoJSAPI& jsapi, ScriptLoadRequest* aRequest,
|
||||
JS::Handle<JSObject*> aScopeChain, JS::CompileOptions* aOptions) {
|
||||
// It's very important to use aRequest->mURI, not the final URI of the channel
|
||||
// aRequest ended up getting script data from, as the script filename.
|
||||
|
@ -2203,6 +2349,19 @@ nsresult ScriptLoader::FillCompileOptionsForRequest(
|
|||
return true;
|
||||
}
|
||||
|
||||
class MOZ_RAII AutoSetProcessingScriptTag {
|
||||
nsCOMPtr<nsIScriptContext> mContext;
|
||||
bool mOldTag;
|
||||
|
||||
public:
|
||||
explicit AutoSetProcessingScriptTag(nsIScriptContext* aContext)
|
||||
: mContext(aContext), mOldTag(mContext->GetProcessingScriptTag()) {
|
||||
mContext->SetProcessingScriptTag(true);
|
||||
}
|
||||
|
||||
~AutoSetProcessingScriptTag() { mContext->SetProcessingScriptTag(mOldTag); }
|
||||
};
|
||||
|
||||
nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
|
||||
using namespace mozilla::Telemetry;
|
||||
MOZ_ASSERT(aRequest->IsReadyToRun());
|
||||
|
@ -2242,8 +2401,8 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
|
|||
JSContext* cx = aes.cx();
|
||||
JS::Rooted<JSObject*> global(cx, globalObject->GetGlobalJSObject());
|
||||
|
||||
bool oldProcessingScriptTag = context->GetProcessingScriptTag();
|
||||
context->SetProcessingScriptTag(true);
|
||||
AutoSetProcessingScriptTag setProcessingScriptTag(context);
|
||||
|
||||
nsresult rv;
|
||||
{
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
|
@ -2255,8 +2414,6 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
|
|||
// currentScript is set to null for modules.
|
||||
AutoCurrentScriptUpdater scriptUpdater(this, nullptr);
|
||||
|
||||
EnsureModuleResolveHook(cx);
|
||||
|
||||
ModuleLoadRequest* request = aRequest->AsModuleRequest();
|
||||
MOZ_ASSERT(request->mModuleScript);
|
||||
MOZ_ASSERT(!request->mOffThreadToken);
|
||||
|
@ -2267,7 +2424,13 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
|
|||
aRequest));
|
||||
JS::Rooted<JS::Value> error(cx, moduleScript->ErrorToRethrow());
|
||||
JS_SetPendingException(cx, error);
|
||||
return NS_OK; // An error is reported by AutoEntryScript.
|
||||
|
||||
// For a dynamic import, the promise is rejected. Otherwise an error is
|
||||
// either reported by AutoEntryScript.
|
||||
if (request->IsDynamicImport()) {
|
||||
FinishDynamicImport(cx, request, NS_OK);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> module(cx, moduleScript->ModuleRecord());
|
||||
|
@ -2280,9 +2443,16 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
|
|||
|
||||
rv = nsJSUtils::ModuleEvaluate(cx, module);
|
||||
MOZ_ASSERT(NS_FAILED(rv) == aes.HasException());
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("ScriptLoadRequest (%p): evaluation failed", aRequest));
|
||||
rv = NS_OK; // An error is reported by AutoEntryScript.
|
||||
// For a dynamic import, the promise is rejected. Otherwise an error is
|
||||
// either reported by AutoEntryScript.
|
||||
rv = NS_OK;
|
||||
}
|
||||
|
||||
if (request->IsDynamicImport()) {
|
||||
FinishDynamicImport(cx, request, rv);
|
||||
}
|
||||
|
||||
aRequest->mCacheInfo = nullptr;
|
||||
|
@ -2354,8 +2524,7 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
|
|||
|
||||
// Queue the current script load request to later save the bytecode.
|
||||
if (script && encodeBytecode) {
|
||||
aRequest->mScript = script;
|
||||
HoldJSObjects(aRequest);
|
||||
aRequest->SetScript(script);
|
||||
TRACE_FOR_TEST(aRequest->Element(), "scriptloader_encode");
|
||||
MOZ_ASSERT(aRequest->mBytecodeOffset ==
|
||||
aRequest->mScriptBytecode.length());
|
||||
|
@ -2379,7 +2548,6 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
|
|||
MaybeTriggerBytecodeEncoding();
|
||||
}
|
||||
|
||||
context->SetProcessingScriptTag(oldProcessingScriptTag);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -2567,7 +2735,8 @@ bool ScriptLoader::HasPendingRequests() {
|
|||
return mParserBlockingRequest || !mXSLTRequests.isEmpty() ||
|
||||
!mLoadedAsyncRequests.isEmpty() ||
|
||||
!mNonAsyncExternalScriptInsertedRequests.isEmpty() ||
|
||||
!mDeferRequests.isEmpty() || !mPendingChildLoaders.IsEmpty();
|
||||
!mDeferRequests.isEmpty() || !mDynamicImportRequests.isEmpty() ||
|
||||
!mPendingChildLoaders.IsEmpty();
|
||||
}
|
||||
|
||||
void ScriptLoader::ProcessPendingRequestsAsync() {
|
||||
|
@ -2980,12 +3149,31 @@ void ScriptLoader::HandleLoadError(ScriptLoadRequest* aRequest,
|
|||
RefPtr<ScriptLoadRequest> req = mXSLTRequests.Steal(aRequest);
|
||||
FireScriptAvailable(aResult, req);
|
||||
}
|
||||
} else if (aRequest->IsModuleRequest() && !aRequest->IsPreload()) {
|
||||
} else if (aRequest->IsPreload()) {
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
aRequest->Cancel();
|
||||
}
|
||||
if (aRequest->IsTopLevel()) {
|
||||
MOZ_ALWAYS_TRUE(
|
||||
mPreloads.RemoveElement(aRequest, PreloadRequestComparator()));
|
||||
}
|
||||
MOZ_ASSERT(!aRequest->isInList());
|
||||
AccumulateCategorical(LABELS_DOM_SCRIPT_PRELOAD_RESULT::LoadError);
|
||||
} else if (aRequest->IsModuleRequest()) {
|
||||
ModuleLoadRequest* modReq = aRequest->AsModuleRequest();
|
||||
MOZ_ASSERT(!modReq->IsTopLevel());
|
||||
MOZ_ASSERT(!modReq->isInList());
|
||||
modReq->Cancel();
|
||||
// A single error is fired for the top level module.
|
||||
if (modReq->IsDynamicImport()) {
|
||||
MOZ_ASSERT(modReq->IsTopLevel());
|
||||
if (aRequest->isInList()) {
|
||||
RefPtr<ScriptLoadRequest> req = mDynamicImportRequests.Steal(aRequest);
|
||||
modReq->Cancel();
|
||||
FinishDynamicImport(modReq, aResult);
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(!modReq->IsTopLevel());
|
||||
MOZ_ASSERT(!modReq->isInList());
|
||||
modReq->Cancel();
|
||||
// The error is handled for the top level module.
|
||||
}
|
||||
} else if (mParserBlockingRequest == aRequest) {
|
||||
MOZ_ASSERT(!aRequest->isInList());
|
||||
mParserBlockingRequest = nullptr;
|
||||
|
@ -3000,16 +3188,6 @@ void ScriptLoader::HandleLoadError(ScriptLoadRequest* aRequest,
|
|||
FireScriptAvailable(aResult, aRequest);
|
||||
ContinueParserAsync(aRequest);
|
||||
mCurrentParserInsertedScript = oldParserInsertedScript;
|
||||
} else if (aRequest->IsPreload()) {
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
aRequest->Cancel();
|
||||
}
|
||||
if (aRequest->IsTopLevel()) {
|
||||
MOZ_ALWAYS_TRUE(
|
||||
mPreloads.RemoveElement(aRequest, PreloadRequestComparator()));
|
||||
}
|
||||
MOZ_ASSERT(!aRequest->isInList());
|
||||
AccumulateCategorical(LABELS_DOM_SCRIPT_PRELOAD_RESULT::LoadError);
|
||||
} else {
|
||||
// This happens for blocking requests cancelled by ParsingComplete().
|
||||
MOZ_ASSERT(aRequest->IsCanceled());
|
||||
|
@ -3110,11 +3288,12 @@ nsresult ScriptLoader::PrepareLoadedRequest(ScriptLoadRequest* aRequest,
|
|||
mLoadingAsyncRequests.Contains(aRequest) ||
|
||||
mNonAsyncExternalScriptInsertedRequests.Contains(aRequest) ||
|
||||
mXSLTRequests.Contains(aRequest) ||
|
||||
mDynamicImportRequests.Contains(aRequest) ||
|
||||
(aRequest->IsModuleRequest() &&
|
||||
!aRequest->AsModuleRequest()->IsTopLevel() &&
|
||||
!aRequest->isInList()) ||
|
||||
mPreloads.Contains(aRequest, PreloadRequestComparator()) ||
|
||||
mParserBlockingRequest,
|
||||
mParserBlockingRequest == aRequest,
|
||||
"aRequest should be pending!");
|
||||
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
|
@ -3191,6 +3370,13 @@ void ScriptLoader::ParsingComplete(bool aTerminated) {
|
|||
mLoadedAsyncRequests.Clear();
|
||||
mNonAsyncExternalScriptInsertedRequests.Clear();
|
||||
mXSLTRequests.Clear();
|
||||
|
||||
for (ScriptLoadRequest* req = mDynamicImportRequests.getFirst(); req;
|
||||
req = req->getNext()) {
|
||||
req->Cancel();
|
||||
FinishDynamicImport(req->AsModuleRequest(), NS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
if (mParserBlockingRequest) {
|
||||
mParserBlockingRequest->Cancel();
|
||||
mParserBlockingRequest = nullptr;
|
||||
|
|
|
@ -310,9 +310,16 @@ class ScriptLoader final : public nsISupports {
|
|||
*/
|
||||
void Destroy() { GiveUpBytecodeEncoding(); }
|
||||
|
||||
void StartDynamicImport(ModuleLoadRequest* aRequest);
|
||||
void FinishDynamicImport(ModuleLoadRequest* aRequest, nsresult aResult);
|
||||
void FinishDynamicImport(JSContext* aCx, ModuleLoadRequest* aRequest,
|
||||
nsresult aResult);
|
||||
|
||||
private:
|
||||
virtual ~ScriptLoader();
|
||||
|
||||
void EnsureModuleHooksInitialized();
|
||||
|
||||
ScriptLoadRequest* CreateLoadRequest(
|
||||
ScriptKind aKind, nsIURI* aURI, nsIScriptElement* aElement,
|
||||
nsIPrincipal* aTriggeringPrincipal, mozilla::CORSMode aCORSMode,
|
||||
|
@ -419,6 +426,7 @@ class ScriptLoader final : public nsISupports {
|
|||
nsresult AttemptAsyncScriptCompile(ScriptLoadRequest* aRequest,
|
||||
bool* aCouldCompileOut);
|
||||
nsresult ProcessRequest(ScriptLoadRequest* aRequest);
|
||||
void ProcessDynamicImport(ModuleLoadRequest* aRequest);
|
||||
nsresult CompileOffThreadOrProcessRequest(ScriptLoadRequest* aRequest);
|
||||
void FireScriptAvailable(nsresult aResult, ScriptLoadRequest* aRequest);
|
||||
void FireScriptEvaluated(nsresult aResult, ScriptLoadRequest* aRequest);
|
||||
|
@ -500,6 +508,8 @@ class ScriptLoader final : public nsISupports {
|
|||
nsresult AssociateSourceElementsForModuleTree(JSContext* aCx,
|
||||
ModuleLoadRequest* aRequest);
|
||||
|
||||
void RunScriptWhenSafe(ScriptLoadRequest* aRequest);
|
||||
|
||||
nsIDocument* mDocument; // [WEAK]
|
||||
nsCOMArray<nsIScriptLoaderObserver> mObservers;
|
||||
ScriptLoadRequestList mNonAsyncExternalScriptInsertedRequests;
|
||||
|
@ -509,6 +519,7 @@ class ScriptLoader final : public nsISupports {
|
|||
ScriptLoadRequestList mLoadedAsyncRequests;
|
||||
ScriptLoadRequestList mDeferRequests;
|
||||
ScriptLoadRequestList mXSLTRequests;
|
||||
ScriptLoadRequestList mDynamicImportRequests;
|
||||
RefPtr<ScriptLoadRequest> mParserBlockingRequest;
|
||||
|
||||
// List of script load request that are holding a buffer which has to be saved
|
||||
|
|
|
@ -1584,6 +1584,9 @@ pref("javascript.options.streams", true);
|
|||
// BigInt API
|
||||
pref("javascript.options.bigint", false);
|
||||
|
||||
// Dynamic module import.
|
||||
pref("javascript.options.dynamicImport", false);
|
||||
|
||||
// advanced prefs
|
||||
pref("advanced.mailftp", false);
|
||||
pref("image.animation_mode", "normal");
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
lsan-allowed: [Init, nsHostResolver::ResolveHost]
|
||||
prefs: [javascript.options.dynamicImport:true, security.csp.experimentalEnabled:true]
|
||||
|
|
|
@ -2,6 +2,3 @@
|
|||
[Basic dynamic imports]
|
||||
expected: FAIL
|
||||
|
||||
[Dynamic imports should resolve module.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[inline-event-handler.html]
|
||||
expected: ERROR
|
||||
expected: TIMEOUT
|
||||
[dynamic import should work when triggered from inline event handlers]
|
||||
expected: TIMEOUT
|
||||
|
||||
|
|
|
@ -5,6 +5,3 @@
|
|||
[propagate-nonce-external-module]
|
||||
expected: FAIL
|
||||
|
||||
[Dynamically imported module should eval when imported from script w/ a valid nonce.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -5,6 +5,3 @@
|
|||
[propagate-nonce-inline-module]
|
||||
expected: FAIL
|
||||
|
||||
[Dynamically imported module should eval when imported from script w/ a valid nonce.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
[string-compilation-base-url-external-classic.html]
|
||||
expected: ERROR
|
||||
[setTimeout should successfully import]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[eval should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[Function should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[reflected-inline-event-handlers should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[inline-event-handlers-UA-code should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,17 +1,10 @@
|
|||
[string-compilation-base-url-external-module.html]
|
||||
expected: ERROR
|
||||
[setTimeout should successfully import]
|
||||
expected: TIMEOUT
|
||||
|
||||
[eval should successfully import]
|
||||
expected: NOTRUN
|
||||
|
||||
[Function should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[reflected-inline-event-handlers should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[inline-event-handlers-UA-code should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
[string-compilation-base-url-inline-classic.html]
|
||||
expected: ERROR
|
||||
[setTimeout should successfully import]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[eval should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[the Function constructor should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[reflected inline event handlers should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[inline event handlers triggered via UA code should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,17 +1,10 @@
|
|||
[string-compilation-base-url-inline-module.html]
|
||||
expected: ERROR
|
||||
[setTimeout should successfully import]
|
||||
expected: TIMEOUT
|
||||
|
||||
[eval should successfully import]
|
||||
expected: NOTRUN
|
||||
|
||||
[the Function constructor should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[reflected inline event handlers should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[inline event handlers triggered via UA code should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
[string-compilation-classic.html]
|
||||
expected: ERROR
|
||||
[eval should successfully import]
|
||||
expected: FAIL
|
||||
|
||||
[setTimeout should successfully import]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[the Function constructor should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[reflected inline event handlers should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[inline event handlers triggered via UA code should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,17 +1,10 @@
|
|||
[string-compilation-module.html]
|
||||
expected: ERROR
|
||||
[eval should successfully import]
|
||||
[setTimeout should successfully import]
|
||||
expected: FAIL
|
||||
|
||||
[setTimeout should successfully import]
|
||||
expected: TIMEOUT
|
||||
|
||||
[the Function constructor should successfully import]
|
||||
expected: NOTRUN
|
||||
|
||||
[reflected inline event handlers should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[inline event handlers triggered via UA code should successfully import]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
[string-compilation-nonce-classic.html]
|
||||
expected: ERROR
|
||||
[setTimeout must inherit the nonce from the triggering script, thus execute]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[direct eval must inherit the nonce from the triggering script, thus execute]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[indirect eval must inherit the nonce from the triggering script, thus execute]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[the Function constructor must inherit the nonce from the triggering script, thus execute]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[reflected inline event handlers must inherit the nonce from the triggering script, thus execute]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[inline event handlers triggered via UA code must inherit the nonce from the triggering script, thus execute]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,20 +1,10 @@
|
|||
[string-compilation-nonce-module.html]
|
||||
expected: ERROR
|
||||
[setTimeout must inherit the nonce from the triggering script, thus execute]
|
||||
expected: TIMEOUT
|
||||
|
||||
[direct eval must inherit the nonce from the triggering script, thus execute]
|
||||
expected: NOTRUN
|
||||
|
||||
[indirect eval must inherit the nonce from the triggering script, thus execute]
|
||||
expected: NOTRUN
|
||||
|
||||
[the Function constructor must inherit the nonce from the triggering script, thus execute]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[reflected inline event handlers must inherit the nonce from the triggering script, thus execute]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[inline event handlers triggered via UA code must inherit the nonce from the triggering script, thus execute]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -2,12 +2,6 @@
|
|||
[Evaled the script via eval, successful import]
|
||||
expected: FAIL
|
||||
|
||||
[Evaled the script via eval, failed import]
|
||||
expected: FAIL
|
||||
|
||||
[Evaled the script via Function, successful import]
|
||||
expected: FAIL
|
||||
|
||||
[Evaled the script via Function, failed import]
|
||||
expected: FAIL
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче