Backed out changeset 046f0f522ce7 (bug 1896709) Backed out changeset 0271e50308e6 (bug 1896709) Backed out changeset 26fac760de19 (bug 1896709) Backed out changeset 6fa3424dfc40 (bug 1896709) Backed out changeset b7bcb9904435 (bug 1896709) Backed out changeset c6878c5fdde4 (bug 1896709) Backed out changeset 8ca8a4082e44 (bug 1896709) Backed out changeset 20ff83806cc6 (bug 1896709) Backed out changeset 6c9338852a19 (bug 1896709) Backed out changeset e8615b5d82ab (bug 1896709) Backed out changeset 842f2047a4bd (bug 1896709) Backed out changeset 54eea04a7342 (bug 1896709) Backed out changeset 220b544127cb (bug 1896709) Backed out changeset 52ce0ebfb29a (bug 1896709) Backed out changeset 34fc79dc1ad7 (bug 1896709) Backed out changeset 50b0f6a23e3c (bug 1896709) Backed out changeset 89c4c6bb465a (bug 1896709)
233 lines
7.2 KiB
C++
233 lines
7.2 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* 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 "ScriptLoadRequest.h"
|
|
#include "GeckoProfiler.h"
|
|
|
|
#include "mozilla/dom/Document.h"
|
|
#include "mozilla/dom/ScriptLoadContext.h"
|
|
#include "mozilla/dom/WorkerLoadContext.h"
|
|
#include "mozilla/dom/ScriptSettings.h"
|
|
#include "mozilla/HoldDropJSObjects.h"
|
|
#include "mozilla/StaticPrefs_dom.h"
|
|
#include "mozilla/Unused.h"
|
|
#include "mozilla/Utf8.h" // mozilla::Utf8Unit
|
|
|
|
#include "js/SourceText.h"
|
|
|
|
#include "ModuleLoadRequest.h"
|
|
#include "nsContentUtils.h"
|
|
#include "nsICacheInfoChannel.h"
|
|
#include "nsIClassOfService.h"
|
|
#include "nsISupportsPriority.h"
|
|
|
|
using JS::SourceText;
|
|
|
|
namespace JS::loader {
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
// ScriptFetchOptions
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
NS_IMPL_CYCLE_COLLECTION(ScriptFetchOptions, mTriggeringPrincipal)
|
|
|
|
ScriptFetchOptions::ScriptFetchOptions(
|
|
mozilla::CORSMode aCORSMode, const nsAString& aNonce,
|
|
mozilla::dom::RequestPriority aFetchPriority,
|
|
const ParserMetadata aParserMetadata, nsIPrincipal* aTriggeringPrincipal)
|
|
: mCORSMode(aCORSMode),
|
|
mNonce(aNonce),
|
|
mFetchPriority(aFetchPriority),
|
|
mParserMetadata(aParserMetadata),
|
|
mTriggeringPrincipal(aTriggeringPrincipal) {}
|
|
|
|
ScriptFetchOptions::~ScriptFetchOptions() = default;
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
// ScriptLoadRequest
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ScriptLoadRequest)
|
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
|
NS_INTERFACE_MAP_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(ScriptLoadRequest)
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(ScriptLoadRequest)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(ScriptLoadRequest)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ScriptLoadRequest)
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFetchOptions, mCacheInfo, mLoadContext,
|
|
mLoadedScript)
|
|
tmp->mScriptForBytecodeEncoding = nullptr;
|
|
tmp->DropBytecodeCacheReferences();
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ScriptLoadRequest)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFetchOptions, mCacheInfo, mLoadContext,
|
|
mLoadedScript)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ScriptLoadRequest)
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mScriptForBytecodeEncoding)
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
|
|
|
ScriptLoadRequest::ScriptLoadRequest(
|
|
ScriptKind aKind, nsIURI* aURI,
|
|
mozilla::dom::ReferrerPolicy aReferrerPolicy,
|
|
ScriptFetchOptions* aFetchOptions, const SRIMetadata& aIntegrity,
|
|
nsIURI* aReferrer, LoadContextBase* aContext)
|
|
: mKind(aKind),
|
|
mState(State::CheckingCache),
|
|
mFetchSourceOnly(false),
|
|
mReferrerPolicy(aReferrerPolicy),
|
|
mFetchOptions(aFetchOptions),
|
|
mIntegrity(aIntegrity),
|
|
mReferrer(aReferrer),
|
|
mURI(aURI),
|
|
mLoadContext(aContext),
|
|
mEarlyHintPreloaderId(0) {
|
|
MOZ_ASSERT(mFetchOptions);
|
|
if (mLoadContext) {
|
|
mLoadContext->SetRequest(this);
|
|
}
|
|
}
|
|
|
|
ScriptLoadRequest::~ScriptLoadRequest() { DropJSObjects(this); }
|
|
|
|
void ScriptLoadRequest::SetReady() {
|
|
MOZ_ASSERT(!IsFinished());
|
|
mState = State::Ready;
|
|
}
|
|
|
|
void ScriptLoadRequest::Cancel() {
|
|
mState = State::Canceled;
|
|
if (HasScriptLoadContext()) {
|
|
GetScriptLoadContext()->MaybeCancelOffThreadScript();
|
|
}
|
|
}
|
|
|
|
void ScriptLoadRequest::DropBytecodeCacheReferences() {
|
|
mCacheInfo = nullptr;
|
|
DropJSObjects(this);
|
|
}
|
|
|
|
bool ScriptLoadRequest::HasScriptLoadContext() const {
|
|
return HasLoadContext() && mLoadContext->IsWindowContext();
|
|
}
|
|
|
|
bool ScriptLoadRequest::HasWorkerLoadContext() const {
|
|
return HasLoadContext() && mLoadContext->IsWorkerContext();
|
|
}
|
|
|
|
mozilla::dom::ScriptLoadContext* ScriptLoadRequest::GetScriptLoadContext() {
|
|
MOZ_ASSERT(mLoadContext);
|
|
return mLoadContext->AsWindowContext();
|
|
}
|
|
|
|
mozilla::loader::SyncLoadContext* ScriptLoadRequest::GetSyncLoadContext() {
|
|
MOZ_ASSERT(mLoadContext);
|
|
return mLoadContext->AsSyncContext();
|
|
}
|
|
|
|
mozilla::dom::WorkerLoadContext* ScriptLoadRequest::GetWorkerLoadContext() {
|
|
MOZ_ASSERT(mLoadContext);
|
|
return mLoadContext->AsWorkerContext();
|
|
}
|
|
|
|
mozilla::dom::WorkletLoadContext* ScriptLoadRequest::GetWorkletLoadContext() {
|
|
MOZ_ASSERT(mLoadContext);
|
|
return mLoadContext->AsWorkletContext();
|
|
}
|
|
|
|
ModuleLoadRequest* ScriptLoadRequest::AsModuleRequest() {
|
|
MOZ_ASSERT(IsModuleRequest());
|
|
return static_cast<ModuleLoadRequest*>(this);
|
|
}
|
|
|
|
const ModuleLoadRequest* ScriptLoadRequest::AsModuleRequest() const {
|
|
MOZ_ASSERT(IsModuleRequest());
|
|
return static_cast<const ModuleLoadRequest*>(this);
|
|
}
|
|
|
|
void ScriptLoadRequest::NoCacheEntryFound() {
|
|
MOZ_ASSERT(IsCheckingCache());
|
|
MOZ_ASSERT(mURI);
|
|
// At the time where we check in the cache, the mBaseURL is not set, as this
|
|
// is resolved by the network. Thus we use the mURI, for checking the cache
|
|
// and later replace the mBaseURL using what the Channel->GetURI will provide.
|
|
switch (mKind) {
|
|
case ScriptKind::eClassic:
|
|
case ScriptKind::eImportMap:
|
|
mLoadedScript = new ClassicScript(mReferrerPolicy, mFetchOptions, mURI);
|
|
break;
|
|
case ScriptKind::eModule:
|
|
mLoadedScript = new ModuleScript(mReferrerPolicy, mFetchOptions, mURI);
|
|
break;
|
|
case ScriptKind::eEvent:
|
|
MOZ_ASSERT_UNREACHABLE("EventScripts are not using ScriptLoadRequest");
|
|
break;
|
|
}
|
|
mState = State::Fetching;
|
|
}
|
|
|
|
void ScriptLoadRequest::SetPendingFetchingError() {
|
|
MOZ_ASSERT(IsCheckingCache());
|
|
mState = State::PendingFetchingError;
|
|
}
|
|
|
|
void ScriptLoadRequest::MarkScriptForBytecodeEncoding(JSScript* aScript) {
|
|
MOZ_ASSERT(!IsModuleRequest());
|
|
MOZ_ASSERT(!mScriptForBytecodeEncoding);
|
|
MarkForBytecodeEncoding();
|
|
mScriptForBytecodeEncoding = aScript;
|
|
HoldJSObjects(this);
|
|
}
|
|
|
|
static bool IsInternalURIScheme(nsIURI* uri) {
|
|
return uri->SchemeIs("moz-extension") || uri->SchemeIs("resource") ||
|
|
uri->SchemeIs("chrome");
|
|
}
|
|
|
|
void ScriptLoadRequest::SetBaseURLFromChannelAndOriginalURI(
|
|
nsIChannel* aChannel, nsIURI* aOriginalURI) {
|
|
// Fixup moz-extension: and resource: URIs, because the channel URI will
|
|
// point to file:, which won't be allowed to load.
|
|
if (aOriginalURI && IsInternalURIScheme(aOriginalURI)) {
|
|
mBaseURL = aOriginalURI;
|
|
} else {
|
|
aChannel->GetURI(getter_AddRefs(mBaseURL));
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
// ScriptLoadRequestList
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
ScriptLoadRequestList::~ScriptLoadRequestList() { CancelRequestsAndClear(); }
|
|
|
|
void ScriptLoadRequestList::CancelRequestsAndClear() {
|
|
while (!isEmpty()) {
|
|
RefPtr<ScriptLoadRequest> first = StealFirst();
|
|
first->Cancel();
|
|
// And just let it go out of scope and die.
|
|
}
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
bool ScriptLoadRequestList::Contains(ScriptLoadRequest* aElem) const {
|
|
for (const ScriptLoadRequest* req = getFirst(); req; req = req->getNext()) {
|
|
if (req == aElem) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
#endif // DEBUG
|
|
|
|
} // namespace JS::loader
|