tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ModuleLoader.cpp (19675B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "ModuleLoader.h"
      8 
      9 #include "GeckoProfiler.h"
     10 #include "ScriptLoader.h"
     11 #include "js/CompileOptions.h"  // JS::CompileOptions, JS::InstantiateOptions
     12 #include "js/ContextOptions.h"  // JS::ContextOptionsRef
     13 #include "js/MemoryFunctions.h"
     14 #include "js/Modules.h"  // JS::FinishDynamicModuleImport, JS::{G,S}etModuleResolveHook, JS::Get{ModulePrivate,ModuleScript,RequestedModule{s,Specifier,SourcePos}}, JS::SetModule{DynamicImport,Metadata}Hook
     15 #include "js/PropertyAndElement.h"  // JS_DefineProperty
     16 #include "js/Realm.h"
     17 #include "js/SourceText.h"
     18 #include "js/experimental/JSStencil.h"  // JS::Stencil, JS::CompileModuleScriptToStencil, JS::InstantiateModuleStencil
     19 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
     20 #include "js/loader/LoadedScript.h"
     21 #include "js/loader/ModuleLoadRequest.h"
     22 #include "js/loader/ModuleLoaderBase.h"
     23 #include "js/loader/ScriptLoadRequest.h"
     24 #include "jsapi.h"
     25 #include "mozilla/Assertions.h"
     26 #include "mozilla/CycleCollectedJSContext.h"
     27 #include "mozilla/LoadInfo.h"
     28 #include "mozilla/Maybe.h"
     29 #include "mozilla/StyleSheet.h"
     30 #include "mozilla/StyleSheetInlines.h"
     31 #include "mozilla/dom/AutoEntryScript.h"
     32 #include "mozilla/dom/Document.h"
     33 #include "mozilla/dom/Element.h"
     34 #include "mozilla/dom/RequestBinding.h"
     35 #include "nsContentSecurityManager.h"
     36 #include "nsError.h"
     37 #include "nsIContent.h"
     38 #include "nsIPrincipal.h"
     39 #include "nsJSUtils.h"
     40 #include "xpcpublic.h"
     41 
     42 using JS::SourceText;
     43 using namespace JS::loader;
     44 
     45 namespace mozilla::dom {
     46 
     47 #undef LOG
     48 #define LOG(args) \
     49  MOZ_LOG(ScriptLoader::gScriptLoaderLog, mozilla::LogLevel::Debug, args)
     50 
     51 #define LOG_ENABLED() \
     52  MOZ_LOG_TEST(ScriptLoader::gScriptLoaderLog, mozilla::LogLevel::Debug)
     53 
     54 //////////////////////////////////////////////////////////////
     55 // DOM module loader
     56 //////////////////////////////////////////////////////////////
     57 
     58 ModuleLoader::ModuleLoader(ScriptLoader* aLoader,
     59                           nsIGlobalObject* aGlobalObject, Kind aKind)
     60    : ModuleLoaderBase(aLoader, aGlobalObject), mKind(aKind) {}
     61 
     62 ScriptLoader* ModuleLoader::GetScriptLoader() {
     63  return static_cast<ScriptLoader*>(mLoader.get());
     64 }
     65 
     66 bool ModuleLoader::CanStartLoad(ModuleLoadRequest* aRequest, nsresult* aRvOut) {
     67  if (!GetScriptLoader()->GetDocument()) {
     68    *aRvOut = NS_ERROR_NULL_POINTER;
     69    return false;
     70  }
     71 
     72  nsCOMPtr<nsIPrincipal> principal = aRequest->TriggeringPrincipal();
     73  if (BasePrincipal::Cast(principal)->ContentScriptAddonPolicy()) {
     74    // To prevent dynamic code execution, content scripts can only
     75    // load moz-extension URLs.
     76    if (!aRequest->URI()->SchemeIs("moz-extension")) {
     77      *aRvOut = NS_ERROR_DOM_WEBEXT_CONTENT_SCRIPT_URI;
     78      return false;
     79    }
     80  } else {
     81    // If this document is sandboxed without 'allow-scripts', abort.
     82    if (GetScriptLoader()->GetDocument()->HasScriptsBlockedBySandbox()) {
     83      *aRvOut = NS_ERROR_CONTENT_BLOCKED;
     84      return false;
     85    }
     86  }
     87 
     88  if (LOG_ENABLED()) {
     89    nsAutoCString url;
     90    aRequest->URI()->GetAsciiSpec(url);
     91    LOG(("ScriptLoadRequest (%p): Start Module Load (url = %s)", aRequest,
     92         url.get()));
     93  }
     94 
     95  return true;
     96 }
     97 
     98 nsresult ModuleLoader::StartFetch(ModuleLoadRequest* aRequest) {
     99  if (aRequest->IsCachedStencil()) {
    100    GetScriptLoader()->EmulateNetworkEvents(aRequest);
    101    SetModuleFetchStarted(aRequest);
    102    return aRequest->OnFetchComplete(NS_OK);
    103  }
    104 
    105  // According to the spec, module scripts have different behaviour to classic
    106  // scripts and always use CORS. Only exception: Non linkable about: pages
    107  // which load local module scripts.
    108  bool isAboutPageLoadingChromeURI = ScriptLoader::IsAboutPageLoadingChromeURI(
    109      aRequest, GetScriptLoader()->GetDocument());
    110 
    111  nsContentSecurityManager::CORSSecurityMapping corsMapping =
    112      isAboutPageLoadingChromeURI
    113          ? nsContentSecurityManager::CORSSecurityMapping::DISABLE_CORS_CHECKS
    114          : nsContentSecurityManager::CORSSecurityMapping::REQUIRE_CORS_CHECKS;
    115 
    116  nsSecurityFlags securityFlags =
    117      nsContentSecurityManager::ComputeSecurityFlags(aRequest->CORSMode(),
    118                                                     corsMapping);
    119 
    120  securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
    121 
    122  // Delegate Shared Behavior to base ScriptLoader
    123  //
    124  // aCharsetForPreload is passed as Nothing() because this is not a preload
    125  // and `StartLoadInternal` is able to find the charset by using `aRequest`
    126  // for this case.
    127  nsresult rv = GetScriptLoader()->StartLoadInternal(
    128      aRequest, securityFlags, Nothing() /* aCharsetForPreload */);
    129  NS_ENSURE_SUCCESS(rv, rv);
    130 
    131  // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-an-import()-module-script-graph
    132  // Step 1. Disallow further import maps given settings object.
    133  if (!aRequest->GetScriptLoadContext()->IsPreload()) {
    134    LOG(("ScriptLoadRequest (%p): Disallow further import maps.", aRequest));
    135    DisallowImportMaps();
    136  }
    137 
    138  LOG(("ScriptLoadRequest (%p): Start fetching module", aRequest));
    139 
    140  return NS_OK;
    141 }
    142 
    143 void ModuleLoader::AsyncExecuteInlineModule(ModuleLoadRequest* aRequest) {
    144  MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(
    145      mozilla::NewRunnableMethod<RefPtr<ModuleLoadRequest>>(
    146          "ModuleLoader::ExecuteInlineModule", this,
    147          &ModuleLoader::ExecuteInlineModule, aRequest)));
    148 }
    149 
    150 void ModuleLoader::ExecuteInlineModule(ModuleLoadRequest* aRequest) {
    151  MOZ_ASSERT(aRequest->IsFinished());
    152  MOZ_ASSERT(aRequest->IsTopLevel());
    153  MOZ_ASSERT(aRequest->GetScriptLoadContext()->mIsInline);
    154 
    155  if (aRequest->GetScriptLoadContext()->GetParserCreated() == NOT_FROM_PARSER) {
    156    GetScriptLoader()->RunScriptWhenSafe(aRequest);
    157  } else {
    158    GetScriptLoader()->MaybeMoveToLoadedList(aRequest);
    159    GetScriptLoader()->ProcessPendingRequests();
    160  }
    161 
    162  aRequest->GetScriptLoadContext()->MaybeUnblockOnload();
    163 }
    164 
    165 void ModuleLoader::OnModuleLoadComplete(ModuleLoadRequest* aRequest) {
    166  MOZ_ASSERT(aRequest->IsFinished());
    167 
    168  if (aRequest->IsTopLevel() || aRequest->IsDynamicImport()) {
    169    if (aRequest->GetScriptLoadContext()->mIsInline &&
    170        aRequest->GetScriptLoadContext()->GetParserCreated() ==
    171            NOT_FROM_PARSER) {
    172      // https://html.spec.whatwg.org/#prepare-the-script-element
    173      // Step 32.2.
    174      //    type: "module":
    175      //    3.1. Queue an element task on the networking task source given
    176      //         el to perform the following steps:
    177      //        1. Mark as ready el given result.
    178      //
    179      // Step 33. If ... el's type is "module":
    180      //    ...
    181      //    3. Otherwise, if el is not parser-inserted:
    182      //      3. Set el's steps to run when the result is ready to the
    183      //         following:
    184      //        ...
    185      //        2.1. Execute the script element scripts[0].
    186      AsyncExecuteInlineModule(aRequest);
    187      return;
    188    } else if (aRequest->GetScriptLoadContext()->mIsInline &&
    189               aRequest->GetScriptLoadContext()->GetParserCreated() !=
    190                   NOT_FROM_PARSER &&
    191               !nsContentUtils::IsSafeToRunScript()) {
    192      // Avoid giving inline async module scripts that don't have
    193      // external dependencies a guaranteed execution time relative
    194      // to the HTML parse. That is, deliberately avoid guaranteeing
    195      // that the script would always observe a DOM shape where the
    196      // parser has not added further elements to the DOM.
    197      // (If `nsContentUtils::IsSafeToRunScript()` returns `true`,
    198      // we come here synchronously from the parser. If it returns
    199      // `false` we come here from an external dependency completing
    200      // its fetch, in which case we already are at an unspecific
    201      // point relative to the parse.)
    202      AsyncExecuteInlineModule(aRequest);
    203      return;
    204    } else {
    205      GetScriptLoader()->MaybeMoveToLoadedList(aRequest);
    206      GetScriptLoader()->ProcessPendingRequestsAsync();
    207    }
    208  }
    209 
    210  aRequest->GetScriptLoadContext()->MaybeUnblockOnload();
    211 }
    212 
    213 nsresult ModuleLoader::CompileFetchedModule(
    214    JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::CompileOptions& aOptions,
    215    ModuleLoadRequest* aRequest, JS::MutableHandle<JSObject*> aModuleOut) {
    216  if (!nsJSUtils::IsScriptable(aGlobal)) {
    217    return NS_ERROR_FAILURE;
    218  }
    219 
    220  switch (aRequest->mModuleType) {
    221    case JS::ModuleType::Unknown:
    222      MOZ_CRASH("Unexpected module type");
    223    case JS::ModuleType::JavaScriptOrWasm:
    224      return CompileJavaScriptOrWasmModule(aCx, aOptions, aRequest, aModuleOut);
    225    case JS::ModuleType::JSON:
    226      return CompileJsonModule(aCx, aOptions, aRequest, aModuleOut);
    227    case JS::ModuleType::CSS:
    228      return CompileCssModule(aCx, aOptions, aRequest, aModuleOut);
    229    case JS::ModuleType::Bytes:
    230      MOZ_CRASH("Unexpected module type");
    231  }
    232 
    233  MOZ_CRASH("Unhandled module type");
    234 }
    235 
    236 nsresult ModuleLoader::CompileJavaScriptOrWasmModule(
    237    JSContext* aCx, JS::CompileOptions& aOptions, ModuleLoadRequest* aRequest,
    238    JS::MutableHandle<JSObject*> aModuleOut) {
    239  GetScriptLoader()->CalculateCacheFlag(aRequest);
    240 
    241 #ifdef NIGHTLY_BUILD
    242  if (aRequest->HasWasmMimeTypeEssence()) {
    243    MOZ_ASSERT(aRequest->IsTextSource());
    244 
    245    ModuleLoader::MaybeSourceText maybeSource;
    246    nsresult rv = aRequest->GetScriptSource(aCx, &maybeSource,
    247                                            aRequest->mLoadContext.get());
    248    NS_ENSURE_SUCCESS(rv, rv);
    249 
    250    auto compile = [&](auto& source) {
    251      return JS::CompileWasmModule(aCx, aOptions, source);
    252    };
    253 
    254    auto* wasmModule = maybeSource.mapNonEmpty(compile);
    255    if (!wasmModule) {
    256      return NS_ERROR_FAILURE;
    257    }
    258 
    259    aModuleOut.set(wasmModule);
    260    return NS_OK;
    261  }
    262 #endif
    263 
    264  if (aRequest->IsCachedStencil()) {
    265    JS::InstantiateOptions instantiateOptions(aOptions);
    266    RefPtr<JS::Stencil> stencil = aRequest->GetStencil();
    267    aModuleOut.set(
    268        JS::InstantiateModuleStencil(aCx, instantiateOptions, stencil));
    269    if (!aModuleOut) {
    270      return NS_ERROR_FAILURE;
    271    }
    272 
    273    bool alreadyStarted;
    274    if (!JS::StartCollectingDelazifications(aCx, aModuleOut, stencil,
    275                                            alreadyStarted)) {
    276      return NS_ERROR_FAILURE;
    277    }
    278    (void)alreadyStarted;
    279 
    280    return NS_OK;
    281  }
    282 
    283  if (aRequest->GetScriptLoadContext()->mWasCompiledOMT) {
    284    JS::InstantiationStorage storage;
    285    RefPtr<JS::Stencil> stencil =
    286        aRequest->GetScriptLoadContext()->StealOffThreadResult(aCx, &storage);
    287    if (!stencil) {
    288      return NS_ERROR_FAILURE;
    289    }
    290 
    291    aRequest->SetStencil(stencil);
    292 
    293    JS::InstantiateOptions instantiateOptions(aOptions);
    294    aModuleOut.set(JS::InstantiateModuleStencil(aCx, instantiateOptions,
    295                                                stencil, &storage));
    296    if (!aModuleOut) {
    297      return NS_ERROR_FAILURE;
    298    }
    299 
    300    if (aRequest->PassedConditionForEitherCache()) {
    301      bool alreadyStarted;
    302      if (!JS::StartCollectingDelazifications(aCx, aModuleOut, stencil,
    303                                              alreadyStarted)) {
    304        return NS_ERROR_FAILURE;
    305      }
    306      MOZ_ASSERT(!alreadyStarted);
    307    }
    308 
    309    GetScriptLoader()->TryCacheRequest(aRequest);
    310 
    311    return NS_OK;
    312  }
    313 
    314  RefPtr<JS::Stencil> stencil;
    315  if (aRequest->IsTextSource()) {
    316    MaybeSourceText maybeSource;
    317    nsresult rv = aRequest->GetScriptSource(aCx, &maybeSource,
    318                                            aRequest->mLoadContext.get());
    319    NS_ENSURE_SUCCESS(rv, rv);
    320 
    321    auto compile = [&](auto& source) {
    322      return JS::CompileModuleScriptToStencil(aCx, aOptions, source);
    323    };
    324    stencil = maybeSource.mapNonEmpty(compile);
    325  } else {
    326    MOZ_ASSERT(aRequest->IsSerializedStencil());
    327    JS::DecodeOptions decodeOptions(aOptions);
    328    decodeOptions.borrowBuffer = true;
    329 
    330    JS::TranscodeRange range = aRequest->SerializedStencil();
    331    JS::TranscodeResult tr =
    332        JS::DecodeStencil(aCx, decodeOptions, range, getter_AddRefs(stencil));
    333    if (tr != JS::TranscodeResult::Ok) {
    334      return NS_ERROR_DOM_JS_DECODING_ERROR;
    335    }
    336  }
    337 
    338  if (!stencil) {
    339    return NS_ERROR_FAILURE;
    340  }
    341 
    342  aRequest->SetStencil(stencil);
    343 
    344  JS::InstantiateOptions instantiateOptions(aOptions);
    345  aModuleOut.set(
    346      JS::InstantiateModuleStencil(aCx, instantiateOptions, stencil));
    347  if (!aModuleOut) {
    348    return NS_ERROR_FAILURE;
    349  }
    350 
    351  if (aRequest->PassedConditionForEitherCache()) {
    352    bool alreadyStarted;
    353    if (!JS::StartCollectingDelazifications(aCx, aModuleOut, stencil,
    354                                            alreadyStarted)) {
    355      return NS_ERROR_FAILURE;
    356    }
    357    MOZ_ASSERT(!alreadyStarted);
    358  }
    359 
    360  GetScriptLoader()->TryCacheRequest(aRequest);
    361 
    362  return NS_OK;
    363 }
    364 
    365 nsresult ModuleLoader::CompileJsonModule(
    366    JSContext* aCx, JS::CompileOptions& aOptions, ModuleLoadRequest* aRequest,
    367    JS::MutableHandle<JSObject*> aModuleOut) {
    368  MOZ_ASSERT(!aRequest->GetScriptLoadContext()->mWasCompiledOMT);
    369 
    370  MOZ_ASSERT(aRequest->IsTextSource());
    371  ModuleLoader::MaybeSourceText maybeSource;
    372  nsresult rv = aRequest->GetScriptSource(aCx, &maybeSource,
    373                                          aRequest->mLoadContext.get());
    374  NS_ENSURE_SUCCESS(rv, rv);
    375 
    376  auto compile = [&](auto& source) {
    377    return JS::CompileJsonModule(aCx, aOptions, source);
    378  };
    379 
    380  auto* jsonModule = maybeSource.mapNonEmpty(compile);
    381  if (!jsonModule) {
    382    return NS_ERROR_FAILURE;
    383  }
    384 
    385  aModuleOut.set(jsonModule);
    386  return NS_OK;
    387 }
    388 
    389 nsresult ModuleLoader::CompileCssModule(
    390    JSContext* aCx, JS::CompileOptions& aOptions, ModuleLoadRequest* aRequest,
    391    JS::MutableHandle<JSObject*> aModuleOut) {
    392  MOZ_ASSERT(!aRequest->GetScriptLoadContext()->mWasCompiledOMT);
    393  MOZ_ASSERT(mozilla::StaticPrefs::layout_css_module_scripts_enabled());
    394 
    395  MOZ_ASSERT(aRequest->IsTextSource());
    396  ModuleLoader::MaybeSourceText maybeSource;
    397  nsresult rv = aRequest->GetScriptSource(aCx, &maybeSource,
    398                                          aRequest->mLoadContext.get());
    399  NS_ENSURE_SUCCESS(rv, rv);
    400 
    401  // https://html.spec.whatwg.org/#creating-a-css-module-script
    402  JS::Rooted<JSObject*> cssModule(aCx, nullptr);
    403  ErrorResult error;
    404  auto compile = [&](auto& source) {
    405    using T = decltype(source);
    406    static_assert(std::is_same_v<T, JS::SourceText<char16_t>&> ||
    407                  std::is_same_v<T, JS::SourceText<Utf8Unit>&>);
    408 
    409    nsCOMPtr<nsPIDOMWindowInner> window =
    410        do_QueryInterface(aRequest->GetGlobalObject());
    411    if (!window) {
    412      error.ThrowNotSupportedError("Not supported when there is no document");
    413      return;
    414    }
    415 
    416    Document* constructorDocument = window->GetExtantDoc();
    417    if (!constructorDocument) {
    418      error.ThrowNotSupportedError("Not supported when there is no document");
    419      return;
    420    }
    421 
    422    // 5. Let sheet be the result of running the steps to create a constructed
    423    // CSSStyleSheet
    424    //    with an empty dictionary as the argument.
    425    // Note that according to the specification, the baseURL should be the
    426    // baseURL of the document, but that doesn't seem correct (see
    427    // https://github.com/whatwg/html/issues/11629).
    428    dom::CSSStyleSheetInit options;
    429    RefPtr<StyleSheet> sheet = StyleSheet::CreateConstructedSheet(
    430        *constructorDocument, aRequest->BaseURL(), options, error);
    431    if (error.Failed()) {
    432      return;
    433    }
    434 
    435    // 6. Run the steps to synchronously replace the rules of a CSSStyleSheet on
    436    // sheet given source. Ideally we wouldn't run this on the main thread for
    437    // large scripts, see https://bugzilla.mozilla.org/show_bug.cgi?id=1987143.
    438    if constexpr (std::is_same_v<T, JS::SourceText<mozilla::Utf8Unit>&>) {
    439      nsDependentCSubstring text(source.get(), source.length());
    440      sheet->ReplaceSync(text, error);
    441    } else if constexpr (std::is_same_v<T, JS::SourceText<char16_t>&>) {
    442      nsDependentSubstring text(source.get(), source.length());
    443      sheet->ReplaceSync(NS_ConvertUTF16toUTF8(text), error);
    444    }
    445    if (error.Failed()) {
    446      return;
    447    }
    448 
    449    JS::Rooted<JS::Value> val(aCx, JS::NullValue());
    450    if (!GetOrCreateDOMReflector(aCx, sheet, &val) || !val.isObject()) {
    451      if (!JS_IsExceptionPending(aCx)) {
    452        error.ThrowUnknownError("Internal error");
    453      }
    454      return;
    455    }
    456 
    457    // Steps. 1 - 4 (re-ordered), 7, 8
    458    cssModule.set(JS::CreateDefaultExportSyntheticModule(aCx, val));
    459  };
    460 
    461  maybeSource.mapNonEmpty(compile);
    462  if (!cssModule) {
    463    if (error.Failed()) {
    464      MOZ_ALWAYS_TRUE(error.MaybeSetPendingException(aCx));
    465    }
    466    return NS_ERROR_FAILURE;
    467  }
    468 
    469  aModuleOut.set(cssModule);
    470  return NS_OK;
    471 }
    472 
    473 already_AddRefed<ModuleLoadRequest> ModuleLoader::CreateTopLevel(
    474    nsIURI* aURI, nsIScriptElement* aElement, ReferrerPolicy aReferrerPolicy,
    475    ScriptFetchOptions* aFetchOptions, const SRIMetadata& aIntegrity,
    476    nsIURI* aReferrer, ScriptLoadContext* aContext,
    477    ScriptLoadRequestType aRequestType) {
    478  RefPtr<ModuleLoadRequest> request = new ModuleLoadRequest(
    479      JS::ModuleType::JavaScript, aIntegrity, aReferrer, aContext,
    480      ModuleLoadRequest::Kind::TopLevel, this, nullptr);
    481 
    482  GetScriptLoader()->TryUseCache(aReferrerPolicy, aFetchOptions, aURI, request,
    483                                 aElement, aFetchOptions->mNonce, aRequestType);
    484 
    485  return request.forget();
    486 }
    487 
    488 already_AddRefed<ModuleLoadRequest> ModuleLoader::CreateRequest(
    489    JSContext* aCx, nsIURI* aURI, JS::Handle<JSObject*> aModuleRequest,
    490    JS::Handle<JS::Value> aHostDefined, JS::Handle<JS::Value> aPayload,
    491    bool aIsDynamicImport, ScriptFetchOptions* aOptions,
    492    ReferrerPolicy aReferrerPolicy, nsIURI* aBaseURL,
    493    const SRIMetadata& aSriMetadata) {
    494  RefPtr<ScriptLoadContext> context = new ScriptLoadContext();
    495  context->mIsInline = false;
    496  ModuleLoadRequest::Kind kind;
    497  ModuleLoadRequest* root = nullptr;
    498  if (aIsDynamicImport) {
    499    context->mScriptMode = ScriptLoadContext::ScriptMode::eAsync;
    500    kind = ModuleLoadRequest::Kind::DynamicImport;
    501  } else {
    502    MOZ_ASSERT(!aHostDefined.isUndefined());
    503    root = static_cast<ModuleLoadRequest*>(aHostDefined.toPrivate());
    504    MOZ_ASSERT(root);
    505    LoadContextBase* loadContext = root->mLoadContext;
    506    context->mScriptMode = loadContext->AsWindowContext()->mScriptMode;
    507    kind = ModuleLoadRequest::Kind::StaticImport;
    508  }
    509 
    510  JS::ModuleType moduleType = GetModuleRequestType(aCx, aModuleRequest);
    511  RefPtr<ModuleLoadRequest> request = new ModuleLoadRequest(
    512      moduleType, aSriMetadata, aBaseURL, context, kind, this, root);
    513 
    514  GetScriptLoader()->TryUseCache(aReferrerPolicy, aOptions, aURI, request);
    515 
    516  return request.forget();
    517 }
    518 
    519 already_AddRefed<ScriptFetchOptions>
    520 ModuleLoader::CreateDefaultScriptFetchOptions() {
    521  RefPtr<ScriptFetchOptions> options = ScriptFetchOptions::CreateDefault();
    522  nsCOMPtr<nsIPrincipal> principal = GetGlobalObject()->PrincipalOrNull();
    523  options->SetTriggeringPrincipal(principal);
    524  return options.forget();
    525 }
    526 
    527 nsIURI* ModuleLoader::GetClientReferrerURI() {
    528  Document* document = GetScriptLoader()->GetDocument();
    529 #ifdef DEBUG
    530  nsCOMPtr<nsIPrincipal> principal = GetGlobalObject()->PrincipalOrNull();
    531 #endif  // DEBUG
    532  MOZ_ASSERT_IF(GetKind() == WebExtension,
    533                BasePrincipal::Cast(principal)->ContentScriptAddonPolicy());
    534  MOZ_ASSERT_IF(GetKind() == Normal, principal == document->NodePrincipal());
    535 
    536  return document->GetDocBaseURI();
    537 }
    538 
    539 ModuleLoader::~ModuleLoader() {
    540  LOG(("ModuleLoader::~ModuleLoader %p", this));
    541  mLoader = nullptr;
    542 }
    543 
    544 #undef LOG
    545 #undef LOG_ENABLED
    546 
    547 }  // namespace mozilla::dom