Skip to content

Commit 36b8e9c

Browse files
committed
Add cross-platform testing docs and D110 zwasm allocator injection decision
- CLAUDE.md: cross-platform testing section, --seed 0 note, reference links - .dev/references/setup-orbstack.md: shared VM setup (with zwasm) - .dev/references/ubuntu-testing-guide.md: test commands, known differences - D110: future plan for zwasm allocator injection to eliminate dual-GC
1 parent e41ee70 commit 36b8e9c

4 files changed

Lines changed: 155 additions & 0 deletions

File tree

.claude/CLAUDE.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,15 @@ Wasm history: `bench/wasm_history.yaml` — CW vs wasmtime wasm benchmark progre
232232
**Baseline accuracy**: Sequential full-suite runs cause thermal throttling.
233233
For accurate baselines, measure each benchmark individually with 10+ runs.
234234

235+
## Cross-Platform Testing (Ubuntu x86_64)
236+
237+
Test on Ubuntu x86_64 via OrbStack before releases. See:
238+
- Setup: `.dev/references/setup-orbstack.md` (shared VM with zwasm)
239+
- Commands: `.dev/references/ubuntu-testing-guide.md`
240+
241+
**Critical**: `zig build test --seed 0` required on Rosetta (crashes without it).
242+
3 float-format test failures are known/accepted platform differences.
243+
235244
## Notice
236245

237246
**Shell escaping**: For `swap!`, `nil?` etc., write a temp .clj file instead of `-e`.
@@ -302,3 +311,5 @@ Check `.claude/references/zig-tips.md` first, then Zig stdlib at
302311
| Known issues | `.dev/known-issues.md` | Bug/workaround/debt tracking (P0-P3) |
303312
| Baselines | `.dev/baselines.md` | Non-functional regression thresholds |
304313
| Bytecode debug | `./zig-out/bin/cljw --dump-bytecode` | When VM tests fail or bytecode looks wrong |
314+
| Ubuntu testing | `.dev/references/ubuntu-testing-guide.md` | OrbStack VM test commands + --seed 0 |
315+
| OrbStack setup | `.dev/references/setup-orbstack.md` | VM creation (shared with zwasm) |

.dev/decisions.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,3 +912,29 @@ refactoring tractable.
912912
**Rules**: `.claude/rules/zone-deps.md` (auto-loads on src/ edits).
913913

914914
**Result targets**: 0 upward imports, bootstrap.zig < 200 LOC, main.zig < 200 LOC.
915+
916+
## D110: zwasm Allocator Injection — Eliminate Dual-GC
917+
918+
**Date**: 2026-03-08
919+
**Status**: Future (depends on zwasm D128)
920+
**Decision**: When zwasm implements allocator injection (D128), CW will pass its
921+
own GC-managed allocator to zwasm instead of letting zwasm use an internal Arena.
922+
This eliminates the dual-GC lifecycle mismatch.
923+
924+
**Current problem**: CW GC (Mark-Sweep) manages wasm Value objects (wasm_module,
925+
wasm_fn, wasm_instance). When CW GC sweeps these, it frees the CW-side wrapper,
926+
but zwasm's internal Arena retains the underlying memory. The Arena only frees
927+
on full deinit (process exit), so long-running CW processes that load/unload
928+
Wasm modules will leak zwasm-side memory.
929+
930+
**Target state**: CW passes its allocator to `zwasm.Engine.init(cw_allocator)`.
931+
zwasm allocations become CW GC-visible. When CW GC sweeps a wasm Value, the
932+
underlying zwasm memory is also reclaimable.
933+
934+
**Scope**: Only zwasm's internal bookkeeping (module metadata, function tables,
935+
instance state). Wasm linear memory remains separately managed per spec.
936+
937+
**Migration**: Minimal CW changes — update `wasm_types.zig` to pass allocator
938+
at Engine construction. Requires zwasm D128 to be implemented first.
939+
940+
Related: zwasm D128, cw-new D13.

.dev/references/setup-orbstack.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# OrbStack Ubuntu x86_64 VM Setup
2+
3+
One-time setup for local Ubuntu x86_64 testing via OrbStack on Apple Silicon.
4+
This VM is shared with zwasm — if already created, skip to verification.
5+
6+
## VM Creation
7+
8+
```bash
9+
orb create --arch amd64 ubuntu my-ubuntu-amd64
10+
```
11+
12+
## Tool Installation
13+
14+
See `zwasm/.dev/references/setup-orbstack.md` for full installation commands.
15+
The same VM and tools are used for both projects:
16+
17+
| Tool | Version | Path |
18+
| ---------- | -------- | ------------------------ |
19+
| Zig | 0.15.2 | /opt/zig/zig |
20+
| wasmtime | 42.0.1 | ~/.wasmtime/bin/wasmtime |
21+
| wasm-tools | 1.245.1 | /usr/local/bin/wasm-tools|
22+
| WASI SDK | 25 | /opt/wasi-sdk |
23+
| Rust | stable | ~/.cargo/bin/rustc |
24+
| hyperfine | system | /usr/bin/hyperfine |
25+
26+
## Verification
27+
28+
```bash
29+
orb run -m my-ubuntu-amd64 bash -lc "zig version && wasmtime --version"
30+
# Expected: 0.15.2, wasmtime-cli 42.0.1
31+
```
32+
33+
## Notes
34+
35+
- VM name: `my-ubuntu-amd64` (shared between zwasm and ClojureWasm)
36+
- Mac filesystem accessible inside VM at original paths (e.g., `/Users/shota.508/...`)
37+
but building directly from Mac FS is slow — rsync to VM-local storage instead
38+
- OrbStack uses Rosetta for x86_64 emulation on Apple Silicon
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Ubuntu x86_64 Testing Guide (OrbStack)
2+
3+
How to run ClojureWasm tests on the local OrbStack Ubuntu x86_64 VM.
4+
5+
## Connection
6+
7+
```bash
8+
# Interactive shell
9+
orb shell my-ubuntu-amd64
10+
11+
# One-shot command (used by Claude Code)
12+
orb run -m my-ubuntu-amd64 bash -lc "COMMAND"
13+
```
14+
15+
Claude Code uses stateless one-shot execution — each `orb run` starts a fresh shell.
16+
Always use `bash -lc` to load `.bashrc` (PATH for zig, wasmtime, etc.).
17+
18+
## Sync Project
19+
20+
Rsync from Mac filesystem to VM-local storage for build performance:
21+
22+
```bash
23+
orb run -m my-ubuntu-amd64 bash -lc "
24+
rsync -a --delete \
25+
--exclude='.zig-cache' --exclude='zig-out' \
26+
'/Users/shota.508/ClojureWasm/' ~/ClojureWasm/
27+
"
28+
```
29+
30+
Run sync before each test session to pick up latest changes.
31+
32+
## Test Commands
33+
34+
All commands run inside the VM at `~/ClojureWasm/`:
35+
36+
```bash
37+
# Unit tests (IMPORTANT: --seed 0 required on Rosetta)
38+
orb run -m my-ubuntu-amd64 bash -lc "cd ~/ClojureWasm && zig build test --seed 0"
39+
40+
# Full test suite
41+
orb run -m my-ubuntu-amd64 bash -lc "cd ~/ClojureWasm && zig build test --seed 0 && \
42+
zig build -Doptimize=ReleaseSafe && \
43+
./zig-out/bin/cljw test"
44+
45+
# E2E tests
46+
orb run -m my-ubuntu-amd64 bash -lc "cd ~/ClojureWasm && bash test/e2e/run_e2e.sh"
47+
48+
# Benchmarks
49+
orb run -m my-ubuntu-amd64 bash -lc "cd ~/ClojureWasm && bash bench/run_bench.sh --quick"
50+
```
51+
52+
## Critical: --seed 0 Workaround
53+
54+
**`zig build test` crashes without `--seed 0` on Rosetta x86_64 emulation.**
55+
56+
Root cause: Zig 0.15.2 build runner's `shuffleWithIndex` (Random.zig:375) produces
57+
an index out of bounds under Rosetta's Random implementation. The `--seed 0` flag
58+
disables test shuffling, avoiding the crash entirely.
59+
60+
This is 100% reproducible without the flag and 100% fixed with it.
61+
62+
## Known Platform Differences
63+
64+
3 float-format tests fail on x86_64 due to platform-specific formatting differences
65+
(e.g., `-0.0` vs `0.0`, exponential notation). These are cosmetic, not bugs:
66+
67+
- `test.core-print: print double -0.0`
68+
- `test.core-print: print MIN_VALUE`
69+
- `test.core-print: print MAX_VALUE`
70+
71+
These are tracked and accepted — not regressions.
72+
73+
## Expected Results
74+
75+
| Suite | Expectation |
76+
| ---------- | ------------------------------------ |
77+
| Unit tests | 1338+ pass (3 known float failures) |
78+
| cljw test | 83 namespaces, no crashes |
79+
| E2E | all pass |
80+
| Benchmarks | no regression vs Mac baseline |

0 commit comments

Comments
 (0)