Conversation
…nels)
The webcrypto-composed polymorph-tls suite (three async wit-bindgen
components) hit `assert!(!state.is_null())` in wit-bindgen's callback entry
(async_support.rs:578): the runtime had invoked a task's [callback] export
whose context-local slot 0 was empty. Root cause chain, isolated with new
env-gated probes (CE_CTX_TRACE / CE_SP_TRACE / extended CE_AMBIENT_TRACE):
- Engine continuation chunks — the segments of a promising activation
between suspension/hop points — begin as promise reactions with no
synchronous signal to the runtime. With several concurrently-suspended
sibling activations, chunks interleave at an empty bracket stack, and
the ambient (tier-2 LIFO claims) misattributes every read in a later
chunk: a hop's owner capture, or an unsafe intrinsic like context.set,
which has no hop to re-anchor on. wit-bindgen's callback epilogue then
restored one task's state pointer into another THREAD's context slots,
and the starved thread's next disciplined callback invocation trapped.
- Two contributing defects fixed:
1. scheduler.ts claimActivationAmbient: idempotence was a positional
NOOP, leaving a stale finished-callee claim on top (its release edge
is a promise reaction, one microtask late). Re-claiming now moves the
claim to the top — the stack's own documented contract.
2. jspi/bridge.ts: attribution sentinels. At every point where the
engine is about to queue a continuation reaction — the fast-path hop
(jspi pin (j)) and the genuine-suspension settle — queue a microtask
FIRST that claims the chunk's owner. Per-promise reaction FIFO makes
each [sentinel, chunk] pair contiguous even when several promises
settle in one drain, so every chunk starts with its owner freshly on
top, with zero delay and zero reordering.
The reordering constraint is load-bearing: a first-cut serializing gate
(one un-run continuation at a time) fixed attribution but measurably
shifted the deterministic-profile backpressure-admission order —
async-calls-sync.wast's guest asserts that order and caught it. The
sentinel design perturbs nothing: engine-natural scheduling is preserved
bit-for-bit (full corpus + browser/shell lane expectations unchanged).
`Promise.resolve().then`, not `queueMicrotask`, which bare engine shells
lack (sm-pinned lane caught it).
Pins: runtime/tests/jspi/chunk_attribution_test.ts (two interleaved
resumptions must each read their own ambient; fails pre-fix), and the
tls smoke's webcrypto composition is now fully green — its #24 xfail is
pruned (tools/smoke-tls/run.ts), all applicable cases green on every
composition (sole remaining class: tag-gating #25).
Gates: runtime 324 (seeds unset/1/4242), harness 69 (x3 seeds, zero
corpus deltas), sm-pinned + chromium + firefox lanes at unchanged
expectations, websocket 55/55, wasi-shims, ct-runner, webcrypto, webrtc,
iroh exam 5/5, smoke-tls PASS (seeded too).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #24.
Two scheduler fixes (details in the commit message):
claimActivationAmbientre-claims now move-to-top instead of noop — the LIFO's documented "top = innermost running activation" contract.jspi/bridge.ts: a microtask claiming the chunk's owner is queued contiguously ahead of every engine continuation reaction (fast-path hop and genuine-suspension settle alike). This is the JSPI substitute for the identity that fibers give wasmtime for free.A serializing-gate design was tried and rejected: it fixed attribution but shifted deterministic-profile admission order (caught by async-calls-sync.wast). The sentinel design preserves engine-natural ordering exactly — all corpus/lane expectations unchanged.
Pins:
runtime/tests/jspi/chunk_attribution_test.ts(fails pre-fix) + the tls smoke's webcrypto composition xfail pruned (now the integration pin; all applicable cases green on every composition).Gates: runtime + harness across seeds {unset,1,4242}, sm-pinned / chromium / firefox lanes at unchanged expectations, websocket 55/55 conformance, wasi-shims, ct-runner, webcrypto, webrtc, iroh exam 5/5, smoke-tls PASS.