tor-browser

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

commit 6a1bf0a168094a71f21f700472b00de770b18e0e
parent a278af2759c343173c898684d3a3c0d08c29c9bf
Author: Yoshi Cheng-Hao Huang <allstars.chh@gmail.com>
Date:   Fri, 19 Dec 2025 21:40:07 +0000

Bug 2006871 - Part 3: Pass ImportPhase to various module functions. r=jonco

Defer Import Evaluation:
- FinishLoadingImportedModule : https://tc39.es/proposal-defer-import-eval/#sec-FinishLoadingImportedModule
- ContinueDynamicImport: https://tc39.es/proposal-defer-import-eval/#sec-ContinueDynamicImport

Source Phase Import:
- FinishLoadingImportedModule: https://tc39.es/proposal-source-phase-imports/#sec-FinishLoadingImportedModule
- ContinueModuleLoading: https://tc39.es/proposal-source-phase-imports/#sec-ContinueModuleLoading
- InnerModuleLinking: https://tc39.es/proposal-source-phase-imports/#sec-InnerModuleLinking
- InnerModuleEvaluation: https://tc39.es/proposal-source-phase-imports/#sec-innermoduleevaluation

Differential Revision: https://phabricator.services.mozilla.com/D277003

Diffstat:
Mjs/src/vm/Modules.cpp | 56+++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 41 insertions(+), 15 deletions(-)

diff --git a/js/src/vm/Modules.cpp b/js/src/vm/Modules.cpp @@ -56,16 +56,15 @@ static bool SyntheticModuleEvaluate(JSContext* cx, Handle<ModuleObject*> module, static bool ContinueModuleLoading(JSContext* cx, Handle<GraphLoadingStateRecordObject*> state, Handle<ModuleObject*> moduleCompletion, - Handle<Value> error); + ImportPhase phase, Handle<Value> error); static bool TryStartDynamicModuleImport(JSContext* cx, HandleScript script, HandleValue specifierArg, HandleValue optionsArg, HandleObject promise); static bool ContinueDynamicImport(JSContext* cx, Handle<JSScript*> referrer, - Handle<JSObject*> moduleRequest, Handle<PromiseObject*> promiseCapability, Handle<ModuleObject*> module, - bool usePromise); + ImportPhase phase, bool usePromise); static bool LinkAndEvaluateDynamicImport(JSContext* cx, unsigned argc, Value* vp); static bool LinkAndEvaluateDynamicImport( @@ -109,6 +108,7 @@ JS_PUBLIC_API bool JS::FinishLoadingImportedModule( CHECK_THREAD(cx); cx->check(referrer, moduleRequest, payload, result); + MOZ_ASSERT(moduleRequest->is<ModuleRequestObject>()); MOZ_ASSERT(result); Rooted<ModuleObject*> module(cx, &result->as<ModuleObject>()); @@ -140,14 +140,17 @@ JS_PUBLIC_API bool JS::FinishLoadingImportedModule( if (object->is<GraphLoadingStateRecordObject>()) { Rooted<GraphLoadingStateRecordObject*> state(cx); state = &object->as<GraphLoadingStateRecordObject>(); - return ContinueModuleLoading(cx, state, module, UndefinedHandleValue); + return ContinueModuleLoading( + cx, state, module, moduleRequest->as<ModuleRequestObject>().phase(), + UndefinedHandleValue); } // Step 3. Else, // Step 3.a. Perform ContinueDynamicImport(payload, result). MOZ_ASSERT(object->is<PromiseObject>()); Rooted<PromiseObject*> promise(cx, &object->as<PromiseObject>()); - return ContinueDynamicImport(cx, referrer, moduleRequest, promise, module, + return ContinueDynamicImport(cx, referrer, promise, module, + moduleRequest->as<ModuleRequestObject>().phase(), usePromise); } @@ -166,7 +169,8 @@ JS_PUBLIC_API bool JS::FinishLoadingImportedModuleFailed( if (payload->is<GraphLoadingStateRecordObject>()) { Rooted<GraphLoadingStateRecordObject*> state(cx); state = &payload->as<GraphLoadingStateRecordObject>(); - return ContinueModuleLoading(cx, state, nullptr, error); + return ContinueModuleLoading(cx, state, nullptr, ImportPhase::Evaluation, + error); } // Step 3. Else, @@ -1437,7 +1441,8 @@ static bool FailWithUnsupportedAttributeException( return false; } - return ContinueModuleLoading(cx, state, nullptr, exnStack.exception()); + return ContinueModuleLoading(cx, state, nullptr, ImportPhase::Evaluation, + exnStack.exception()); } // https://tc39.es/ecma262/#sec-InnerModuleLoading @@ -1552,8 +1557,9 @@ static bool InnerModuleLoading(JSContext* cx, static bool ContinueModuleLoading(JSContext* cx, Handle<GraphLoadingStateRecordObject*> state, Handle<ModuleObject*> moduleCompletion, - Handle<Value> error) { + ImportPhase phase, Handle<Value> error) { MOZ_ASSERT_IF(moduleCompletion, error.isUndefined()); + MOZ_ASSERT(phase < ImportPhase::Limit); // Step 1. If state.[[IsLoading]] is false, return unused. if (!state->isLoading()) { @@ -1562,6 +1568,9 @@ static bool ContinueModuleLoading(JSContext* cx, // Step 2. If moduleCompletion is a normal completion, then if (moduleCompletion) { + // TODO: Bug 1943933: Implement Source Phase Imports + MOZ_ASSERT(phase == ImportPhase::Evaluation); + // Step 2.a. Perform InnerModuleLoading(state, moduleCompletion.[[Value]]). return InnerModuleLoading(cx, state, moduleCompletion); } @@ -1757,6 +1766,7 @@ static bool InnerModuleLinking(JSContext* cx, Handle<ModuleObject*> module, for (const RequestedModule& request : module->requestedModules()) { // Step 9.a. Let requiredModule be ? GetImportedModule(module, required). required = request.moduleRequest(); + MOZ_ASSERT(required->phase() == ImportPhase::Evaluation); requiredModule = GetImportedModule(cx, module, required); if (!requiredModule) { return false; @@ -2058,6 +2068,7 @@ static bool InnerModuleEvaluation(JSContext* cx, Handle<ModuleObject*> module, // Step 11.a. Let requiredModule be GetImportedModule(module, // required). required = request.moduleRequest(); + MOZ_ASSERT(required->phase() == ImportPhase::Evaluation); requiredModule = GetImportedModule(cx, module, required); if (!requiredModule) { return false; @@ -2667,7 +2678,8 @@ static bool TryStartDynamicModuleImport(JSContext* cx, HandleScript script, // Step 12. Let moduleRequest be a new ModuleRequest Record { [[Specifier]]: // specifierString, [[Attributes]]: attributes }. RootedObject moduleRequest( - cx, ModuleRequestObject::create(cx, specifierAtom, attributes)); + cx, ModuleRequestObject::create(cx, specifierAtom, attributes, + ImportPhase::Evaluation)); if (!moduleRequest) { return false; } @@ -2738,17 +2750,18 @@ bool js::OnModuleEvaluationFailure(JSContext* cx, // required. class DynamicImportContextObject : public NativeObject { public: - enum { ReferrerSlot = 0, PromiseSlot, ModuleSlot, SlotCount }; + enum { ReferrerSlot = 0, PromiseSlot, ModuleSlot, PhaseSlot, SlotCount }; static const JSClass class_; [[nodiscard]] static DynamicImportContextObject* create( JSContext* cx, Handle<JSScript*> referrer, Handle<PromiseObject*> promise, - Handle<ModuleObject*> module); + Handle<ModuleObject*> module, ImportPhase phase); JSScript* referrer() const; PromiseObject* promise() const; ModuleObject* module() const; + ImportPhase phase() const; static void finalize(JS::GCContext* gcx, JSObject* obj); }; @@ -2761,7 +2774,7 @@ const JSClass DynamicImportContextObject::class_ = { /* static */ DynamicImportContextObject* DynamicImportContextObject::create( JSContext* cx, Handle<JSScript*> referrer, Handle<PromiseObject*> promise, - Handle<ModuleObject*> module) { + Handle<ModuleObject*> module, ImportPhase phase) { Rooted<DynamicImportContextObject*> self( cx, NewObjectWithGivenProto<DynamicImportContextObject>(cx, nullptr)); if (!self) { @@ -2773,6 +2786,7 @@ DynamicImportContextObject* DynamicImportContextObject::create( } self->initReservedSlot(PromiseSlot, ObjectValue(*promise)); self->initReservedSlot(ModuleSlot, ObjectValue(*module)); + self->initReservedSlot(PhaseSlot, Int32Value(int32_t(phase))); return self; } @@ -2803,12 +2817,21 @@ ModuleObject* DynamicImportContextObject::module() const { return &value.toObject().as<ModuleObject>(); } +ImportPhase DynamicImportContextObject::phase() const { + Value value = getReservedSlot(PhaseSlot); + if (value.isUndefined()) { + return ImportPhase::Limit; + } + + return static_cast<ImportPhase>(value.toInt32()); +} + // https://tc39.es/ecma262/#sec-ContinueDynamicImport /* static */ bool ContinueDynamicImport(JSContext* cx, Handle<JSScript*> referrer, - Handle<JSObject*> moduleRequest, Handle<PromiseObject*> promiseCapability, - Handle<ModuleObject*> module, bool usePromise) { + Handle<ModuleObject*> module, ImportPhase phase, + bool usePromise) { MOZ_ASSERT(module); // Step 1, 2: Already handled in FinishLoadingImportedModuleFailed functions. @@ -2817,7 +2840,7 @@ bool ContinueDynamicImport(JSContext* cx, Handle<JSScript*> referrer, // parameters that captures module, promiseCapability, and onRejected... Rooted<DynamicImportContextObject*> context( cx, DynamicImportContextObject::create(cx, referrer, promiseCapability, - module)); + module, phase)); if (!context) { return RejectPromiseWithPendingError(cx, promiseCapability); } @@ -2878,6 +2901,9 @@ static bool LinkAndEvaluateDynamicImport( } MOZ_ASSERT(!JS_IsExceptionPending(cx)); + // TODO: Bug 1952263: Implement Defer Imports Evaluation. + MOZ_ASSERT(context->phase() == ImportPhase::Evaluation); + // Step 6.c. Let evaluatePromise be module.Evaluate(). JS::Rooted<JS::Value> rval(cx); mozilla::DebugOnly<bool> ok = JS::ModuleEvaluate(cx, module, &rval);