Skip to content

feat: mach-std 0.13.0 — robust spawn, deallocate Result, format coverage#297

Merged
octalide merged 4 commits into
devfrom
feat/0.13.0
Jun 19, 2026
Merged

feat: mach-std 0.13.0 — robust spawn, deallocate Result, format coverage#297
octalide merged 4 commits into
devfrom
feat/0.13.0

Conversation

@octalide

@octalide octalide commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

Integration branch for the 0.13.0 release.

Items

  • mach#1487 — robust process spawn (linux). os.spawn/spawn_redirected now clone(CLONE_VM|CLONE_VFORK|SIGCHLD) the child onto a private stack + a pinned trampoline instead of fork(). Sharing the address space (CLONE_VM) skips fork's copy-on-write commit accounting, so spawn never ENOMEMs on a swapless vm.overcommit_memory=0 host. Verified on x86_64 (native) and aarch64 (qemu) via strace/QEMU_STRACE (clone(child_stack=…, flags=CLONE_VM|CLONE_VFORK|SIGCHLD), zero fork/vfork) + exec/capture + a new repeated-spawn regression. Darwin intentionally stays on fork() — see note below.
  • chore: std.allocator.deallocate generic returns a numeric value instead of translating to a Result or Option #291std.allocator.deallocateResult. The generic deallocate[T] now returns Result[bool, str] (ok on the nil/zero no-op too), aligning with allocate/reallocate; deallocate_raw stays the raw i64 primitive. Every caller that inspected the status was updated + a new test added.
  • test: format coverage gaps — f32 (+ document), smaller int widths, negative signed hex #293 — format coverage + f32 docs. Documented f32 widening to f64 (module + dispatch arm) and added tests for f32 widening, smaller int widths (i8/i16/i32, u16/u32), and negative signed hex.
  • release — bump to 0.13.0 + CHANGELOG.

Notes

  • std: generic derive helpers via $fields (stretch) #285 ($fields derive helpers) is NOT in this release — blocked by a mach 2.0.1 limitation: $each $fields(T) unrolls eagerly at template sema and rejects a generic type parameter ($fields requires a record type), unlike variadic packs which defer to monomorphization (#1475). Only concrete record types work today. It is an explicit stretch ("not required for the release"); deferring pending a compiler fix.
  • Darwin spawn stays on fork(): it is not subject to the linux heuristic-overcommit ENOMEM, and a separate-stack vfork variant needs hand-written stack-switch asm that cannot be runtime-verified without macOS CI — out of scope for a memory-safety-critical change verified here only on linux.

mach build + mach test green (563 passed, 0 failed).

Closes #291
Closes #293
Refs mach#1487

octalide added 4 commits June 19, 2026 12:37
Replace the fork()-based linux spawn with clone(CLONE_VM|CLONE_VFORK|
SIGCHLD) onto a private child stack plus a pinned trampoline, so the child
never copies or touches the parent's address space. Under CLONE_VM the
kernel never runs fork's COW commit-accounting, so spawn no longer ENOMEMs
on a swapless vm.overcommit_memory=0 host (GitHub runners) — mach#1487 —
and the fix benefits every fork-heavy mach program.

The child runs the trampoline on its own stack (reached by a direct
jump/branch from the clone child, mirroring thread_spawn): it only
redirects fds, closes inherited fds, and execs, then exits 126/127 on
failure. CLONE_VFORK suspends the parent until the child execs or exits,
keeping argv/envp and the ctx struct stable.

Verified x86_64 (native) and aarch64 (qemu): strace/QEMU_STRACE confirm
clone(CLONE_VM|CLONE_VFORK|SIGCHLD, child_stack=...); exec/capture and a
new repeated-spawn regression pass on both arches.

Refs mach#1487
… hex

Document f32 formatting (widens to f64, no f32-specific shortest
round-trip) on the module and the dispatch arm, and add tests:
- f32 exactly-representable values plus an inexact one (0.1f32) showing
  the full f64 expansion of the widened value.
- one case per smaller width class (i8/i16/i32, u16/u32) that widens to
  i64/u64.
- negative signed hex (-1i64 -> ffffffffffffffff, -42i64 -> ...d6).

Closes #293
Align the generic deallocate[T] with allocate/reallocate by translating
the raw deallocator status into a Result instead of a bare i64: ok(true)
on success (including the nil-pointer / count == 0 no-op), err on a
non-zero status. Update every caller that inspected the return
(vector/deque/heap/bitset/buffer dnit, map free, arena tests) and add a
generic-deallocate Result test. deallocate_raw stays i64 (the raw errno
primitive under the typed layer).

Closes #291
Robust clone-based process spawn (mach#1487), generic deallocate returns
Result (#291), and format f32 documentation + coverage tests (#293).
@octalide octalide changed the title feat: mach-std 0.13.0 (robust spawn, derive helpers, deallocate Result, format tests) feat: mach-std 0.13.0 — robust spawn, deallocate Result, format coverage Jun 19, 2026
@octalide octalide marked this pull request as ready for review June 19, 2026 16:56
@octalide octalide merged commit 8dc2e2c into dev Jun 19, 2026
1 check passed
@octalide octalide deleted the feat/0.13.0 branch June 19, 2026 16:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant