diff --git a/quest/m3/README.md b/quest/m3/README.md index fafe64a88..dc6a55bf8 100644 --- a/quest/m3/README.md +++ b/quest/m3/README.md @@ -11,6 +11,13 @@ std the translators cover before a consumer calls them. Decided with the maintainer on 2026-10-27: rust2 aims to support all of std, so a generic std gap is planned here even when moq never calls it. +Decided with the maintainer on 2026-11-07: ✅ little time goes to unsafe Rust. A +translator may refuse unsafe code with its span, requiring safe Rust, and a common +library's unsafe internals may be replaced by a runtime mapping over its public API, as +`hashbrown`'s and tokio's channels are (rejected: planning each unsafe std gap that no +consumer reaches, such as `MaybeUninit::zeroed`, `Rc::new_uninit`, and +`ptr::write_bytes`). + ## Required - [Retrial Cranelift on moq's tests](/quest/m3/cranelift-unwind.md) - waits on upstream: moq's tests pass under Cranelift, so its CI can weigh it again diff --git a/quest/m3/ts-wasm-bindgen/README.md b/quest/m3/ts-wasm-bindgen/README.md index 328d09ad1..dfcbc30e5 100644 --- a/quest/m3/ts-wasm-bindgen/README.md +++ b/quest/m3/ts-wasm-bindgen/README.md @@ -49,12 +49,15 @@ Decided with the maintainer on 2026-11-06: `link_section` static, not from the `extern` blocks' source. The [spike](https://github.com/moq-dev/rust2/pull/638) has the measurements: `macro_rules!`-made imports, which source reading misses, are on the encoder's path. -- Open: web-codecs' `VideoEncoder` also hands its frames and errors through tokio's - `sync::mpsc` and `sync::watch`. Translation refuses those today, in their intrusive - lists and raw pointers into `UnsafeCell`s, about 50 refusals in the spike's census. So - web-codecs translating end to end needs them too, beyond the quests below. +- ✅ web-codecs' encoders and decoders also hand their frames and errors through tokio's + `sync::mpsc` and `sync::watch`, which translation refuses today (about 50 refusals in + the spike's census), so + [tokio's sync channels are mapped into the runtime](/quest/m3/ts-wasm-bindgen/tokio-sync.md) + (rejected: translating tokio's source, whose intrusive lists and raw pointers into + `UnsafeCell`s are unsafe code a JS caller has no use for). ## Required - [Translate wasm-bindgen imports](/quest/m3/ts-wasm-bindgen/imports.md) - web-sys and js-sys imports read from the encoded program, with `JsValue` and imported types as JS values, proven on synchronous calls - [wasm-bindgen closures and promises](/quest/m3/ts-wasm-bindgen/closures.md) - `Closure` and js-sys's futures mapped, proven on web-sys's `VideoEncoder` in headless Chromium +- [tokio's sync channels mapped into the runtime](/quest/m3/ts-wasm-bindgen/tokio-sync.md) - `mpsc`, `watch`, `oneshot`, and `select!`'s support, which web-codecs passes frames and errors through diff --git a/quest/m3/ts-wasm-bindgen/tokio-sync.md b/quest/m3/ts-wasm-bindgen/tokio-sync.md new file mode 100644 index 000000000..7f2915375 --- /dev/null +++ b/quest/m3/ts-wasm-bindgen/tokio-sync.md @@ -0,0 +1,34 @@ +# [M] tokio's sync channels mapped into the runtime + +## Goal + +tokio's `sync::mpsc` (bounded and unbounded), `sync::watch`, and `sync::oneshot`, and +`tokio::select!`'s support, are mapped into the [rust2-ts](/ts/README.md) runtime, as +`hashbrown` and `bytes` are, so a crate passing values through them translates with no +`ts.toml` binding. Differential tests against native Rust on tokio's current-thread +runtime prove it: values, ordering, closed and lagged errors, and when each future +becomes ready. + +## Plan + +Suggested on [#638](https://github.com/moq-dev/rust2/pull/638): web-rs's web-codecs hands +its encoders' and decoders' frames out through `mpsc::unbounded_channel`, and their errors +through `watch::channel`, read in a `tokio::select!` with `biased;`. Its spike's census +counts about 50 refusals in tokio's `sync`. + +Decided with the maintainer on 2026-11-07: ✅ map the channels into the runtime (rejected: +translating tokio's source, whose intrusive waiter lists, raw pointers into `UnsafeCell`s, +atomics, and `process::abort` mean nothing in single-threaded JS; and mapping only +web-codecs' methods, which the next consumer would reopen). Unsafe Rust may stay refused +where a wrapper over a common library does the job. + +- Each channel's public API maps, waiters kept in a queue the runtime wakes, as + `rs.Future`s on its executor. Methods that block a thread (`blocking_recv`, + `blocking_send`) are refused, as no JS thread blocks. +- `select!` expands to code that already translates, apart from its support module: + `thread_rng_n` picks the first branch polled, uniform as tokio's is, so a `select!` + without `biased;` maps too. +- `Notify`, `Mutex`, `RwLock`, and `Semaphore` stay refused where reached, until a + consumer needs them. + +Public API: the translator's output for a crate using tokio's sync channels.