Skip to content

pin-advance migration map: CM#705 removes the may_enter flag/trap #173

Description

@lannbot

Upstream is removing the non-reentrancy restriction: WebAssembly/component-model#705 ("CABI: remove the may_enter flag/trap", open as of 2026-08-20) deletes the may_enter flag+trap from the canon lift, resource.drop (destructor), and subtask.cancel paths and from cooperative scheduling conditions, making previously-trapping reentrance valid (new WAST coverage: reentrance.wast, the during-sync-call-* family, rewritten trap-on-reenter.wast). What remains upstream is "run to completion": exclusive-thread serialization of async callback turns via automatic backpressure. (#696/#697 are obviated by it.)

Discipline: the pinned definitions.py stays the tie-breaker until the submodule pin is deliberately advanced (docs/architecture.md §1). Nothing is removed preemptively. This issue is the map, filed so (a) no further investment lands in machinery with an expiry date, and (b) the pin-advance PR has a plan waiting.

Inventory: deltic machinery keyed on may_enter, with dispositions

  1. Synthetic per-instantiation root (plan v3 amendment 4 / plan/task: component instance tree has no wire form — host-entry reentrance gate locks only the leaf #101: ComponentInstanceState.rootOf, isSyntheticRoot, enteringSet's host-entry {leaf, root}) — exists solely so host-entry reentrance traps through entering_set(None). Delete. The plan format never carried a wire form for the tree, so this is a contract-text amendment (orchestrator event), not a wire change.
  2. The enter/leave bracket discipline at every site: createLiftedFunction's host-entry gate, Store.tick's bracket, Thread.resumeWith's bracket, Task.requestCancellation's delivery gate+bracket (#705 removes the subtask.cancel check outright — note task core: record tick's poison marker; keep the bracket broken on cancellation-delivery traps #164's fix there is on the removal list), the FACT start-call gates (fact_calls.ts), enter-sync-call's check (adjudicated reentrance: enter-sync-call checks the callee gate but never takes it — host-mediated reentry passes where the reference traps #165), and the dtor lift's entry gate. Reentrance enforcement goes; only poisoning refusal remains (next item). The lift harness itself (resources: host-initiated dtors run as full canonical lifts #163) stays — it is canon_resource_drop's model independent of the gate.
  3. Poisoning re-keys onto the marker. Per-instance poisoning (deltic's named divergence from store-fatal traps) is currently implemented as "mayEnter stays false forever" with the poisonedInstances WeakMap as a shadow (Go components trap (and poison their instance) when the Go runtime reads the clock inside cabi_realloc #145). Post-#705 the WeakMap marker is the only mechanism: entry refusal = isInstancePoisoned + withPoisonCause; releaseSyntheticRootOnPoison deleted. Prerequisite — every bracket-break site must record the marker — landed in task core: record tick's poison marker; keep the bracket broken on cancellation-delivery traps #164 (the tick-path gap).
  4. The scheduler: tick skips threads whose instance is not host-enterable #155 tick filter and scheduler: resumeWith has the same not-host-enterable window as tick, and the tick fix cannot transfer #156/scheduler: settled tails defer while their instance is not host-enterable #161 deferral machinery (readyCandidates enterability filter, dispatchableTail, hasServiceableSettled, serviceSettled skip-in-place, driveAsync's race-set exclusion and all-deferred fallthrough). The lock states they defend against cease to exist; what survives is poisoned-tail retirement (resumeWith's early return). Most of scheduler: settled tails defer while their instance is not host-enterable #161 becomes removable — revisit whether the race-set exclusion is still load-bearing once nothing can defer (a queued settled entry is then always immediately serviceable).
  5. Trap-message surface: the transient "cannot enter component instance (reentrance forbidden)" disappears; the poisoned-corpse refusal (with the Go components trap (and poison their instance) when the Go runtime reads the clock inside cabi_realloc #145 cause suffix) remains. Check corpus wording expectations.
  6. Unaffected: backpressure/exclusive-thread and the CM-4: sync-streams.wast:145 overfits wasmtime's scheduler — upstream test-defect filing kit #43 deferred-entry policy (run-to-completion is retained upstream); the settlement/host-activity driver architecture; embedder/streams: a lifted wrapper's HostActivity arm outlives the hand-back to the guest — one identity round-trip suppresses deadlock verdicts forever #162 (arm liveness), streams: teardown abandon of a parked-write future discards a delivered value; reader poisoned for the writer's fault #168 (future teardown), embedder boundary: missing record/flags labels lower silently; multi-store lift failures escape as AssertionError #170 (embedder fault discipline) — orthogonal.
  7. Tests: the task_test.ts synthetic-root section (plan/task: component instance tree has no wire form — host-entry reentrance gate locks only the leaf #101/scheduler: tick skips threads whose instance is not host-enterable #155/scheduler: resumeWith has the same not-host-enterable window as tick, and the tick fix cannot transfer #156/task core: record tick's poison marker; keep the bracket broken on cancellation-delivery traps #164 pins), settled_deferral_test.ts, and dtor_normalization_test.ts's sibling-enterability pin mostly invert or become obsolete; the poisoning pins survive re-keyed per item 3. The conformance corpus gains #705's new reentrance family and loses trap expectations — testgen regen + expectation triage, including per-browser overlays.

Sequencing sketch

  1. Wait for upstream merge (the PR may still change — re-derive this map against the merged form).
  2. Pin advance in its own PR: submodule bump + testgen regen + corpus triage, no runtime changes beyond what the corpus forces.
  3. Mechanical removal tracks, poisoning re-key (item 3) FIRST, then filters/deferral (item 4), then the root (item 1, with the contract amendment).
  4. Close reentrance: enter-sync-call checks the callee gate but never takes it — host-mediated reentry passes where the reference traps #165's named-divergence entry in docs/architecture.md as resolved.

Metadata

Metadata

Assignees

No one assigned

    Labels

    p2Minor bugs; desirable lower-priority featuresupstream-trackingBlocked on or watching an external project (spec, wasmtime, engines, toolchains)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions