Commit Graph

2 Commits

Author SHA1 Message Date
b3d6bc4420 w6c_ww: cgtypetest nullable is discriminates pointer-vs-null (#45 review)
The #45 non-ident arm tag-compared the word in AX against the variant
index; for the nullable (*T | void) fold that word IS the pointer —
`h.m is *t` on a non-null pointer answered FALSE (silent cs≠ww,
cstage correct: CMPQ $0 + JE/JNE polarity per cgen.c N_TYPETEST).
The ident path had the same missing nullable arm since before #45
(pre-existing at master, unexercised in the bootstrap corpus). One
nullable branch at the shared compare choke-point closes both halves:
want stays RAW (cstage tests tag == ptr_tag unclamped, a no-match -1
takes the void polarity). Rows nullable_dot_field + nullable_ident
pin both polarities and both states in 927; whole-corpus control
(5 selfhost combined.ww, master-vs-branch w6c + w6c_ww) byte-id.
2026-06-04 04:54:43 +09:00
b2e4388792 w6c_ww: cgtypetest resolves non-ident scrutinees, no-spill tag compare (fix #45)
Pre-#45 wwstage `is` resolved only N_IDENT scrutinees; xs[i] / p.field
/ call() fell through with scrutoff=0 + scrutt=nil and emitted
MOVQ (BP),AX; CMPQ $0,AX — tag read off the saved-BP word, variant
clamped to 0 (SILENT cs≠ww; cstage cgexprs the scrutinee and compares
the real tag in AX). The non-ident arm now cgexprs the scrutinee (tag
lands in AX) and compares directly. NOT the `as` twin's @asrt_spill
(#200): cmp against cstage shows N_TYPETEST never spills — `as`
re-reads payload words after the check, `is` consumes only the tag,
and a spill would break rule-10 byte-id. Variant index resolves from
the STAMPED scrutinee type via flatvariantidx/flatslicevariantidx
(matchscrutt's node walk can't carry N_DOT through cgtypetest's
N_TTAGGED gate). Ident path untouched (control row + hand-cmp vs
pre-#45 w6c_ww). wwstage-only source change; cs==ww byte-id pinned
per row in 927_is_nonident_run.
2026-06-04 04:40:54 +09:00