AbortSignal.any(signals) returns a signal that is already aborted with a garbage reason (5e-324), even when all inputs are fresh. The 'abort' event never fires when a source signal is later aborted. Non-AbortSignal entries are also accepted silently instead of throwing TypeError.
Reproduced on starlingmonkey-v0.3.0 (starling.wasm) under wasmtime 45.0.0.
Reproduction
Save as test.js:
const c1 = new AbortController();
const c2 = new AbortController();
const combined = AbortSignal.any([c1.signal, c2.signal]);
console.log(combined.aborted); // actual: true (expected: false)
console.log(combined.reason); // actual: 5e-324 (expected: undefined)
combined.addEventListener("abort", () => console.log("fired"));
c2.abort("boom");
console.log(combined.reason); // actual: 5e-324 (expected: "boom"); "fired" never logs
AbortSignal.any([{}]); // actual: returns aborted signal (expected: TypeError)
then run wasmtime -S http --dir . starling.wasm test.js.
AbortController, AbortSignal.abort(), and AbortSignal.timeout() all work, so it seems the bug is isolated to .any().
Likely cause
In builtins/web/abort/abort-signal.cpp, create_with_signals iterates the call's args directly instead of unpacking the sequence<AbortSignal> required by the spec. The Array argument is treated as one AbortSignal, is_aborted reads Slots::Reason off the Array's reserved slots, finds non-undefined garbage, and short-circuits as if a source signal were already aborted. Calling with varargs (AbortSignal.any(s1, s2)) bypasses the unpacking step and works correctly.
Environment
- StarlingMonkey:
starlingmonkey-v0.3.0
- Host:
wasmtime 45.0.0
- Platform: macOS arm64
AbortSignal.any(signals)returns a signal that is already aborted with a garbagereason(5e-324), even when all inputs are fresh. The'abort'event never fires when a source signal is later aborted. Non-AbortSignalentries are also accepted silently instead of throwingTypeError.Reproduced on
starlingmonkey-v0.3.0(starling.wasm) underwasmtime 45.0.0.Reproduction
Save as
test.js:then run
wasmtime -S http --dir . starling.wasm test.js.AbortController,AbortSignal.abort(), andAbortSignal.timeout()all work, so it seems the bug is isolated to.any().Likely cause
In
builtins/web/abort/abort-signal.cpp,create_with_signalsiterates the call'sargsdirectly instead of unpacking thesequence<AbortSignal>required by the spec. The Array argument is treated as oneAbortSignal,is_abortedreadsSlots::Reasonoff the Array's reserved slots, finds non-undefined garbage, and short-circuits as if a source signal were already aborted. Calling with varargs (AbortSignal.any(s1, s2)) bypasses the unpacking step and works correctly.Environment
starlingmonkey-v0.3.0wasmtime 45.0.0