Commit f7d483d
P1: fix Zig FFI to build and match the Idris2 ABI (#33)
* Auto-install pinned Zig toolchain in setup + devcontainer
The Zig FFI bridge is half of the ABI-FFI standard, but nothing installed
Zig: .tool-versions only lists it (commented), setup.sh stops at `just`,
and the devcontainer's `postCreateCommand: just deps` referenced a `deps`
recipe that did not exist. Unlike the other toolchain pieces, Zig is not
distributed via GitHub releases, so it must come from ziglang.org.
Add scripts/install-zig.sh: an idempotent, fail-soft installer for the
pinned Zig 0.14.0 (arch/OS-aware, uses the system CA store the agent proxy
populates, never --insecure). If ziglang.org is not on the session's egress
allowlist the download 403s and the script exits 0 with an actionable
message, so it never blocks setup or a session.
Wire it in via the two paths the project already uses: a "Step 1b" in
setup.sh (where the template exposes that step), and a new `deps` Justfile
recipe backing the devcontainer postCreateCommand. Once ziglang.org is
allowlisted, future setups and dev containers install Zig automatically.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019xMKB3T4Vo5FYC7Czx3JSH
* P1: fix Zig FFI to build and match the Idris2 ABI
`zig test src/main.zig -lc` crashed with "free(): double free detected"
on the second test (create supervisor and worker).
Root cause: dual ownership of tree nodes. The handle's flat `nodes`
ArrayList owns every node created by otpiser_create_supervisor /
otpiser_create_worker, while otpiser_add_child also links a child into
its parent supervisor's `children` list. TreeNode.deinit then recursively
freed each child (child.deinit() + allocator.destroy(child)), so any node
that was added as a child was freed twice on otpiser_free: once via the
parent's recursive deinit and once via the handle's flat `nodes` sweep.
Fix: make `children` a non-owning reference list. TreeNode.deinit now
releases only its own `children` container and no longer frees the child
nodes. The handle's `nodes` list remains the single owner and frees every
node exactly once. This matches the alloyiser reference idiom (single,
flat ownership; handles are plain structs behind ?*T).
No exported C symbol names or Result-enum integer values were changed.
All 17 C:otpiser_* symbols in Foreign.idr keep their matching export fn,
and the Result enum still mirrors resultToInt (Ok=0 .. MalformedTree=6).
Verification:
- src/interface/ffi: `zig test src/main.zig -lc` -> all 7 tests pass, 0 errors/warnings
- src/interface/abi: `idris2 --build otpiser-abi.ipkg` -> exit 0
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019xMKB3T4Vo5FYC7Czx3JSH
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 5ee4413 commit f7d483d
1 file changed
Lines changed: 6 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
76 | | - | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
77 | 79 | | |
78 | 80 | | |
79 | 81 | | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
80 | 85 | | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | 86 | | |
86 | 87 | | |
87 | 88 | | |
| |||
0 commit comments