aboutsummaryrefslogtreecommitdiff
path: root/src/boot/boot.sh
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-15 14:10:03 +0330
committerGravatar zinc <zinc@downsta.ir> 2026-10-15 14:10:03 +0330
commita3b72f0c6d02f96606c200cde04735fd57151805 (patch)
tree7ed42ed6b38588750b31db23c6274cc9fdf8c175 /src/boot/boot.sh
parentmerge work/borrow: borrow returns before definition, borrows clause, borrow m... (diff)
boot: build the compiler from a pinned wasm seed (seed/zc.wasm, WASI) under wasmtime or node, proven by the fixpoint; seed/MANIFEST hashes; make seed; legacy c bootstrap kept as make genome-c
Diffstat (limited to 'src/boot/boot.sh')
-rwxr-xr-xsrc/boot/boot.sh50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/boot/boot.sh b/src/boot/boot.sh
new file mode 100755
index 0000000..c7eb2ed
--- /dev/null
+++ b/src/boot/boot.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+# bootstraps the compiler from the pinned wasm seed. usage: src/boot/boot.sh OUTDIR
+# checks seed/zc.wasm against seed/MANIFEST, then under a wasm runtime (wasmtime, or
+# node) the seed compiles the compiler sources to g1 and g1 compiles them to g2; when
+# they differ g2 compiles them to g3 and g2 = g3 is required (the fixpoint). the result is
+# OUTDIR/genome.bin. the seed is proven by the fixpoint, not trusted. nothing here
+# uses the c core.
+set -e
+cd "$(dirname "$0")/../.."
+OUT=${1:?outdir}; SEED=${SEED:-seed/zc.wasm}; MAN=${MAN:-seed/MANIFEST}
+mkdir -p "$OUT"
+sha() { if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | cut -d' ' -f1; else shasum -a 256 "$1" | cut -d' ' -f1; fi; }
+want=$(sed -n 's/^seed-sha256 //p' "$MAN"); got=$(sha "$SEED")
+if [ -z "$BOOT_NOCHECK" ] && [ "$want" != "$got" ]; then
+ echo "boot: $SEED does not match $MAN" >&2
+ echo "boot: manifest sha256 $want" >&2
+ echo "boot: file sha256 $got" >&2
+ echo "boot: the seed was changed or damaged; restore it from git, or run make seed to rebuild it on purpose" >&2
+ exit 1
+fi
+if [ -n "$WASM_RUNTIME" ]; then RT=$WASM_RUNTIME
+elif command -v wasmtime >/dev/null 2>&1; then RT=wasmtime
+elif command -v node >/dev/null 2>&1 && node -e 'process.exit(+process.versions.node.split(".")[0] < 18 ? 1 : 0)' 2>/dev/null; then RT=node
+else
+ echo "boot: no WebAssembly runtime found. the compiler is built from seed/zc.wasm under one of:" >&2
+ echo "boot: node 18 or later (macOS: brew install node; debian/ubuntu: apt install nodejs)" >&2
+ echo "boot: wasmtime (macOS: brew install wasmtime; elsewhere: curl https://wasmtime.dev/install.sh -sSf | bash)" >&2
+ exit 1
+fi
+run() { case "$RT" in node) node src/boot/run.mjs "$1" ;; wasmtime) wasmtime run --dir=. "$1" ;; *) $RT "$1" ;; esac; }
+le64() { n=$1 i=0; while [ $i -lt 8 ]; do printf "\\$(printf %03o $(( (n >> (8 * i)) & 255 )))"; i=$((i + 1)); done; }
+SRC="src/runtime/rt.zc src/core/core.zc $(sed 's#^#src/compiler/#' src/compiler/parts | tr '\n' ' ')"
+input() { cat src/tools/build.zc; printf '`'; cat $SRC; }
+stage() { # stage IMAGE OUT: IMAGE empty means the seed's own genome
+ { if [ -n "$1" ]; then printf 'ZCIMAGE\n'; le64 $(wc -c < "$1"); cat "$1"; fi; input; } | run "$SEED" > "$2.tmp"
+ mv "$2.tmp" "$2"
+}
+echo "boot: seed $got ok, runtime $RT"
+stage "" "$OUT/g1.bin"; echo "boot: g1 (seed -> sources): $(sha "$OUT/g1.bin")"
+[ "${BOOT_STAGES:-}" = 1 ] && exit 0
+img=$(sed -n 's/^image-sha256 //p' "$MAN")
+[ -n "$img" ] && { [ "$img" = "$(sha "$OUT/g1.bin")" ] && echo "boot: g1 is the image the manifest records" || echo "boot: g1 differs from the manifest's image (the sources changed since the seed was made)"; }
+stage "$OUT/g1.bin" "$OUT/g2.bin"; echo "boot: g2 (g1 -> sources): $(sha "$OUT/g2.bin")"
+if cmp -s "$OUT/g1.bin" "$OUT/g2.bin"; then
+ # g1 rebuilt itself unchanged, so it is the fixpoint: a third stage would only repeat it
+ cp "$OUT/g2.bin" "$OUT/genome.bin"; echo "boot: fixpoint (g1 = g2)"; exit 0
+fi
+stage "$OUT/g2.bin" "$OUT/g3.bin"; echo "boot: g3 (g2 -> sources): $(sha "$OUT/g3.bin")"
+cmp "$OUT/g2.bin" "$OUT/g3.bin" || { echo "boot: no fixpoint: g2 and g3 differ" >&2; exit 1; }
+cp "$OUT/g2.bin" "$OUT/genome.bin"; echo "boot: fixpoint (g2 = g3)"