Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,34 @@ the site (`runtime/src/intrinsics/async_builtins.ts`, the determinacy park
in `createSubtaskCancel`); regression pinned across seeds by
`runtime/tests/cancel_bracket_race_test.ts`.

Named divergence (2026-08-20, [#165](https://github.com/lann/deltic/issues/165),
adjudicated-accept): **`enter-sync-call` checks the callee's reentrance gate
but does not take it.** A FACT sync guest→guest call performs the
reference's `trap_if(not may_enter_from(caller))` and stops — the
`enter_from`/`leave_to` bracket around the call body (`Store.lift`,
definitions.py:578-585) is deliberately omitted, so *host-mediated* reentry
into the callee while the call is in flight (host → A.f → C.g → host import
→ host re-enters C.g) is admitted where the pinned reference traps. Pure
guest→guest cycles remain statically impossible (FACT compile-time traps;
the instance-import DAG, [#99](https://github.com/lann/deltic/issues/99)/
[#101](https://github.com/lann/deltic/issues/101)). Accepted on three
grounds: **wasmtime parity** (`enter_guest_sync_call` performs no reentrance
check at all, and fused adapters elide it); **architecture** — taking the
bracket would create a guest→guest lock spanning suspension points,
reintroducing the await-spanning-lock class that
[#156](https://github.com/lann/deltic/issues/156)/[#160](https://github.com/lann/deltic/issues/160)
eliminated; and **upstream trajectory** — CM PR
[#705](https://github.com/WebAssembly/component-model/pull/705) ("CABI:
remove the may_enter flag/trap") deletes the trap from the `canon lift`,
`resource.drop`, and `subtask.cancel` paths and makes previously-trapping
reentrance valid, retaining only run-to-completion serialization of async
callback turns. This divergence is therefore a trailing indicator of the
upstream removal and self-resolves when the submodule pin advances past
#705; the pin-advance migration map is
[#173](https://github.com/lann/deltic/issues/173). Until that advance the
pinned definitions.py remains the tie-breaker everywhere else — every
reentrance check deltic does enforce stays in force.

## 7. Canonical ABI decisions

Authority: [CanonicalABI.md] and its executable reference
Expand Down
20 changes: 14 additions & 6 deletions runtime/src/intrinsics/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -514,12 +514,20 @@ function createTrampolineBody(
// Deliberately *not* done here: `enter_from` / `leave_to` around the
// bracket. The reference locks the callee for the duration, which
// would additionally trap host-mediated reentrance (host -> A.f ->
// C.g -> host import -> host invokes C.g). Doing it needs the trap /
// capability-signal distinction that only `exec/boundary.ts` has
// (a `NeedsJspi` bail out of a sync callee skips `exit-sync-call`
// and would poison a healthy instance), and the general form of that
// hole is the missing `ComponentInstance.parent` chain already
// recorded in `task/mod.ts` `enteringSet`. Reported, not smuggled in.
// C.g -> host import -> host invokes C.g).
//
// ADJUDICATED 2026-08-20 (deltic#165; named divergence in
// docs/architecture.md section 6): accepted — the bracket stays
// omitted. Three grounds: wasmtime parity (`enter_guest_sync_call`
// checks nothing); taking the bracket would create a guest-to-guest
// lock spanning suspension points, reintroducing the await-spanning
// -lock class removed by #156/#160; and upstream is deleting the
// trap outright — CM PR #705 ("CABI: remove the may_enter
// flag/trap") makes previously-trapping reentrance valid, so this
// divergence is a trailing indicator of the removal and
// self-resolves at the submodule pin advance (migration map:
// deltic#173). Until that pin advance the reference's checks deltic
// DOES enforce stay in force.
if (
typeof callerInstance === "number" &&
typeof calleeInstance === "number"
Expand Down
Loading