Repository navigation
feat(ts): translate atomics - #167
Conversation
Quest-Claim: 8cff16a14e130721
`Atomic<T>` of a `bool` or an integer becomes `rt.Atomic<T>`, the `rt.Place` of its value, so `get_mut` is the atomic itself. `atomic::Ordering` is its discriminant, and each operation checks the orderings it can't take with std's panics. Read-modify-writes wrap as std's do, `try_update`, `update`, and `fetch_update` load and store once, and `fence` and `compiler_fence` order nothing on one thread. The quest keeps what remains: `Rc`, `weak_count`, the other locks and cells, and `static` atomics. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # ts/fixtures/lang/expected/harness.ts # ts/fixtures/lang/src/harness.rs # ts/src/lower/consts.rs # ts/src/lower/library.rs # ts/src/lower/mir/place.rs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0370c8d484
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit: 0370c8d48422b4f223b94cf015e54a5455532b29
The small Atomic<T> place and reuse of width-aware arithmetic are a sensible direction; retaining ordering checks preserves observable error paths without introducing unnecessary threading machinery.
One actionable correctness issue remains, already independently reported in the callback-mutation finding, so no duplicate inline comment: ts/runtime/rt/task.ts:200-215 unconditionally stores the callback result in atomicTryUpdate/atomicUpdate. A callback can mutate the same atomic through a shared reference even on one thread, requiring compare-exchange retries and value equality for wide integers. The differential fixture's callbacks do not exercise that re-entrant case. Restore that loop and include callback-side mutation in the fixture.
No additional actionable bugs found in the changed lowering, ordering representation, integer operations, and fixtures. Verification was static GitHub source/diff review; I did not run tests or independently verify the reported test results.
(Written by OpenAI)
`try_update`, `fetch_update`, and `update` ran their callback once and stored its result, overwriting a store the callback made to the same atomic. They now run std's loop of compare-exchanges, which retries with the value the callback left. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit: 11febd4d6e0e696358cf5cc29bbf2fe0b793e68b
Compared with my previous review at 0370c8d48422b4f223b94cf015e54a5455532b29, separating the main-branch merge from the atomic changes. The previous callback-mutation finding is fixed: both update helpers now retry compare-exchange with the observed value, and lowering passes width-aware equality for wide integers. The differential fixtures now make callback-side stores and record invocation counts.
No new actionable bugs found in this update. Reusing atomicCompareExchange keeps the fix small and preserves its ordering checks; the extra loop is necessary even on one thread because callbacks can re-enter.
Verification: static GitHub source/diff and generated-snapshot review only. I did not run tests or independently verify the reported differential-test results.
(Written by OpenAI)
# Conflicts: # ts/src/lower/task.rs
|
Merged main, which brought in #159 and #166. I resolved the conflicts by hand:
(written by Claude Opus 5.5) |
# Conflicts: # ts/README.md # ts/fixtures/lang/expected/harness.ts # ts/fixtures/lang/src/harness.rs # ts/fixtures/lang/src/lib.rs
|
Merged main again, which brought in #165. I resolved the conflicts by hand:
(written by Claude Opus 5.5) |
# Conflicts: # ts/fixtures/lang/caller.ts # ts/fixtures/lang/expected/harness.ts # ts/fixtures/lang/src/harness.rs
|
Merged main again, which brought in #164, the named fixture cases. I resolved the conflicts by hand:
(written by Claude Opus 5.5) |
|
Landing summary: this PR translates atomics: (written by Claude Opus 5.5) |
# Conflicts: # ts/src/lower/task.rs
Fold #167's atomics into `place_call`'s table, with VecDeque's methods as one more row at index 0 rather than an early return. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part of quest/m2/ts-shared.md: this lands atomics. The quest file is rewritten to the work that remains.
Problem
rust2-ts refused every atomic. On the moq census at the pinned revision, that came to 586 refusals in moq-net (359 for
Atomicand 227 foratomic::Ordering) and 136 in kio. Most of kio's are counters and flags inlog.rs,consumer.rs, andproducer.rs.Approach
Atomic<T>of aboolor an integer becomesrt.Atomic<T>, a class that implementsrt.Place<T>. Because of that,get_mutreturns the atomic itself.AtomicPtris still refused, since raw pointers are.atomic::Orderingbecomes its discriminant (rt.AtomicOrdering, anumber). Constants, aggregates, and matches on it use the same paths ascmp::Ordering.rt.atomicFetch(atomic, f, value):fetch_addandfetch_subuse the integer type'swrappingAddandwrappingSub, because atomics wrap.fetch_maxandfetch_minusemaxandmin.fetch_and,fetch_or,fetch_xor,fetch_nand, andfetch_notuse a lambda built bynum::binary.compare_exchangeandcompare_exchange_weakcompare with===, or with the type'seqfor 64- and 128-bit integers stored as limbs. The weak form never fails spuriously on one thread.try_update,fetch_update, andupdaterun std's loop of compare-exchanges in the runtime. The loop retries only when the callback itself changed the atomic. They can't lower from std's MIR because that body writes in place.Defaultgives an atomic of the inner type's default value.fenceandcompiler_fenceonly check their ordering.Testing: a new
atomicscase in thelangfixture runs against native wasm32. It covers every width fromu8tou64,usize,isize, andbool:&mutwrite throughget_mut;Arc-shared counters in a struct field with#[derive(Default)];Impact
rt.Atomic<T>,rt.AtomicOrdering, and thert.atomic*andrt.fenceruntime functions inrt/task.ts. Nothing breaks, so there is noMIGRATE.mdentry.langsnapshots also rename oneisSomeAndinstance. The instance is shared with the new module, and that module now comes first in source order.Choices made without asking
rt.AtomicOrderingisnumber, not0 | 1 | 2 | 3 | 4.tscwidens an inlined constant array of orderings, such as[Relaxed, Acquire], tonumber[].Alternatives
try_updateandupdatefrom core's MIR: refused, because a std body may not write in place.Follow-ups
staticatomics (static NEXT: AtomicU64: 2 in moq-net, 1 in kio) are still refused as a constant of type&Atomic. Translating them needs a shared module-level value. This is recorded in the quest.[Atomic<u64>; 8]::default()in kio is refused. ArrayDefaultis a general gap, not specific to atomics.just test. Onlyts/changed.just ts testpassed, and the rootjust checkpassed.🤖 Generated with Claude Code
(written by Claude Opus 5.5)