Skip to content
Closed
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
4 changes: 4 additions & 0 deletions quest/m3/ts-unsafe/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,7 @@ Public API: the translator's output.
- [NonZero's unchecked arithmetic](/quest/m3/ts-unsafe/nonzero-unchecked-ops.md) - `NonZero::unchecked_add` and `unchecked_mul` translate, aborting at std's site
- [UnsafeCell's raw accessors](/quest/m3/ts-unsafe/unsafecell.md) - `UnsafeCell::raw_get`, `from_mut`, and `replace` translate
- [A byte local whose address is taken, in a buffer of its own](/quest/m3/ts-unsafe/lone-byte-buffers.md) - raw and mutable slices of a `u8` local, and casts of them to byte arrays, translate instead of being refused
- [Zeroed values beyond one Box](/quest/m3/ts-unsafe/zeroed-values.md) - `MaybeUninit::zeroed`, `mem::zeroed`, and `Box::new_zeroed_slice` translate through the zero-value code
- [Rc and Arc of an uninitialized value](/quest/m3/ts-unsafe/rc-arc-uninit.md) - `Rc` and `Arc`'s `new_uninit`, `new_zeroed`, slice forms, and `assume_init` translate
- [A raw pointer into a nested array](/quest/m3/ts-unsafe/nested-array-pointers.md) - `&raw mut (*p)[1][0]` points into its inner array
- [ptr::write_bytes beyond bytes](/quest/m3/ts-unsafe/write-bytes-any.md) - `write_bytes` of integers, floats, and arrays and tuples of them translates
22 changes: 22 additions & 0 deletions quest/m3/ts-unsafe/nested-array-pointers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# [M] A raw pointer into a nested array

## Goal

[rust2-ts](/ts/README.md) translates a raw pointer to an element of a nested array, such as
`&raw mut (*p)[1][0]`, today refused as not supported yet. It points at that element in
its inner array, so reads, writes, and arithmetic within the inner array match native Rust,
proven by differential tests.

## Plan

Suggested on [#639](https://github.com/moq-dev/rust2/pull/639). An element pointer is
`rs.AtIndex`, `{ array, index }`, into the array JS holds it in; for a nested array that is
the inner array. Arithmetic that crosses from one inner array into the next, which Rust
allows within the outer allocation, stays refused with a span unless the plan finds a
cheap exact way; say which in the PR.

Decided with the maintainer on 2026-11-07: ✅ m3, in this epic (from #639's follow-ups), ✅
arithmetic within the inner array (rejected: crossing inner arrays as a requirement). No
consumer at the moq pin.

Public API: the translator's output.
22 changes: 22 additions & 0 deletions quest/m3/ts-unsafe/rc-arc-uninit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# [S] Rc and Arc of an uninitialized value

## Goal

[rust2-ts](/ts/README.md) translates `Rc` and `Arc`'s `new_uninit`, `new_zeroed`, their
slice forms (`new_uninit_slice`, `new_zeroed_slice`), and `assume_init`, the way `Box`'s
forms translate, proven by differential tests against native Rust, with strong and weak
counts and drops matching.

## Plan

Suggested on [#639](https://github.com/moq-dev/rust2/pull/639) (`Box::new_uninit`,
`new_zeroed`, `write`, and `assume_init` for one value) and
[#606](https://github.com/moq-dev/rust2/pull/606) (`Box::new_uninit_slice`). These are
stable std APIs, and std gaps are deferred, not dropped. Cover both ways a program writes
the value before `assume_init`: `Rc::get_mut(&mut rc).unwrap().write(v)`, and a write
through `as_ptr`.

Decided with the maintainer on 2026-11-07: ✅ m3, in this epic (from #639's follow-ups). No
consumer at the moq pin.

Public API: the translator's output.
22 changes: 22 additions & 0 deletions quest/m3/ts-unsafe/write-bytes-any.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# [S] ptr::write_bytes beyond bytes

## Goal

[rust2-ts](/ts/README.md) translates `ptr::write_bytes` for pointees other than bytes whose
every byte pattern the runtime can build, such as integers, floats, and arrays and tuples of
them (zeroing a `[u32]` is the common case), proven by differential tests against native
Rust. Any other pointee stays refused with a span.

## Plan

Suggested on [#642](https://github.com/moq-dev/rust2/pull/642), which translated
`write_bytes` for `u8` and `MaybeUninit<u8>` pointers through `rs.ptrWriteBytes`. A value
of `n` repeated bytes is the integer or float those bytes spell in little-endian wasm32
order; the zero case can reuse [#639](https://github.com/moq-dev/rust2/pull/639)'s
zero-value code. A pattern that is invalid for the pointee (a `bool` of 2) is UB in Rust and
need not be reproduced.

Decided with the maintainer on 2026-11-07: ✅ m3, in this epic (from #642's follow-ups), ✅
any byte pattern (rejected: zero only). No consumer at the moq pin.

Public API: the translator's output.
21 changes: 21 additions & 0 deletions quest/m3/ts-unsafe/zeroed-values.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# [S] Zeroed values beyond one Box

## Goal

[rust2-ts](/ts/README.md) translates `MaybeUninit::zeroed`, `mem::zeroed`, and
`Box::new_zeroed_slice`, proven by differential tests against native Rust. Each builds the
value all-zero bytes give, as `Box::new_zeroed` does.

## Plan

Suggested on [#639](https://github.com/moq-dev/rust2/pull/639), which translated
`Box::new_zeroed` for one value: it builds the zero value part by part through tuples,
arrays, the crate's structs, enums by their zero tag or niche, and std's wrappers (`Wrapping`,
`Cell`, `Mutex`, ...), and leaves a part that can't be zero, such as a reference or a
`String`, unwritten. Reuse that code rather than a second walk. `mem::zeroed` of a type with
a part that can't be zero is UB in Rust; translate it as the same partly unwritten value.

Decided with the maintainer on 2026-11-07: ✅ m3, in this epic (from #639's follow-ups). No
consumer at the moq pin.

Public API: the translator's output.