fune/js/loader/LoadContextBase.h
Jon Coppeard 81c18a4a24 Bug 1877703 - Part 1: Remove speculatively preloaded modules from the module map when import map is registered r=smaug,allstarschh
The initial problem reported in the bug is that we try to speculatively load a
bareword import before the import map is dynamically inserted that makes that
load valid. The load fails and then we cache the failure in the module map.

The more general problem is that import maps change the locations that imports
are resolved to so if when there is a dynamically inserted import map
speculative preload may load and cache the wrong things.

This patch fixes this problem by removing any preloaded modules from the module
map when an import map is registered.

Previously we used to do something like this but it was changed because I
wasn't confident that it wouldn't remove too much. However it appears that this
is necessary to handle this situation, so it's implemented here but with more
checks that it only removes preloaded modules. This is handled by adding extra
flags where necessary so we have the information on hand to check.

I've made these diagnostic asserts so that this actually gets check in real use.

Differential Revision: https://phabricator.services.mozilla.com/D202611
2024-03-19 10:07:34 +00:00

76 lines
2.1 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/. */
#ifndef js_loader_BaseLoadContext_h
#define js_loader_BaseLoadContext_h
#include "js/loader/ScriptLoadRequest.h"
#include "nsIStringBundle.h"
namespace mozilla::dom {
class ScriptLoadContext;
class WorkerLoadContext;
class WorkletLoadContext;
} // namespace mozilla::dom
namespace mozilla::loader {
class SyncLoadContext;
}
namespace JS::loader {
class ScriptLoadRequest;
/*
* LoadContextBase
*
* LoadContexts augment the loading of a ScriptLoadRequest. This class
* is used as a base for all LoadContexts, and provides shared functionality.
*
*/
enum class ContextKind { Window, Sync, Worker, Worklet };
class LoadContextBase : public nsISupports {
private:
ContextKind mKind;
protected:
virtual ~LoadContextBase() = default;
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(LoadContextBase)
explicit LoadContextBase(ContextKind kind);
void SetRequest(JS::loader::ScriptLoadRequest* aRequest);
// Used to output a string for the Gecko Profiler.
virtual void GetProfilerLabel(nsACString& aOutString);
// Whether this is a preload, for contexts that support them.
virtual bool IsPreload() const { return false; }
// Casting to the different contexts
bool IsWindowContext() const { return mKind == ContextKind::Window; }
mozilla::dom::ScriptLoadContext* AsWindowContext();
bool IsSyncContext() const { return mKind == ContextKind::Sync; }
mozilla::loader::SyncLoadContext* AsSyncContext();
bool IsWorkerContext() const { return mKind == ContextKind::Worker; }
mozilla::dom::WorkerLoadContext* AsWorkerContext();
bool IsWorkletContext() const { return mKind == ContextKind::Worklet; }
mozilla::dom::WorkletLoadContext* AsWorkletContext();
RefPtr<JS::loader::ScriptLoadRequest> mRequest;
};
} // namespace JS::loader
#endif // js_loader_BaseLoadContext_h