Severity: high — missing spec-mandated trap; docs claim it implemented.
canonResourceDrop (cabi/handles.ts:167-171) calls the raw dtor core
export directly (in-code comment: "Reference: dtor invoked through
store.lift/store.lower so that may_enter gating applies... Deferred;
direct call."). The reference routes the dtor through the store lift path
(definitions.py:2326-2333 -> :579-584): trap_if(not inst.may_enter_from(caller)) with the same-instance exemption, may_enter
cleared during the call, and a dtor trap poisons the impl instance (no
leave on trap).
Guest-observable divergence: a guest can drop an own handle whose dtor
re-enters a currently-entered sibling instance — the reference traps
"cannot enter component instance"; deltic silently runs the dtor. A
trapping dtor also fails to poison the implementing instance (and must
trigger the #66 retireInstanceAsyncEnds walk via the existing poison
seam).
Second half: docs/architecture.md §7 says "JS-initiated drops (using,
FinalizationRegistry) enter via a promising trampoline" — but
dropWrapper (embedder/resources.ts:92-103) and the FinalizationRegistry
callback (:54-63) call s.rt.dtor directly. A dtor that legally calls a
Suspending host import (explicitly permitted by §7) dies with
SuspendError on these paths.
Fix shape:
- implement the gate: same-instance exemption per the reference text;
enter/leave bracket so a dtor trap poisons the impl instance;
- JS-initiated drops: enter through a promising-wrapped path when the mode
supports it; keep drop(): void non-blocking (track the in-flight
promise via pendingHostCalls, surface async dtor failure through the
host-failure channel + instance poisoning).
Explicitly OUT of scope here (document instead): the §5 "guest-initiated
cross-component dtor calls route through generated wasm" claim. Today the
dtor call is a JS frame inside the drop trampoline, so a guest-initiated
drop whose dtor suspends traps under the JSPI frame rule (deterministic,
loud). A pure-wasm dispatch path is real machinery; docs §5/§7 get a
known-limitation note until it exists.
Found in the 2026-08-10 adversarial conformance review (runtime + translator vs component-model @ 73b7ad5 definitions.py; wasmtime-environ 47.0.3 treated as trusted).
Severity: high — missing spec-mandated trap; docs claim it implemented.
canonResourceDrop(cabi/handles.ts:167-171) calls the raw dtor coreexport directly (in-code comment: "Reference: dtor invoked through
store.lift/store.lower so that may_enter gating applies... Deferred;
direct call."). The reference routes the dtor through the store lift path
(definitions.py:2326-2333 -> :579-584):
trap_if(not inst.may_enter_from(caller))with the same-instance exemption, may_entercleared during the call, and a dtor trap poisons the impl instance (no
leave on trap).
Guest-observable divergence: a guest can drop an own handle whose dtor
re-enters a currently-entered sibling instance — the reference traps
"cannot enter component instance"; deltic silently runs the dtor. A
trapping dtor also fails to poison the implementing instance (and must
trigger the #66
retireInstanceAsyncEndswalk via the existing poisonseam).
Second half: docs/architecture.md §7 says "JS-initiated drops (
using,FinalizationRegistry) enter via a
promisingtrampoline" — butdropWrapper(embedder/resources.ts:92-103) and the FinalizationRegistrycallback (:54-63) call
s.rt.dtordirectly. A dtor that legally calls aSuspendinghost import (explicitly permitted by §7) dies withSuspendErroron these paths.Fix shape:
enter/leave bracket so a dtor trap poisons the impl instance;
supports it; keep
drop(): voidnon-blocking (track the in-flightpromise via
pendingHostCalls, surface async dtor failure through thehost-failure channel + instance poisoning).
Explicitly OUT of scope here (document instead): the §5 "guest-initiated
cross-component dtor calls route through generated wasm" claim. Today the
dtor call is a JS frame inside the drop trampoline, so a guest-initiated
drop whose dtor suspends traps under the JSPI frame rule (deterministic,
loud). A pure-wasm dispatch path is real machinery; docs §5/§7 get a
known-limitation note until it exists.
Found in the 2026-08-10 adversarial conformance review (runtime + translator vs component-model @ 73b7ad5 definitions.py; wasmtime-environ 47.0.3 treated as trusted).