From 201e52a10a392c49be5a8423a7b1d8149bd8207e Mon Sep 17 00:00:00 2001 From: Andreu Botella Date: Wed, 11 Feb 2026 13:18:20 +0100 Subject: [PATCH] Don't require hosts to handle the `FinalizationRegistry` context We currently require the `HostEnqueueFinalizationRegistryCleanupJob` host hook to set the `FinalizationRegistry`'s AsyncContext mapping in order for the FR callback to be called in the right context. However, the only reason we are doing this, rather than swapping the context in `CleanupFinalizationRegistry`, is because if we do that, hosts might not have any context information to report for any exceptions thrown from userland JS. However, given that we seem to be moving away from making hosts propagate the error context to error events and into storing the context whenever an `Error` instance is created (see #145 and #148), there's no longer any reason to make hosts handle the FR context. So this patch instead changes `CleanupFinalizationRegistry` to handle it. --- spec.html | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/spec.html b/spec.html index 50d5cfa..3659ee5 100644 --- a/spec.html +++ b/spec.html @@ -133,31 +133,30 @@

Agents

- -

Processing Model of WeakRef and FinalizationRegistry Targets

- - -

Host Hooks

- - -

- HostEnqueueFinalizationRegistryCleanupJob ( - _finalizationRegistry_: a FinalizationRegistry, - ): ~unused~ -

-
-
-

Let _cleanupJob_ be a new Job Abstract Closure with no parameters that captures _finalizationRegistry_ and performs the following steps when called:

- - 1. Let _previousContextMapping_ be AsyncContextSwap(_finalizationRegistry_.[[FinalizationRegistryAsyncContextMapping]]). - 1. Let _cleanupResult_ be Completion(CleanupFinalizationRegistry(_finalizationRegistry_)). - 1. If _cleanupResult_ is an abrupt completion, perform any host-defined steps for reporting the error. + +

+ CleanupFinalizationRegistry ( + _finalizationRegistry_: a FinalizationRegistry, + ): either a normal completion containing ~unused~ or a throw completion +

+
+
+ + 1. Assert: _finalizationRegistry_ has [[Cells]] and [[CleanupCallback]] internal slots. + 1. Assert: _finalizationRegistry_ has [[Cells]], [[CleanupCallback]], and [[FinalizationRegistryAsyncContextMapping]] internal slots. + 1. Let _callback_ be _finalizationRegistry_.[[CleanupCallback]]. + 1. Let _previousContextMapping_ be AsyncContextSwap(_finalizationRegistry_.[[FinalizationRegistryAsyncContextMapping]]). + 1. While _finalizationRegistry_.[[Cells]] contains a Record _cell_ such that _cell_.[[WeakRefTarget]] is ~empty~, an implementation may perform the following steps: + 1. Choose any such _cell_. + 1. Remove _cell_ from _finalizationRegistry_.[[Cells]]. + 1. Perform ? HostCallJobCallback(_callback_, *undefined*, « _cell_.[[HeldValue]] »). + 1. Let _result_ be Completion(HostCallJobCallback(_callback_, *undefined*, « _cell_.[[HeldValue]] »)). + 1. If _result_ is a throw completion, then 1. Perform AsyncContextSwap(_previousContextMapping_). - 1. Return ~unused~. - -

An implementation of HostEnqueueFinalizationRegistryCleanupJob schedules _cleanupJob_ to be performed at some future time, if possible. It must also conform to the requirements in .

-
-
+ 1. Return ? _result_. + 1. Perform AsyncContextSwap(_previousContextMapping_). + 1. Return ~unused~. +