Bug 1742438 - Part 3: Split ScriptLoadInfo into ScriptLoadRequest and ScriptLoadInfo (as a LoadContext) classes; r=asuth,jonco

Here we split ScriptLoadInfo's representation -- we are distinguishing between "what is being loaded"
and "how it is being loaded in a worker context". Requesting review from asuth for the workers side
of things, and jonco for js/loader.

Differential Revision: https://phabricator.services.mozilla.com/D146175
This commit is contained in:
Yulia Startsev 2022-07-14 17:07:25 +00:00
parent c7e0fc2f1f
commit adbf7d814a
12 changed files with 209 additions and 172 deletions

View File

@ -77,19 +77,13 @@
#define MAX_CONCURRENT_SCRIPTS 1000
using JS::loader::ScriptKind;
using JS::loader::ScriptLoadRequest;
using mozilla::ipc::PrincipalInfo;
namespace mozilla::dom::workerinternals {
namespace {
ScriptLoadInfo* AsWorkerRequest(JS::loader::ScriptLoadRequest* req) {
return static_cast<ScriptLoadInfo*>(req);
}
JS::loader::ScriptLoadRequest* AsScriptRequest(ScriptLoadInfo* aRequest) {
return static_cast<JS::loader::ScriptLoadRequest*>(aRequest);
}
nsresult ConstructURI(const nsAString& aScriptURL, nsIURI* baseURI,
const mozilla::Encoding* aDocumentEncoding,
nsIURI** aResult) {
@ -409,12 +403,12 @@ NS_IMPL_ISUPPORTS(ScriptLoaderRunnable, nsIRunnable, nsINamed)
class ScriptExecutorRunnable final : public MainThreadWorkerSyncRunnable {
WorkerScriptLoader& mScriptLoader;
ScriptLoadInfo* mRequest;
ScriptLoadRequest* mRequest;
public:
ScriptExecutorRunnable(WorkerScriptLoader& aScriptLoader,
nsIEventTarget* aSyncLoopTarget,
ScriptLoadInfo* aRequest);
ScriptLoadRequest* aRequest);
private:
~ScriptExecutorRunnable() = default;
@ -477,6 +471,8 @@ WorkerScriptLoader::WorkerScriptLoader(
MOZ_ASSERT_IF(aIsMainScript, aScriptURLs.Length() == 1);
for (const nsString& aScriptURL : aScriptURLs) {
RefPtr<ScriptLoadInfo> loadContext = new ScriptLoadInfo(aScriptURL);
// Create ScriptLoadRequests for this WorkerScriptLoader
ReferrerPolicy aReferrerPolicy = mWorkerPrivate->GetReferrerPolicy();
@ -488,14 +484,19 @@ WorkerScriptLoader::WorkerScriptLoader(
nsCOMPtr<nsIURI> aURI;
nsresult rv = ConstructURI(aScriptURL, baseURI, aDocumentEncoding,
getter_AddRefs(aURI));
// If we failed to construct the URI, handle it in the LoadContext so it is
// thrown in the right order.
if (NS_WARN_IF(NS_FAILED(rv))) {
loadContext->mLoadResult = rv;
}
RefPtr<ScriptFetchOptions> fetchOptions =
new ScriptFetchOptions(CORSMode::CORS_NONE, aReferrerPolicy, nullptr);
RefPtr<ScriptLoadInfo> request = new ScriptLoadInfo(aURI, fetchOptions);
request->mURL = aScriptURL;
if (NS_WARN_IF(NS_FAILED(rv))) {
request->mLoadResult = rv;
}
RefPtr<ScriptLoadRequest> request =
new ScriptLoadRequest(ScriptKind::eClassic, aURI, fetchOptions,
SRIMetadata(), nullptr, /* = aReferrer */
loadContext);
mLoadingRequests.AppendElement(request);
}
@ -533,14 +534,16 @@ nsIURI* WorkerScriptLoader::GetBaseURI() {
return baseURI;
}
void WorkerScriptLoader::LoadingFinished(ScriptLoadInfo* aRequest,
void WorkerScriptLoader::LoadingFinished(ScriptLoadRequest* aRequest,
nsresult aRv) {
AssertIsOnMainThread();
aRequest->mLoadResult = aRv;
ScriptLoadInfo* loadContext = aRequest->GetWorkerLoadContext();
MOZ_ASSERT(!aRequest->mLoadingFinished);
aRequest->mLoadingFinished = true;
loadContext->mLoadResult = aRv;
MOZ_ASSERT(!loadContext->mLoadingFinished);
loadContext->mLoadingFinished = true;
if (IsMainWorkerScript() && NS_SUCCEEDED(aRv)) {
MOZ_DIAGNOSTIC_ASSERT(mWorkerPrivate->PrincipalURIMatchesScriptURL());
@ -549,25 +552,28 @@ void WorkerScriptLoader::LoadingFinished(ScriptLoadInfo* aRequest,
MaybeExecuteFinishedScripts(aRequest);
}
void WorkerScriptLoader::MaybeExecuteFinishedScripts(ScriptLoadInfo* aRequest) {
void WorkerScriptLoader::MaybeExecuteFinishedScripts(
ScriptLoadRequest* aRequest) {
AssertIsOnMainThread();
// We execute the last step if we don't have a pending operation with the
// cache and the loading is completed.
if (aRequest->Finished()) {
aRequest->ClearCacheCreator();
ScriptLoadInfo* loadContext = aRequest->GetWorkerLoadContext();
if (loadContext->Finished()) {
loadContext->ClearCacheCreator();
DispatchMaybeMoveToLoadedList(aRequest);
}
}
void WorkerScriptLoader::MaybeMoveToLoadedList(ScriptLoadInfo* aRequest) {
void WorkerScriptLoader::MaybeMoveToLoadedList(ScriptLoadRequest* aRequest) {
mWorkerPrivate->AssertIsOnWorkerThread();
MOZ_ASSERT(!aRequest->mExecutionScheduled);
aRequest->mExecutionScheduled = true;
ScriptLoadInfo* loadContext = aRequest->GetWorkerLoadContext();
MOZ_ASSERT(!loadContext->mExecutionScheduled);
loadContext->mExecutionScheduled = true;
while (!mLoadingRequests.isEmpty()) {
ScriptLoadRequest* request = mLoadingRequests.getFirst();
if (!AsWorkerRequest(request)->mExecutionScheduled) {
if (!request->GetWorkerLoadContext()->mExecutionScheduled) {
break;
}
@ -614,14 +620,14 @@ bool WorkerScriptLoader::ProcessPendingRequests(JSContext* aCx) {
while (!mLoadedRequests.isEmpty()) {
RefPtr<ScriptLoadRequest> req = mLoadedRequests.StealFirst();
ScriptLoadInfo* loadInfo = AsWorkerRequest(req);
ScriptLoadInfo* loadInfo = req->GetWorkerLoadContext();
// We don't have a ProcessRequest method (like we do on the DOM), as there
// isn't much processing that we need to do per request that isn't related
// to evaluation (the processsing done for the DOM is handled in
// DataRecievedFrom{Cache,Network} for workers.
// So, this inner loop calls EvaluateScript directly. This will change
// once modules are introduced as we will have some extra work to do.
if (!EvaluateScript(aCx, loadInfo)) {
if (!EvaluateScript(aCx, req)) {
mExecutionAborted = true;
mMutedErrorFlag = loadInfo->mMutedErrorFlag.valueOr(true);
mLoadedRequests.CancelRequestsAndClear();
@ -632,7 +638,7 @@ bool WorkerScriptLoader::ProcessPendingRequests(JSContext* aCx) {
return true;
}
nsresult WorkerScriptLoader::OnStreamComplete(ScriptLoadInfo* aRequest,
nsresult WorkerScriptLoader::OnStreamComplete(ScriptLoadRequest* aRequest,
nsresult aStatus) {
AssertIsOnMainThread();
@ -667,10 +673,9 @@ nsresult WorkerScriptLoader::LoadScripts() {
if (!mWorkerPrivate->IsServiceWorker() || IsDebuggerScript()) {
for (ScriptLoadRequest* req = mLoadingRequests.getFirst(); req;
req = req->getNext()) {
ScriptLoadInfo* loadInfo = AsWorkerRequest(req);
nsresult rv = LoadScript(loadInfo);
nsresult rv = LoadScript(req);
if (NS_WARN_IF(NS_FAILED(rv))) {
LoadingFinished(loadInfo, rv);
LoadingFinished(req, rv);
return rv;
}
}
@ -682,10 +687,10 @@ nsresult WorkerScriptLoader::LoadScripts() {
for (ScriptLoadRequest* req = mLoadingRequests.getFirst(); req;
req = req->getNext()) {
ScriptLoadInfo* loadInfo = AsWorkerRequest(req);
ScriptLoadInfo* loadInfo = req->GetWorkerLoadContext();
loadInfo->SetCacheCreator(cacheCreator);
loadInfo->GetCacheCreator()->AddLoader(
MakeNotNull<RefPtr<CacheLoadHandler>>(mWorkerPrivate, loadInfo,
MakeNotNull<RefPtr<CacheLoadHandler>>(mWorkerPrivate, req,
IsMainWorkerScript(), this));
}
@ -706,13 +711,15 @@ nsresult WorkerScriptLoader::LoadScripts() {
return NS_OK;
}
nsresult WorkerScriptLoader::LoadScript(ScriptLoadInfo* aRequest) {
nsresult WorkerScriptLoader::LoadScript(ScriptLoadRequest* aRequest) {
AssertIsOnMainThread();
MOZ_ASSERT_IF(IsMainWorkerScript(), !IsDebuggerScript());
ScriptLoadInfo* loadContext = aRequest->GetWorkerLoadContext();
// The URL passed to us for loading was invalid, stop loading at this point.
if (aRequest->mLoadResult != NS_ERROR_NOT_INITIALIZED) {
return aRequest->mLoadResult;
if (loadContext->mLoadResult != NS_ERROR_NOT_INITIALIZED) {
return loadContext->mLoadResult;
}
WorkerPrivate* parentWorker = mWorkerPrivate->GetParent();
@ -746,7 +753,7 @@ nsresult WorkerScriptLoader::LoadScript(ScriptLoadInfo* aRequest) {
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
NS_ASSERTION(secMan, "This should never be null!");
nsresult& rv = aRequest->mLoadResult;
nsresult& rv = loadContext->mLoadResult;
nsLoadFlags loadFlags = mWorkerPrivate->GetLoadFlags();
@ -781,14 +788,12 @@ nsresult WorkerScriptLoader::LoadScript(ScriptLoadInfo* aRequest) {
->CloneWithNewPolicy(parentWorker->GetReferrerPolicy());
}
ScriptLoadRequest* req = AsScriptRequest(aRequest);
rv = ChannelFromScriptURL(principal, parentDoc, mWorkerPrivate, loadGroup,
ios, secMan, req->mURI, mClientInfo, mController,
IsMainWorkerScript(), mWorkerScriptType,
mWorkerPrivate->ContentPolicyType(), loadFlags,
mWorkerPrivate->CookieJarSettings(), referrerInfo,
getter_AddRefs(channel));
rv = ChannelFromScriptURL(
principal, parentDoc, mWorkerPrivate, loadGroup, ios, secMan,
aRequest->mURI, mClientInfo, mController, IsMainWorkerScript(),
mWorkerScriptType, mWorkerPrivate->ContentPolicyType(), loadFlags,
mWorkerPrivate->CookieJarSettings(), referrerInfo,
getter_AddRefs(channel));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -849,7 +854,7 @@ nsresult WorkerScriptLoader::LoadScript(ScriptLoadInfo* aRequest) {
channelLoadInfo->SetLoadingEmbedderPolicy(respectedCOEP);
}
if (aRequest->mCacheStatus != ScriptLoadInfo::ToBeCached) {
if (loadContext->mCacheStatus != ScriptLoadInfo::ToBeCached) {
rv = channel->AsyncOpen(loader);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@ -858,10 +863,11 @@ nsresult WorkerScriptLoader::LoadScript(ScriptLoadInfo* aRequest) {
nsCOMPtr<nsIOutputStream> writer;
// In case we return early.
aRequest->mCacheStatus = ScriptLoadInfo::Cancel;
loadContext->mCacheStatus = ScriptLoadInfo::Cancel;
rv = NS_NewPipe(
getter_AddRefs(aRequest->mCacheReadStream), getter_AddRefs(writer), 0,
getter_AddRefs(loadContext->mCacheReadStream), getter_AddRefs(writer),
0,
UINT32_MAX, // unlimited size to avoid writer WOULD_BLOCK case
true, false); // non-blocking reader, blocking writer
if (NS_WARN_IF(NS_FAILED(rv))) {
@ -885,7 +891,7 @@ nsresult WorkerScriptLoader::LoadScript(ScriptLoadInfo* aRequest) {
}
void WorkerScriptLoader::DispatchMaybeMoveToLoadedList(
ScriptLoadInfo* aRequest) {
ScriptLoadRequest* aRequest) {
AssertIsOnMainThread();
if (IsMainWorkerScript()) {
@ -900,17 +906,19 @@ void WorkerScriptLoader::DispatchMaybeMoveToLoadedList(
}
bool WorkerScriptLoader::EvaluateScript(JSContext* aCx,
ScriptLoadInfo* aRequest) {
ScriptLoadRequest* aRequest) {
mWorkerPrivate->AssertIsOnWorkerThread();
NS_ASSERTION(aRequest->mExecutionScheduled, "Should be scheduled!");
NS_ASSERTION(!aRequest->mExecutionResult, "Should not have executed yet!");
ScriptLoadInfo* loadContext = aRequest->GetWorkerLoadContext();
NS_ASSERTION(loadContext->mExecutionScheduled, "Should be scheduled!");
NS_ASSERTION(!loadContext->mExecutionResult, "Should not have executed yet!");
MOZ_ASSERT(!mRv.Failed(), "Who failed it and why?");
mRv.MightThrowJSException();
if (NS_FAILED(aRequest->mLoadResult)) {
workerinternals::ReportLoadError(mRv, aRequest->mLoadResult,
aRequest->mURL);
if (NS_FAILED(loadContext->mLoadResult)) {
workerinternals::ReportLoadError(mRv, loadContext->mLoadResult,
loadContext->mURL);
return false;
}
@ -925,16 +933,16 @@ bool WorkerScriptLoader::EvaluateScript(JSContext* aCx,
mWorkerPrivate->ExecutionReady();
}
NS_ConvertUTF16toUTF8 filename(aRequest->mURL);
NS_ConvertUTF16toUTF8 filename(loadContext->mURL);
JS::CompileOptions options(aCx);
options.setFileAndLine(filename.get(), 1).setNoScriptRval(true);
MOZ_ASSERT(aRequest->mMutedErrorFlag.isSome());
options.setMutedErrors(aRequest->mMutedErrorFlag.valueOr(true));
MOZ_ASSERT(loadContext->mMutedErrorFlag.isSome());
options.setMutedErrors(loadContext->mMutedErrorFlag.valueOr(true));
if (aRequest->mSourceMapURL) {
options.setSourceMapURL(aRequest->mSourceMapURL->get());
if (loadContext->mSourceMapURL) {
options.setSourceMapURL(loadContext->mSourceMapURL->get());
}
// Our ErrorResult still shouldn't be a failure.
@ -942,21 +950,22 @@ bool WorkerScriptLoader::EvaluateScript(JSContext* aCx,
// Transfer script length to a local variable, encoding-agnostically.
size_t scriptLength = 0;
std::swap(scriptLength, aRequest->mScriptLength);
std::swap(scriptLength, loadContext->mScriptLength);
// This transfers script data out of the active arm of |aRequest->mScript|.
// This transfers script data out of the active arm of
// |loadContext->mScript|.
bool successfullyEvaluated =
aRequest->mScriptIsUTF8
? EvaluateSourceBuffer(aCx, options, aRequest->mScript.mUTF8,
loadContext->mScriptIsUTF8
? EvaluateSourceBuffer(aCx, options, loadContext->mScript.mUTF8,
scriptLength)
: EvaluateSourceBuffer(aCx, options, aRequest->mScript.mUTF16,
: EvaluateSourceBuffer(aCx, options, loadContext->mScript.mUTF16,
scriptLength);
MOZ_ASSERT(aRequest->ScriptTextIsNull());
MOZ_ASSERT(loadContext->ScriptTextIsNull());
if (!successfullyEvaluated) {
mRv.StealExceptionFromJSContext(aCx);
return false;
}
aRequest->mExecutionResult = true;
loadContext->mExecutionResult = true;
return true;
}
@ -1032,7 +1041,7 @@ NS_IMPL_ISUPPORTS(WorkerScriptLoader, nsINamed)
ScriptExecutorRunnable::ScriptExecutorRunnable(
WorkerScriptLoader& aScriptLoader, nsIEventTarget* aSyncLoopTarget,
ScriptLoadInfo* aRequest)
ScriptLoadRequest* aRequest)
: MainThreadWorkerSyncRunnable(aScriptLoader.mWorkerPrivate,
aSyncLoopTarget),
mScriptLoader(aScriptLoader),

View File

@ -7,7 +7,7 @@
#ifndef mozilla_dom_workers_scriptloader_h__
#define mozilla_dom_workers_scriptloader_h__
#include "mozilla/dom/ScriptLoadInfo.h"
#include "js/loader/ScriptLoadRequest.h"
#include "mozilla/dom/WorkerCommon.h"
#include "mozilla/Maybe.h"
#include "nsIContentPolicy.h"
@ -67,7 +67,7 @@ class NetworkLoadHandler;
* | new WorkerScriptLoader(..) |
* +----------------------------+
* |
* | Create the loader, along with the scriptLoadInfos
* | Create the loader, along with the ScriptLoadRequests
* | call DispatchLoadScripts()
* | Create ScriptLoaderRunnable
* |
@ -164,9 +164,9 @@ class WorkerScriptLoader final : public nsINamed {
protected:
nsIURI* GetBaseURI();
void MaybeExecuteFinishedScripts(ScriptLoadInfo* aRequest);
void MaybeExecuteFinishedScripts(ScriptLoadRequest* aRequest);
void MaybeMoveToLoadedList(ScriptLoadInfo* aRequest);
void MaybeMoveToLoadedList(ScriptLoadRequest* aRequest);
bool StoreCSP();
@ -176,7 +176,7 @@ class WorkerScriptLoader final : public nsINamed {
return mLoadingRequests.isEmpty() && mLoadedRequests.isEmpty();
}
nsresult OnStreamComplete(ScriptLoadInfo* aRequest, nsresult aStatus);
nsresult OnStreamComplete(ScriptLoadRequest* aRequest, nsresult aStatus);
// Are we loading the primary script, which is not a Debugger Script?
bool IsMainWorkerScript() const {
@ -200,7 +200,7 @@ class WorkerScriptLoader final : public nsINamed {
nsresult LoadScripts();
nsresult LoadScript(ScriptLoadInfo* aRequest);
nsresult LoadScript(ScriptLoadRequest* aRequest);
void ShutdownScriptLoader(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
bool aResult, bool aMutedError);
@ -214,11 +214,11 @@ class WorkerScriptLoader final : public nsINamed {
return NS_OK;
}
void LoadingFinished(ScriptLoadInfo* aRequest, nsresult aRv);
void LoadingFinished(ScriptLoadRequest* aRequest, nsresult aRv);
void DispatchMaybeMoveToLoadedList(ScriptLoadInfo* aRequest);
void DispatchMaybeMoveToLoadedList(ScriptLoadRequest* aRequest);
bool EvaluateScript(JSContext* aCx, ScriptLoadInfo* aRequest);
bool EvaluateScript(JSContext* aCx, ScriptLoadRequest* aRequest);
void LogExceptionToConsole(JSContext* aCx, WorkerPrivate* aWorkerPrivate);
};

View File

@ -6,6 +6,7 @@
#include "CacheLoadHandler.h"
#include "ScriptResponseHeaderProcessor.h" // ScriptResponseHeaderProcessor
#include "ScriptLoadInfo.h" // ScriptLoadInfo
#include "nsIPrincipal.h"
@ -38,21 +39,28 @@ NS_IMPL_ISUPPORTS(CacheLoadHandler, nsIStreamLoaderObserver)
NS_IMPL_ISUPPORTS0(CachePromiseHandler)
CachePromiseHandler::CachePromiseHandler(
WorkerScriptLoader* aLoader, JS::loader::ScriptLoadRequest* aRequest)
: mLoader(aLoader), mLoadContext(aRequest->GetWorkerLoadContext()) {
AssertIsOnMainThread();
MOZ_ASSERT(mLoader);
}
void CachePromiseHandler::ResolvedCallback(JSContext* aCx,
JS::Handle<JS::Value> aValue,
ErrorResult& aRv) {
AssertIsOnMainThread();
// May already have been canceled by CacheLoadHandler::Fail from
// CancelMainThread.
MOZ_ASSERT(mRequest->mCacheStatus == ScriptLoadInfo::WritingToCache ||
mRequest->mCacheStatus == ScriptLoadInfo::Cancel);
MOZ_ASSERT_IF(mRequest->mCacheStatus == ScriptLoadInfo::Cancel,
!mRequest->mCachePromise);
MOZ_ASSERT(mLoadContext->mCacheStatus == ScriptLoadInfo::WritingToCache ||
mLoadContext->mCacheStatus == ScriptLoadInfo::Cancel);
MOZ_ASSERT_IF(mLoadContext->mCacheStatus == ScriptLoadInfo::Cancel,
!mLoadContext->mCachePromise);
if (mRequest->mCachePromise) {
mRequest->mCacheStatus = ScriptLoadInfo::Cached;
mRequest->mCachePromise = nullptr;
mLoader->MaybeExecuteFinishedScripts(mRequest);
if (mLoadContext->mCachePromise) {
mLoadContext->mCacheStatus = ScriptLoadInfo::Cached;
mLoadContext->mCachePromise = nullptr;
mLoader->MaybeExecuteFinishedScripts(mLoadContext->mRequest);
}
}
@ -62,15 +70,15 @@ void CachePromiseHandler::RejectedCallback(JSContext* aCx,
AssertIsOnMainThread();
// May already have been canceled by CacheLoadHandler::Fail from
// CancelMainThread.
MOZ_ASSERT(mRequest->mCacheStatus == ScriptLoadInfo::WritingToCache ||
mRequest->mCacheStatus == ScriptLoadInfo::Cancel);
mRequest->mCacheStatus = ScriptLoadInfo::Cancel;
MOZ_ASSERT(mLoadContext->mCacheStatus == ScriptLoadInfo::WritingToCache ||
mLoadContext->mCacheStatus == ScriptLoadInfo::Cancel);
mLoadContext->mCacheStatus = ScriptLoadInfo::Cancel;
mRequest->mCachePromise = nullptr;
mLoadContext->mCachePromise = nullptr;
// This will delete the cache object and will call LoadingFinished() with an
// error for each ongoing operation.
mRequest->GetCacheCreator()->DeleteCache(NS_ERROR_FAILURE);
mLoadContext->GetCacheCreator()->DeleteCache(NS_ERROR_FAILURE);
}
CacheCreator::CacheCreator(WorkerPrivate* aWorkerPrivate)
@ -214,10 +222,10 @@ void CacheCreator::DeleteCache(nsresult aReason) {
}
CacheLoadHandler::CacheLoadHandler(WorkerPrivate* aWorkerPrivate,
ScriptLoadInfo* aRequest,
JS::loader::ScriptLoadRequest* aRequest,
bool aIsWorkerScript,
WorkerScriptLoader* aLoader)
: mRequest(aRequest),
: mLoadContext(aRequest->GetWorkerLoadContext()),
mLoader(aLoader),
mWorkerPrivate(aWorkerPrivate),
mIsWorkerScript(aIsWorkerScript),
@ -242,19 +250,19 @@ void CacheLoadHandler::Fail(nsresult aRv) {
mFailed = true;
if (mPump) {
MOZ_ASSERT(mRequest->mCacheStatus == ScriptLoadInfo::ReadingFromCache);
MOZ_ASSERT(mLoadContext->mCacheStatus == ScriptLoadInfo::ReadingFromCache);
mPump->Cancel(aRv);
mPump = nullptr;
}
mRequest->mCacheStatus = ScriptLoadInfo::Cancel;
mLoadContext->mCacheStatus = ScriptLoadInfo::Cancel;
if (mRequest->mCachePromise) {
mRequest->mCachePromise->MaybeReject(aRv);
if (mLoadContext->mCachePromise) {
mLoadContext->mCachePromise->MaybeReject(aRv);
}
mRequest->mCachePromise = nullptr;
mLoadContext->mCachePromise = nullptr;
mLoader->LoadingFinished(mRequest, aRv);
mLoader->LoadingFinished(mLoadContext->mRequest, aRv);
}
void CacheLoadHandler::Load(Cache* aCache) {
@ -263,7 +271,7 @@ void CacheLoadHandler::Load(Cache* aCache) {
nsCOMPtr<nsIURI> uri;
nsresult rv =
NS_NewURI(getter_AddRefs(uri), mRequest->mURL, nullptr, mBaseURI);
NS_NewURI(getter_AddRefs(uri), mLoadContext->mURL, nullptr, mBaseURI);
if (NS_WARN_IF(NS_FAILED(rv))) {
Fail(rv);
return;
@ -276,11 +284,11 @@ void CacheLoadHandler::Load(Cache* aCache) {
return;
}
MOZ_ASSERT(mRequest->mFullURL.IsEmpty());
CopyUTF8toUTF16(spec, mRequest->mFullURL);
MOZ_ASSERT(mLoadContext->mFullURL.IsEmpty());
CopyUTF8toUTF16(spec, mLoadContext->mFullURL);
mozilla::dom::RequestOrUSVString request;
request.SetAsUSVString().ShareOrDependUpon(mRequest->mFullURL);
request.SetAsUSVString().ShareOrDependUpon(mLoadContext->mFullURL);
mozilla::dom::CacheQueryOptions params;
@ -303,7 +311,7 @@ void CacheLoadHandler::RejectedCallback(JSContext* aCx,
JS::Handle<JS::Value> aValue,
ErrorResult& aRv) {
AssertIsOnMainThread();
MOZ_ASSERT(mRequest->mCacheStatus == ScriptLoadInfo::Uncached);
MOZ_ASSERT(mLoadContext->mCacheStatus == ScriptLoadInfo::Uncached);
Fail(NS_ERROR_FAILURE);
}
@ -316,7 +324,7 @@ void CacheLoadHandler::ResolvedCallback(JSContext* aCx,
return;
}
MOZ_ASSERT(mRequest->mCacheStatus == ScriptLoadInfo::Uncached);
MOZ_ASSERT(mLoadContext->mCacheStatus == ScriptLoadInfo::Uncached);
nsresult rv;
@ -338,8 +346,8 @@ void CacheLoadHandler::ResolvedCallback(JSContext* aCx,
return;
}
mRequest->mCacheStatus = ScriptLoadInfo::ToBeCached;
rv = mLoader->LoadScript(mRequest);
mLoadContext->mCacheStatus = ScriptLoadInfo::ToBeCached;
rv = mLoader->LoadScript(mLoadContext->mRequest);
if (NS_WARN_IF(NS_FAILED(rv))) {
Fail(rv);
}
@ -387,11 +395,11 @@ void CacheLoadHandler::ResolvedCallback(JSContext* aCx,
}
if (!inputStream) {
mRequest->mCacheStatus = ScriptLoadInfo::Cached;
mLoadContext->mCacheStatus = ScriptLoadInfo::Cached;
nsresult rv = DataReceivedFromCache(
(uint8_t*)"", 0, mChannelInfo, std::move(mPrincipalInfo),
mCSPHeaderValue, mCSPReportOnlyHeaderValue, mReferrerPolicyHeaderValue);
mLoader->OnStreamComplete(mRequest, rv);
mLoader->OnStreamComplete(mLoadContext->mRequest, rv);
return;
}
@ -430,7 +438,7 @@ void CacheLoadHandler::ResolvedCallback(JSContext* aCx,
}
}
mRequest->mCacheStatus = ScriptLoadInfo::ReadingFromCache;
mLoadContext->mCacheStatus = ScriptLoadInfo::ReadingFromCache;
}
NS_IMETHODIMP
@ -443,20 +451,20 @@ CacheLoadHandler::OnStreamComplete(nsIStreamLoader* aLoader,
mPump = nullptr;
if (NS_FAILED(aStatus)) {
MOZ_ASSERT(mRequest->mCacheStatus == ScriptLoadInfo::ReadingFromCache ||
mRequest->mCacheStatus == ScriptLoadInfo::Cancel);
MOZ_ASSERT(mLoadContext->mCacheStatus == ScriptLoadInfo::ReadingFromCache ||
mLoadContext->mCacheStatus == ScriptLoadInfo::Cancel);
Fail(aStatus);
return NS_OK;
}
MOZ_ASSERT(mRequest->mCacheStatus == ScriptLoadInfo::ReadingFromCache);
mRequest->mCacheStatus = ScriptLoadInfo::Cached;
MOZ_ASSERT(mLoadContext->mCacheStatus == ScriptLoadInfo::ReadingFromCache);
mLoadContext->mCacheStatus = ScriptLoadInfo::Cached;
MOZ_ASSERT(mPrincipalInfo);
nsresult rv = DataReceivedFromCache(
aString, aStringLen, mChannelInfo, std::move(mPrincipalInfo),
mCSPHeaderValue, mCSPReportOnlyHeaderValue, mReferrerPolicyHeaderValue);
return mLoader->OnStreamComplete(mRequest, rv);
return mLoader->OnStreamComplete(mLoadContext->mRequest, rv);
}
nsresult CacheLoadHandler::DataReceivedFromCache(
@ -467,11 +475,12 @@ nsresult CacheLoadHandler::DataReceivedFromCache(
const nsACString& aReferrerPolicyHeaderValue) {
AssertIsOnMainThread();
if (mLoader->IsCancelled()) {
mRequest->GetCacheCreator()->DeleteCache(mLoader->mCancelMainThread.ref());
mLoadContext->GetCacheCreator()->DeleteCache(
mLoader->mCancelMainThread.ref());
return mLoader->mCancelMainThread.ref();
}
MOZ_ASSERT(mRequest->mCacheStatus == ScriptLoadInfo::Cached);
MOZ_ASSERT(mLoadContext->mCacheStatus == ScriptLoadInfo::Cached);
auto responsePrincipalOrErr = PrincipalInfoToPrincipal(*aPrincipalInfo);
MOZ_DIAGNOSTIC_ASSERT(responsePrincipalOrErr.isOk());
@ -485,28 +494,29 @@ nsresult CacheLoadHandler::DataReceivedFromCache(
nsCOMPtr<nsIPrincipal> responsePrincipal = responsePrincipalOrErr.unwrap();
mRequest->mMutedErrorFlag.emplace(!principal->Subsumes(responsePrincipal));
mLoadContext->mMutedErrorFlag.emplace(
!principal->Subsumes(responsePrincipal));
// May be null.
Document* parentDoc = mWorkerPrivate->GetDocument();
MOZ_ASSERT(mRequest->ScriptTextIsNull());
MOZ_ASSERT(mLoadContext->ScriptTextIsNull());
nsresult rv;
if (StaticPrefs::dom_worker_script_loader_utf8_parsing_enabled()) {
mRequest->InitUTF8Script();
mLoadContext->InitUTF8Script();
rv = ScriptLoader::ConvertToUTF8(nullptr, aString, aStringLen, u"UTF-8"_ns,
parentDoc, mRequest->mScript.mUTF8,
mRequest->mScriptLength);
parentDoc, mLoadContext->mScript.mUTF8,
mLoadContext->mScriptLength);
} else {
mRequest->InitUTF16Script();
mLoadContext->InitUTF16Script();
rv = ScriptLoader::ConvertToUTF16(nullptr, aString, aStringLen, u"UTF-8"_ns,
parentDoc, mRequest->mScript.mUTF16,
mRequest->mScriptLength);
parentDoc, mLoadContext->mScript.mUTF16,
mLoadContext->mScriptLength);
}
if (NS_SUCCEEDED(rv) && mLoader->IsMainWorkerScript()) {
nsCOMPtr<nsIURI> finalURI;
rv = NS_NewURI(getter_AddRefs(finalURI), mRequest->mFullURL);
rv = NS_NewURI(getter_AddRefs(finalURI), mLoadContext->mFullURL);
if (NS_SUCCEEDED(rv)) {
mWorkerPrivate->SetBaseURI(finalURI);
}

View File

@ -78,7 +78,8 @@ class CacheLoadHandler final : public PromiseNativeHandler,
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMLOADEROBSERVER
CacheLoadHandler(WorkerPrivate* aWorkerPrivate, ScriptLoadInfo* aRequest,
CacheLoadHandler(WorkerPrivate* aWorkerPrivate,
JS::loader::ScriptLoadRequest* aRequest,
bool aIsWorkerScript, WorkerScriptLoader* aLoader);
void Fail(nsresult aRv);
@ -102,7 +103,7 @@ class CacheLoadHandler final : public PromiseNativeHandler,
const nsACString& aReferrerPolicyHeaderValue);
void DataReceived();
ScriptLoadInfo* mRequest;
ScriptLoadInfo* mLoadContext;
const RefPtr<WorkerScriptLoader> mLoader;
WorkerPrivate* const mWorkerPrivate;
const bool mIsWorkerScript;
@ -193,11 +194,8 @@ class CachePromiseHandler final : public PromiseNativeHandler {
public:
NS_DECL_ISUPPORTS
CachePromiseHandler(WorkerScriptLoader* aLoader, ScriptLoadInfo* aRequest)
: mLoader(aLoader), mRequest(aRequest) {
AssertIsOnMainThread();
MOZ_ASSERT(mLoader);
}
CachePromiseHandler(WorkerScriptLoader* aLoader,
JS::loader::ScriptLoadRequest* aRequest);
virtual void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
ErrorResult& aRv) override;
@ -209,7 +207,7 @@ class CachePromiseHandler final : public PromiseNativeHandler {
~CachePromiseHandler() { AssertIsOnMainThread(); }
RefPtr<WorkerScriptLoader> mLoader;
ScriptLoadInfo* mRequest;
ScriptLoadInfo* mLoadContext;
};
} // namespace workerinternals::loader

View File

@ -36,10 +36,10 @@ NS_IMPL_ISUPPORTS(NetworkLoadHandler, nsIStreamLoaderObserver,
nsIRequestObserver)
NetworkLoadHandler::NetworkLoadHandler(WorkerScriptLoader* aLoader,
ScriptLoadInfo* aRequest)
JS::loader::ScriptLoadRequest* aRequest)
: mLoader(aLoader),
mWorkerPrivate(aLoader->mWorkerPrivate),
mRequest(aRequest) {
mLoadContext(aRequest->GetWorkerLoadContext()) {
MOZ_ASSERT(mLoader);
}
@ -49,7 +49,7 @@ NetworkLoadHandler::OnStreamComplete(nsIStreamLoader* aLoader,
uint32_t aStringLen,
const uint8_t* aString) {
nsresult rv = DataReceivedFromNetwork(aLoader, aStatus, aStringLen, aString);
return mLoader->OnStreamComplete(mRequest, rv);
return mLoader->OnStreamComplete(mLoadContext->mRequest, rv);
}
nsresult NetworkLoadHandler::DataReceivedFromNetwork(nsIStreamLoader* aLoader,
@ -109,8 +109,8 @@ nsresult NetworkLoadHandler::DataReceivedFromNetwork(nsIStreamLoader* aLoader,
// same-origin checks on them so we should be able to see their errors.
// Note that for data: url, where we allow it through the same-origin check
// but then give it a different origin.
mRequest->mMutedErrorFlag.emplace(!mLoader->IsMainWorkerScript() &&
!principal->Subsumes(channelPrincipal));
mLoadContext->mMutedErrorFlag.emplace(!mLoader->IsMainWorkerScript() &&
!principal->Subsumes(channelPrincipal));
// Make sure we're not seeing the result of a 404 or something by checking
// the 'requestSucceeded' attribute on the http channel.
@ -137,7 +137,7 @@ nsresult NetworkLoadHandler::DataReceivedFromNetwork(nsIStreamLoader* aLoader,
nsAutoCString sourceMapURL;
if (nsContentUtils::GetSourceMapURL(httpChannel, sourceMapURL)) {
mRequest->mSourceMapURL = Some(NS_ConvertUTF8toUTF16(sourceMapURL));
mLoadContext->mSourceMapURL = Some(NS_ConvertUTF8toUTF16(sourceMapURL));
}
}
@ -149,22 +149,22 @@ nsresult NetworkLoadHandler::DataReceivedFromNetwork(nsIStreamLoader* aLoader,
// Worker scripts are always decoded as UTF-8 per spec. Passing null for a
// channel and UTF-8 for the hint will always interpret |aString| as UTF-8.
if (StaticPrefs::dom_worker_script_loader_utf8_parsing_enabled()) {
mRequest->InitUTF8Script();
mLoadContext->InitUTF8Script();
rv = ScriptLoader::ConvertToUTF8(nullptr, aString, aStringLen, u"UTF-8"_ns,
parentDoc, mRequest->mScript.mUTF8,
mRequest->mScriptLength);
parentDoc, mLoadContext->mScript.mUTF8,
mLoadContext->mScriptLength);
} else {
mRequest->InitUTF16Script();
mLoadContext->InitUTF16Script();
rv = ScriptLoader::ConvertToUTF16(nullptr, aString, aStringLen, u"UTF-8"_ns,
parentDoc, mRequest->mScript.mUTF16,
mRequest->mScriptLength);
parentDoc, mLoadContext->mScript.mUTF16,
mLoadContext->mScriptLength);
}
if (NS_FAILED(rv)) {
return rv;
}
if (mRequest->ScriptTextIsNull()) {
if (mRequest->mScriptLength != 0) {
if (mLoadContext->ScriptTextIsNull()) {
if (mLoadContext->mScriptLength != 0) {
return NS_ERROR_FAILURE;
}
@ -186,7 +186,7 @@ nsresult NetworkLoadHandler::DataReceivedFromNetwork(nsIStreamLoader* aLoader,
if (!filename.IsEmpty()) {
// This will help callers figure out what their script url resolved to
// in case of errors.
mRequest->mURL.Assign(NS_ConvertUTF8toUTF16(filename));
mLoadContext->mURL.Assign(NS_ConvertUTF8toUTF16(filename));
}
}
@ -295,7 +295,8 @@ nsresult NetworkLoadHandler::PrepareForRequest(nsIRequest* aRequest) {
ServiceWorkerManager::LocalizeAndReportToAllClients(
scope, "ServiceWorkerRegisterMimeTypeError2",
nsTArray<nsString>{NS_ConvertUTF8toUTF16(scope),
NS_ConvertUTF8toUTF16(mimeType), mRequest->mURL});
NS_ConvertUTF8toUTF16(mimeType),
mLoadContext->mURL});
return NS_ERROR_DOM_NETWORK_ERR;
}
@ -304,11 +305,12 @@ nsresult NetworkLoadHandler::PrepareForRequest(nsIRequest* aRequest) {
// We synthesize the result code, but its never exposed to content.
SafeRefPtr<mozilla::dom::InternalResponse> ir =
MakeSafeRefPtr<mozilla::dom::InternalResponse>(200, "OK"_ns);
ir->SetBody(mRequest->mCacheReadStream, InternalResponse::UNKNOWN_BODY_SIZE);
ir->SetBody(mLoadContext->mCacheReadStream,
InternalResponse::UNKNOWN_BODY_SIZE);
// Drop our reference to the stream now that we've passed it along, so it
// doesn't hang around once the cache is done with it and keep data alive.
mRequest->mCacheReadStream = nullptr;
mLoadContext->mCacheReadStream = nullptr;
// Set the channel info of the channel on the response so that it's
// saved in the cache.
@ -330,12 +332,12 @@ nsresult NetworkLoadHandler::PrepareForRequest(nsIRequest* aRequest) {
ir->Headers()->FillResponseHeaders(channel);
RefPtr<mozilla::dom::Response> response = new mozilla::dom::Response(
mRequest->GetCacheCreator()->Global(), std::move(ir), nullptr);
mLoadContext->GetCacheCreator()->Global(), std::move(ir), nullptr);
mozilla::dom::RequestOrUSVString request;
MOZ_ASSERT(!mRequest->mFullURL.IsEmpty());
request.SetAsUSVString().ShareOrDependUpon(mRequest->mFullURL);
MOZ_ASSERT(!mLoadContext->mFullURL.IsEmpty());
request.SetAsUSVString().ShareOrDependUpon(mLoadContext->mFullURL);
// This JSContext will not end up executing JS code because here there are
// no ReadableStreams involved.
@ -343,7 +345,7 @@ nsresult NetworkLoadHandler::PrepareForRequest(nsIRequest* aRequest) {
jsapi.Init();
ErrorResult error;
RefPtr<Promise> cachePromise = mRequest->GetCacheCreator()->Cache_()->Put(
RefPtr<Promise> cachePromise = mLoadContext->GetCacheCreator()->Cache_()->Put(
jsapi.cx(), request, *response, error);
error.WouldReportJSException();
if (NS_WARN_IF(error.Failed())) {
@ -351,11 +353,11 @@ nsresult NetworkLoadHandler::PrepareForRequest(nsIRequest* aRequest) {
}
RefPtr<CachePromiseHandler> promiseHandler =
new CachePromiseHandler(mLoader, mRequest);
new CachePromiseHandler(mLoader, mLoadContext->mRequest);
cachePromise->AppendNativeHandler(promiseHandler);
mRequest->mCachePromise.swap(cachePromise);
mRequest->mCacheStatus = ScriptLoadInfo::WritingToCache;
mLoadContext->mCachePromise.swap(cachePromise);
mLoadContext->mCacheStatus = ScriptLoadInfo::WritingToCache;
return NS_OK;
}

View File

@ -41,7 +41,8 @@ class NetworkLoadHandler final : public nsIStreamLoaderObserver,
public:
NS_DECL_ISUPPORTS
NetworkLoadHandler(WorkerScriptLoader* aLoader, ScriptLoadInfo* aRequest);
NetworkLoadHandler(WorkerScriptLoader* aLoader,
JS::loader::ScriptLoadRequest* aRequest);
NS_IMETHOD
OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext,
@ -67,7 +68,7 @@ class NetworkLoadHandler final : public nsIStreamLoaderObserver,
RefPtr<WorkerScriptLoader> mLoader;
WorkerPrivate* const mWorkerPrivate;
ScriptLoadInfo* mRequest;
ScriptLoadInfo* mLoadContext;
};
} // namespace mozilla::dom::workerinternals::loader

View File

@ -10,12 +10,8 @@
namespace mozilla {
namespace dom {
ScriptLoadInfo::ScriptLoadInfo(nsIURI* aURI,
JS::loader::ScriptFetchOptions* aFetchOptions)
: JS::loader::ScriptLoadRequest(JS::loader::ScriptKind::eClassic, aURI,
aFetchOptions, SRIMetadata(),
nullptr, /* = aReferrer */
nullptr /* = aLoadContext*/) {
ScriptLoadInfo::ScriptLoadInfo(const nsString& aURL)
: JS::loader::LoadContextBase(JS::loader::ContextKind::Worker), mURL(aURL) {
MOZ_ASSERT(mScriptIsUTF8 == false, "set by member initializer");
MOZ_ASSERT(mScriptLength == 0, "set by member initializer");
mScript.mUTF16 = nullptr;

View File

@ -13,6 +13,7 @@
#include "mozilla/dom/Promise.h"
#include "js/loader/ScriptKind.h"
#include "js/loader/ScriptLoadRequest.h"
#include "js/loader/LoadContextBase.h"
class nsIReferrerInfo;
class nsIURI;
@ -26,9 +27,9 @@ namespace workerinternals::loader {
class CacheCreator;
}
class ScriptLoadInfo : public JS::loader::ScriptLoadRequest {
class ScriptLoadInfo : public JS::loader::LoadContextBase {
public:
ScriptLoadInfo(nsIURI* aURI, JS::loader::ScriptFetchOptions* aFetchOptions);
explicit ScriptLoadInfo(const nsString& aURL);
~ScriptLoadInfo();

View File

@ -6,6 +6,7 @@
#include "mozilla/dom/ScriptLoadContext.h"
#include "mozilla/loader/ComponentModuleLoader.h"
#include "mozilla/dom/ScriptLoadInfo.h"
#include "js/loader/LoadContextBase.h"
#include "js/loader/ScriptLoadRequest.h"
@ -53,4 +54,9 @@ mozilla::loader::ComponentLoadContext* LoadContextBase::AsComponentContext() {
return static_cast<mozilla::loader::ComponentLoadContext*>(this);
}
mozilla::dom::ScriptLoadInfo* LoadContextBase::AsWorkerContext() {
MOZ_ASSERT(IsWorkerContext());
return static_cast<mozilla::dom::ScriptLoadInfo*>(this);
}
} // namespace JS::loader

View File

@ -12,7 +12,8 @@
namespace mozilla::dom {
class ScriptLoadContext;
}
class ScriptLoadInfo;
} // namespace mozilla::dom
namespace mozilla::loader {
class ComponentLoadContext;
@ -37,8 +38,7 @@ class ScriptLoadRequest;
*
*/
// TODO: implement worker LoadContext
enum class ContextKind { Window, Component };
enum class ContextKind { Window, Component, Worker };
class LoadContextBase : public nsISupports {
private:
@ -64,6 +64,9 @@ class LoadContextBase : public nsISupports {
bool IsComponentContext() const { return mKind == ContextKind::Component; }
mozilla::loader::ComponentLoadContext* AsComponentContext();
bool IsWorkerContext() const { return mKind == ContextKind::Worker; }
mozilla::dom::ScriptLoadInfo* AsWorkerContext();
RefPtr<JS::loader::ScriptLoadRequest> mRequest;
};

View File

@ -9,6 +9,7 @@
#include "mozilla/dom/Document.h"
#include "mozilla/dom/ScriptLoadContext.h"
#include "mozilla/dom/ScriptLoadInfo.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/HoldDropJSObjects.h"
#include "mozilla/StaticPrefs_dom.h"
@ -136,6 +137,11 @@ ScriptLoadRequest::GetComponentLoadContext() {
return mLoadContext->AsComponentContext();
}
mozilla::dom::ScriptLoadInfo* ScriptLoadRequest::GetWorkerLoadContext() {
MOZ_ASSERT(mLoadContext);
return mLoadContext->AsWorkerContext();
}
ModuleLoadRequest* ScriptLoadRequest::AsModuleRequest() {
MOZ_ASSERT(IsModuleRequest());
return static_cast<ModuleLoadRequest*>(this);

View File

@ -33,7 +33,10 @@
class nsICacheInfoChannel;
namespace mozilla::dom {
class ScriptLoadContext;
class ScriptLoadInfo;
} // namespace mozilla::dom
namespace mozilla::loader {
@ -306,6 +309,8 @@ class ScriptLoadRequest
mozilla::loader::ComponentLoadContext* GetComponentLoadContext();
mozilla::dom::ScriptLoadInfo* GetWorkerLoadContext();
const ScriptKind mKind; // Whether this is a classic script or a module
// script.