wcc/ww: emit correct (tag,payload) for a tagged value in static-init (#19)
A tagged-union value nested in module-level array/struct static-init mis-emitted in both stages: the lit-bytes emitters had no TY_TAGGED arm, so a tagged element/field fell to the int path and the payload landed in the TAG word -- match then read the wrong variant. The zero-placeholder idiom (today the only way to declare a tagged global: zero-init in static, write at runtime) was correct only by accident (int-variant zero folds to (0,0), which equals the right (tag0,0)). Extract a raw-byte core emittaggedbytes/emit_tagged_bytes -- variant tag@+0, int payload@+8, zero-pad to the slot size; no directive, no offset, no reloc -- and refactor the scalar tagged emitter to delegate to it (byte-id-neutral). Add a TY_TAGGED member branch to the array and struct lit-bytes emitters (both stages) that calls the core at the existing full-slot stride, before the int fallthrough. Zero stays (0,0) byte-identical; a non-zero element/field now emits (tag,payload) correctly. A wide (str/slice) or struct/>8B payload nested in an aggregate needs reloc-at-member-offset machinery the aggregate byte-emitters don't have, so it is loud-rejected (rule 7), deferred to #30; the existing slice-of-tagged static-init reject is unchanged. Regenerates the w6c and wwdump combined.ww. Table-driven 843 test: non-zero array/struct (pre-fix returned the wrong variant), the non-tag-0 bool-variant edge, byte-id-neutral zero-placeholder rows, and wide-payload reject rows; each run row also pins cs-vs-ww asm.
This commit is contained in:
7
Makefile
7
Makefile
@@ -247,6 +247,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
|
||||
$(BIN)/test_arr_strslice_elem \
|
||||
$(BIN)/test_arr_tagged_elem \
|
||||
$(BIN)/test_dup_main_reject \
|
||||
$(BIN)/test_tagged_staticinit \
|
||||
$(BIN)/test_arr_infer_len \
|
||||
$(BIN)/test_arr_cap_reject \
|
||||
$(BIN)/test_tagged_subset_reject \
|
||||
@@ -1438,6 +1439,12 @@ $(BIN)/test_dup_main_reject: test/wcc/842_dup_main_reject.c $(BIN)/ww \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
$(BIN)/test_tagged_staticinit: test/wcc/843_tagged_staticinit.c $(BIN)/ww \
|
||||
$(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
||||
$(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
$(BIN)/test_slice_str_global_zero: test/wcc/686_slice_str_global_zero.c $(BIN)/ww \
|
||||
$(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
||||
$(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \
|
||||
|
||||
Reference in New Issue
Block a user