diff --git a/quest/m3/README.md b/quest/m3/README.md index cbb5b1a3c..72d1a95dd 100644 --- a/quest/m3/README.md +++ b/quest/m3/README.md @@ -49,3 +49,5 @@ memory model for values whose address is reinterpreted, without a consumer. - [Throw only where Rust panics](/quest/m3/ts-runtime-throws.md) - no runtime `rust2-ts:` error where native Rust goes on: an exact slower path, or a refusal at translation - [rust2-ts with no ts.toml](/quest/m3/ts-configless.md) - a crate's whole `pub` API translates with no config and no bound items - [Browser APIs through wasm-bindgen](/quest/m3/ts-wasm-bindgen/README.md) - web-sys and js-sys imports become direct JS calls, so idiomatic crates such as web-rs's web-codecs translate as stock crates +- [`if let` of a temporary whose rest drops](/quest/m3/ts-if-let-drop.md) - `if let Some(E::A(x)) = temp()` with a destructor in the rest of `temp` emits TypeScript that type-checks +- [`u64` wrapping arithmetic in V8](/quest/m3/ts-u64-wrapping.md) - `rs.u64WrappingAdd` and its kin cost near a plain `+` while the value is a safe integer diff --git a/quest/m3/ts-if-let-drop.md b/quest/m3/ts-if-let-drop.md new file mode 100644 index 000000000..f9632a32d --- /dev/null +++ b/quest/m3/ts-if-let-drop.md @@ -0,0 +1,20 @@ +# [S] If-let of a temporary whose rest drops type-checks + +## Goal + +[rust2-ts](/ts/README.md) translates `if let Some(E::A(x)) = temp()`, where the rest of +the temporary has a destructor, into TypeScript that type-checks, proven by differential +tests against native Rust over enums whose variants hold a `Drop` struct, an `Option` of +one, and a plain struct with `Drop`. + +## Plan + +Found by [#654](https://github.com/moq-dev/rust2/pull/654), whose `tokio` fixture works +around it by reading bounded senders by reference. The drop of the rest of the temporary +sits behind a second `tag !== "A"` test, which `tsc` rejects (TS2367) once it narrowed the +temporary in the first test's arm. It is safe Rust, so any crate can hit it; m3's +[unsafe policy](/quest/m3/README.md) puts translation effort there. + +Decided with the maintainer on 2026-11-07: ✅ plan it, in m3 (from #654's follow-ups). + +Public API: the translator's output. diff --git a/quest/m3/ts-u64-wrapping.md b/quest/m3/ts-u64-wrapping.md new file mode 100644 index 000000000..5005561e2 --- /dev/null +++ b/quest/m3/ts-u64-wrapping.md @@ -0,0 +1,22 @@ +# [M] u64 wrapping arithmetic near a plain add in V8 + +## Goal + +[rust2-ts](/ts/README.md)'s `u64` wrapping arithmetic (`rs.u64WrappingAdd` and its kin) +costs close to a plain `+` while the value stays a safe integer, so the codec bench's +`parts/prefix-writes` runs near its hand-written plain-array route in Node and Chrome, not +12-13x off it. Exact for every input, proven by differential tests against native Rust past +2^53 and at the wrap. + +## Plan + +Found by [#656](https://github.com/moq-dev/rust2/pull/656): with `iter_mut` loops stepped by +index, `rs.u64WrappingAdd` costs about 7x a plain `+` per item in Node, and the same loop +with a plain `+ 1` ran at 1.2x the plain array. Bun is already at 2.6-3.5x. Every `u64` loop +in moq pays it. Measure with CPU time or instruction counts in Node, Chrome, and Firefox +(the [bench](/ts/README.md#bench)), and keep the 64-bit representation decided in the +[Design](/ts/README.md#design) section: numbers while safe integers. + +Decided with the maintainer on 2026-11-07: ✅ plan it, in m3 (from #656's follow-ups). + +Public API: the translator's output and `rs.ts`. diff --git a/quest/m3/ts-wasm-bindgen/closures.md b/quest/m3/ts-wasm-bindgen/closures.md index 951a41f56..47131c6e3 100644 --- a/quest/m3/ts-wasm-bindgen/closures.md +++ b/quest/m3/ts-wasm-bindgen/closures.md @@ -24,8 +24,11 @@ headless Chromium proves it against the same fixture's wasm-bindgen build. `spawn_local` queues a microtask, as js-sys's `queue.rs` does. Mapping these stands in for js-sys's JSPI bridge, which `spawn_local` checks first: with no export translated, no JSPI context exists. `jspi_block_on_promise` is refused, as no JS blocks on a promise. -- The fixture keeps web-codecs' calls but not its tokio channels, which the `tokio` - fixture covers. It hands frames out through `Rc>`. +- The fixture keeps web-codecs' calls and its tokio channels, `mpsc::unbounded_channel` + for frames and `watch::channel` for errors read in a `biased;` `select!`, which translate + since [#654](https://github.com/moq-dev/rust2/pull/654). Decided with the maintainer on + 2026-11-07 (rejected: handing frames out through `Rc>`), since + web-codecs end to end needs them. - Chromium decodes and encodes VP8 headless: Chrome 155 there gave a key chunk with a `decoderConfig` and two deltas from three 64x64 frames. Only the bench shell carries Chromium today, apart for its size. Run this test where it does: in the merge gate if