wcc: struct-composite let/def DATA emit via SSoT helper (#129 A.2)

Extract emit_struct_data + emit_struct_lit_bytes helpers (both stages,
mirrored) for module-level let/def with N_STRUCTLIT initializer. Walks
Tfield linked-list in declaration order, zero-fills padding via per-
field offset (rule 13, no hardcoded sizes), dispatches per field kind:
integer via fold_int_literal, float via inline bitcast + sign-XOR byte-
loop (A.1 shape, no INT64_MIN materialised — sibling #144), nested
struct via recursion (#145 inner-field-name-leak gates the test row).
Out-of-scope field kinds (str/slice/ptr/array) fatal loud per rule 7.

LOAD-side widened symmetric to A.1 precedent: cstage cgexpr N_DOT
direct-struct-ident + chained-N_DOT widened via new DefStruct registry
(def_isstructdef populated in let_collect); wwstage cgdot direct-struct-
global falls through to defvarstructinfo on letvarstructinfo nil
(defent.dtnode field added, populated in collectdefs). Both stages
materialise struct-def via LEAQ name(SB) same as struct-let.

Pre-existing cstage scalar 8B short-circuit at emit_lets caused silent
fold-fail-continue on 8B struct lits (`struct{i32,i32}`); gate now
excludes let_isstruct so 8B struct lits route through emit_struct_data.
Wwstage's `!issg` gate was already correct; symmetric ordering restored.

Closes (all bootstrap-NEUTRAL pre-impl; γ-cleanup #40 first consumer):
- emit_lets `is_struct continue` skip → struct lets emitted no DATA
- emit_defs no struct arm → struct defs emitted no DATA
- cstage cgexpr N_DOT for struct-def emitted MOVSXD (BP), AX (broken
  stack-frame read)
- cstage emit_lets sz==8 short-circuit silently skipped 8B struct lits

Test 918 (7 rows: let_int_struct / def_int_struct / let_float_field /
def_float_field / let_empty_struct / let_int_struct_8b / let_norhs_
struct_regression) registered. Make test: 181/181 incl. 990-997 byte-id
+ combined_ww_fresh.

Followups filed:
- #145 (task #41) — nested struct-lit inner field-name leaks as extern
- #42 — wwstage dotchainresolve missing defvarstructinfo lookup (A.2-
  scope-clean today; surfaces post-#145 nested-struct shapes)
- A.3 (task #39) — array static-init audit (parks shape-4 array-in-struct)
- γ-cleanup (task #40) — lib/math const-floatinfo re-fold, blocked-by A.2
This commit is contained in:
2026-05-27 05:04:05 +09:00
parent 1f8fcdc0ee
commit 0ed0b3933c
7 changed files with 1155 additions and 14 deletions

View File

@@ -340,6 +340,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
$(BIN)/test_arr_module_index_run \
$(BIN)/test_arr_float_call_index_run \
$(BIN)/test_def_float_lit_run \
$(BIN)/test_struct_composite_init_run \
$(BIN)/test_f64cgen_run \
$(BIN)/test_f64crossmod_run \
$(BIN)/test_tuprecv_run \
@@ -1153,6 +1154,11 @@ $(BIN)/test_def_float_lit_run: test/wcc/917_def_float_lit_run.c \
$(LIB)/libwwrt.a | $(BIN)
$(CC) $(CFLAGS) -o $@ $<
$(BIN)/test_struct_composite_init_run: test/wcc/918_struct_composite_init_run.c \
$(BIN)/ww $(BIN)/w6c $(BIN)/w6c_ww $(BIN)/w6a $(BIN)/w6l \
$(LIB)/libwwrt.a | $(BIN)
$(CC) $(CFLAGS) -o $@ $<
$(BIN)/test_f64cgen_run: test/wcc/951_f64cgen_run.c $(BIN)/ww $(BIN)/w6c \
$(BIN)/w6a $(BIN)/w6l $(LIB)/libwwrt.a | $(BIN)
$(CC) $(CFLAGS) -o $@ $<