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
2 changes: 2 additions & 0 deletions quest/m3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
20 changes: 20 additions & 0 deletions quest/m3/ts-if-let-drop.md
Original file line number Diff line number Diff line change
@@ -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.
22 changes: 22 additions & 0 deletions quest/m3/ts-u64-wrapping.md
Original file line number Diff line number Diff line change
@@ -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`.
7 changes: 5 additions & 2 deletions quest/m3/ts-wasm-bindgen/closures.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<RefCell<VecDeque>>`.
- 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<RefCell<VecDeque>>`), 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
Expand Down