When reading the spec’s section on liveness:
https://tc39.es/ecma262/multipage/executable-code-and-execution-contexts.html#sec-liveness
and
https://tc39.es/ecma262/multipage/executable-code-and-execution-contexts.html#sec-weakref-execution
There is a note that says:
If an implementation chooses a non-live set S in which to empty WeakRefs, it must empty WeakRefs for all objects in Ssimultaneously. In other words, an implementation must not empty a WeakRef pointing to an object obj without emptying out other WeakRefs that, if not emptied, could result in an execution that observes the Object value of obj.
Am I correct that this note is not purely clarifying, and instead is normative. Without this note the spec seems to allow the following:
let a = {};
let b = {};
a.b = b;
let ra = new WeakRef(a);
let rb = new WeakRef(b);
a = b = null;
await sleep(1);
// host considers the set of objects: [b] non-live and empties rb
assert(rb.deref() === undefined);
// but the set of objects: [a] has not been cleared so…
assert(ra.deref().b !== undefined);
Feel like I must be missing something?