6l: port ET_DYN dynamic linking to the ww side
Ports cmd/6l/{dyn,dynout}.c into selfhost/cmd/6l/{dyn,dynout}.ww:
ET_DYN .so loading + PT_INTERP/PT_DYNAMIC ELF emission with .rela.plt,
.gnu.version_r, BIND_NOW. lsym grows dyn fields; pass.ww promotes
undefs to dyn; out.ww dispatches; main.ww takes -L/-l. The ww driver
forwards -L/-l to 6l_ww so 'ww_ww build snake.ww -L /usr/lib -l ncurses
-l c' runs without cc.
Test 996 pins byte-identical output to C-6l on snake.
'make bootstrap' gains a fourth stage with cmp ww3 == ww4, proving
ww3 is byte-stable when used as a compiler — not just a coincidental
two-stage equilibrium.
Four wwstage 6c cgen quirks surfaced and are documented in dynout.ww's
header (two-level field-write through a pointer field, (scalar, str)
tuple returns, def : str, ≤6 arg calling convention).
This commit is contained in:
39
Makefile
39
Makefile
@@ -150,7 +150,8 @@ $(BIN)/6a_ww: selfhost/cmd/6a/main.ww selfhost/cmd/6a/types.ww \
|
||||
# Built like 6a_ww. Needs -I selfhost/cmd/6l for the local sym/obj/pass/
|
||||
# out modules and -I selfhost/cmd/wwc to find `mem`.
|
||||
$(BIN)/6l_ww: selfhost/cmd/6l/main.ww selfhost/cmd/6l/sym.ww \
|
||||
selfhost/cmd/6l/obj.ww selfhost/cmd/6l/pass.ww \
|
||||
selfhost/cmd/6l/obj.ww selfhost/cmd/6l/dyn.ww \
|
||||
selfhost/cmd/6l/pass.ww selfhost/cmd/6l/dynout.ww \
|
||||
selfhost/cmd/6l/out.ww selfhost/cmd/wwc/mem.ww \
|
||||
$(BIN)/ww $(BIN)/6c $(BIN)/6a $(BIN)/6l \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
@@ -188,7 +189,8 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
|
||||
$(BIN)/test_6c $(BIN)/test_6a $(BIN)/test_6l $(BIN)/test_arch \
|
||||
$(BIN)/test_e2e $(BIN)/test_ffi $(BIN)/test_dyn $(BIN)/test_stdlib \
|
||||
$(BIN)/test_selfhost $(BIN)/test_6a_ww $(BIN)/test_6l_ww \
|
||||
$(BIN)/test_6c_ww $(BIN)/test_ww_ww $(BIN)/test_self_rebuild
|
||||
$(BIN)/test_6c_ww $(BIN)/test_ww_ww $(BIN)/test_self_rebuild \
|
||||
$(BIN)/test_dyn_ww
|
||||
|
||||
$(BIN)/test_smoke: test/wwc/000_smoke.c $(LIB)/libwwc.a | $(BIN)
|
||||
$(CC) $(CFLAGS) $(INCS) -o $@ $< -L$(LIB) -lwwc
|
||||
@@ -252,6 +254,10 @@ $(BIN)/test_self_rebuild: test/wwc/995_self_rebuild.c $(BIN)/ww_ww \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
$(BIN)/test_dyn_ww: test/wwc/996_dyn_ww.c $(BIN)/ww $(BIN)/6l $(BIN)/6l_ww \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
test: all $(TESTS)
|
||||
@WW=$(BIN)/ww BIN=$(BIN) sh test/run
|
||||
|
||||
@@ -264,17 +270,23 @@ clean:
|
||||
rm -rf $(OUT)
|
||||
|
||||
# ---- bootstrap (phase 10) ----------------------------------------------
|
||||
# Three-stage self-host: Cstage (these C tools) → ww1 → ww2 → ww3 with
|
||||
# cmp ww2 == ww3. Stage 1 is wwdump_ww (the ww-built frontend); stages
|
||||
# 2 and 3 assemble with 6a_ww and link with 6l_ww — every tool below
|
||||
# the driver is now in ww. The C `ww` driver still orchestrates the
|
||||
# pipeline (porting it is the remaining phase-10 work).
|
||||
# Four-stage self-host: Cstage (these C tools) → ww1 → ww2 → ww3 → ww4
|
||||
# with cmp ww2 == ww3 and cmp ww3 == ww4. Stage 1 is wwdump_ww (the
|
||||
# ww-built frontend); stages 2/3/4 assemble with 6a_ww and link with
|
||||
# 6l_ww — every tool below the driver is now in ww. The C `ww` driver
|
||||
# still orchestrates the pipeline (porting it is the remaining phase-10
|
||||
# work).
|
||||
#
|
||||
# Why a fourth stage? Stage 3 proves ww1 and ww2 (which differ in how
|
||||
# they were built) emit the same machine code. Stage 4 proves ww3 is
|
||||
# byte-stable when used as a compiler — i.e. the fixed point is truly
|
||||
# fixed, not merely a coincidental two-stage equilibrium.
|
||||
BS = $(OUT)/bootstrap
|
||||
bootstrap: all
|
||||
@echo "=== stage 0 (Cstage): C-built tools ==="
|
||||
@echo " $(BIN)/ww $(BIN)/6c $(BIN)/6a $(BIN)/6l"
|
||||
@echo
|
||||
@echo "=== stage 1: ww-built tools, used to drive stages 2 and 3 ==="
|
||||
@echo "=== stage 1: ww-built tools, used to drive stages 2/3/4 ==="
|
||||
@ls -l $(BIN)/wwdump_ww $(BIN)/6a_ww $(BIN)/6l_ww $(BIN)/ww_ww
|
||||
@rm -rf $(BS) && mkdir -p $(BS)
|
||||
@echo
|
||||
@@ -290,12 +302,21 @@ bootstrap: all
|
||||
@$(BIN)/6l_ww -o $(BS)/ww3 $(BS)/ww3.o $(LIB)/libwwrt.a
|
||||
@ls -l $(BS)/ww3
|
||||
@echo
|
||||
@echo "=== stage 4: ww4 = ww3 self-compiles main.combined.ww ==="
|
||||
@$(BS)/ww3 -c selfhost/cmd/wwdump/main.combined.ww > $(BS)/ww4.s
|
||||
@$(BIN)/6a_ww -o $(BS)/ww4.o $(BS)/ww4.s
|
||||
@$(BIN)/6l_ww -o $(BS)/ww4 $(BS)/ww4.o $(LIB)/libwwrt.a
|
||||
@ls -l $(BS)/ww4
|
||||
@echo
|
||||
@echo "=== fixed-point gates ==="
|
||||
@cmp $(BS)/ww2.s $(BS)/ww3.s && echo " ww2.s == ww3.s ✓"
|
||||
@cmp $(BS)/ww2.o $(BS)/ww3.o && echo " ww2.o == ww3.o ✓ (byte-identical .o)"
|
||||
@cmp $(BS)/ww2 $(BS)/ww3 && echo " ww2 == ww3 ✓ (byte-identical exe)"
|
||||
@cmp $(BS)/ww3.s $(BS)/ww4.s && echo " ww3.s == ww4.s ✓"
|
||||
@cmp $(BS)/ww3.o $(BS)/ww4.o && echo " ww3.o == ww4.o ✓ (byte-identical .o)"
|
||||
@cmp $(BS)/ww3 $(BS)/ww4 && echo " ww3 == ww4 ✓ (byte-identical exe, ww3 is byte-stable as a compiler)"
|
||||
@echo
|
||||
@echo "BOOTSTRAP OK: ww-cgen + 6a_ww + 6l_ww reach a fixed point."
|
||||
@echo "BOOTSTRAP OK: ww-cgen + 6a_ww + 6l_ww reach a fixed point that holds across two iterations."
|
||||
@echo
|
||||
@echo "Phase 10 remaining work:"
|
||||
@echo " - delete cmd/wwc/ cmd/6c/ cmd/6a/ cmd/6l/ cmd/ww/ in the final commit"
|
||||
|
||||
Reference in New Issue
Block a user