selfhost/cmd/wcc/cgenutil: collapse nullableptrtag onto tinfo.params (#50 phase 2, A.6.3f-b)
Phase 2 of A.6.3f, closing A.6.3 entirely (a/b/c/d/e/f-a/f-b all
landed). With #50 phase 1 (26724fe) populating TY_TAGGED.params,
nullableptrtag retires its AST-keyed predecessor: walk ti.params,
strip TY_NAMED via .under on each variant, return idx of first
TY_PTR.
Mirrors cstage cmd/w6c/cgen.c:404-416 line-for-line. Source-order
semantics preserved by phase 1's append-tail head/tail
construction (head = first n.list variant). For a `(*T | void)`,
*T-first → returns 0; void-first → walks past void (vt.kind==
TY_VOID, no match), *T at idx 1 → returns 1.
Two paths the new tinfo-keyed body handles that the AST walk
missed (cstage parity, dead-in-bootstrap today, parallel to #49
TY_TUPLE / #51b typed-float corrections):
- Aliased *T variant: `type ip = *int; let x: (ip | void);` —
cstage cgen.c:415 strips TY_NAMED via .under; new wwstage
body mirrors. Bootstrap has zero aliased-ptr-variant
callsites today (`grep "^type [a-z]+ = \*"` yields only an
out-of-union test/uses.ww case).
- void-first ordering: cstage walks past TY_VOID and finds *T
at idx 1. Same in wwstage. No test/wcc fixture exercises
void-first today.
Outer-type TY_NAMED strip (cstage cgen.c:409 `if t->kind==TY_NAMED
t = t->under`) intentionally skipped: tinfofornode for N_TNAME
already resolves the alias and returns the underlying tinfo
unwrapped — `typenamed` is declared at lib/ww/typ.ww:238 but has
zero producers in selfhost today. The strip would be a no-op
under current invariants. Tracked as part of #13 (TTAGGED
normalization parity) for when wwstage starts producing
TY_NAMED.
Net +30 LOC across cgenutil.ww + two .combined.ww bundler regens
(new function body is ~14 lines vs ~4; new WHY comment shorter
than the pre-graduation note's 7).
Byte-identity (994/995) is the gate; full make test green at
133/133 confirms.
This commit is contained in:
@@ -12588,19 +12588,29 @@ export fn isnullabletype(t: *node) bool = {
|
||||
};
|
||||
|
||||
// nullableptrtag — 0-based index of the *T variant in a nullable
|
||||
// union. The void variant takes the other slot (0 or 1). AST-keyed
|
||||
// for now: tinfofornode doesn't populate TY_TAGGED.params yet
|
||||
// (check.ww:1287-1337 sets size/align/nullable but not the variant
|
||||
// chain), so the tinfo equivalent of cstage cgen.c:405
|
||||
// `nullable_ptr_tag` can't read params today. Graduates to a pure
|
||||
// tinfo helper in A.6.3f (#50) alongside the variant-index work and
|
||||
// the tparam-population glue.
|
||||
// union. Mirror of cstage cgen.c:404-416 `nullable_ptr_tag`: linear
|
||||
// scan ti.params, strip TY_NAMED on each variant, return idx of first
|
||||
// TY_PTR. Phase 1 (26724fe) populated the chain in tinfofornode's
|
||||
// TTAGGED arm so this walk could retire the AST-keyed predecessor.
|
||||
export fn nullableptrtag(t: *node) i32 = {
|
||||
if (t == nil) { return 0; };
|
||||
if (t.kind != nkind.N_TTAGGED) { return 0; };
|
||||
let a: *node = t.list;
|
||||
if (a != nil) { if (a.kind == nkind.N_TPTR) { return 0; }; };
|
||||
return 1;
|
||||
let ti: *tinfo = t.type_: *tinfo;
|
||||
if (ti == nil) { return 0; };
|
||||
if (ti.kind != tykind.TY_TAGGED) { return 0; };
|
||||
let p: *tparam = ti.params;
|
||||
let i: i32 = 0;
|
||||
for (p != nil) {
|
||||
let vt: *tinfo = p.type_;
|
||||
if (vt != nil) {
|
||||
if (vt.kind == tykind.TY_NAMED) { vt = vt.under; };
|
||||
if (vt != nil) {
|
||||
if (vt.kind == tykind.TY_PTR) { return i; };
|
||||
};
|
||||
};
|
||||
p = p.tnext;
|
||||
i += 1;
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
|
||||
// voidvariantindex — find the 0-based index of the `void` variant in a
|
||||
|
||||
@@ -2204,19 +2204,29 @@ export fn isnullabletype(t: *node) bool = {
|
||||
};
|
||||
|
||||
// nullableptrtag — 0-based index of the *T variant in a nullable
|
||||
// union. The void variant takes the other slot (0 or 1). AST-keyed
|
||||
// for now: tinfofornode doesn't populate TY_TAGGED.params yet
|
||||
// (check.ww:1287-1337 sets size/align/nullable but not the variant
|
||||
// chain), so the tinfo equivalent of cstage cgen.c:405
|
||||
// `nullable_ptr_tag` can't read params today. Graduates to a pure
|
||||
// tinfo helper in A.6.3f (#50) alongside the variant-index work and
|
||||
// the tparam-population glue.
|
||||
// union. Mirror of cstage cgen.c:404-416 `nullable_ptr_tag`: linear
|
||||
// scan ti.params, strip TY_NAMED on each variant, return idx of first
|
||||
// TY_PTR. Phase 1 (26724fe) populated the chain in tinfofornode's
|
||||
// TTAGGED arm so this walk could retire the AST-keyed predecessor.
|
||||
export fn nullableptrtag(t: *node) i32 = {
|
||||
if (t == nil) { return 0; };
|
||||
if (t.kind != nkind.N_TTAGGED) { return 0; };
|
||||
let a: *node = t.list;
|
||||
if (a != nil) { if (a.kind == nkind.N_TPTR) { return 0; }; };
|
||||
return 1;
|
||||
let ti: *tinfo = t.type_: *tinfo;
|
||||
if (ti == nil) { return 0; };
|
||||
if (ti.kind != tykind.TY_TAGGED) { return 0; };
|
||||
let p: *tparam = ti.params;
|
||||
let i: i32 = 0;
|
||||
for (p != nil) {
|
||||
let vt: *tinfo = p.type_;
|
||||
if (vt != nil) {
|
||||
if (vt.kind == tykind.TY_NAMED) { vt = vt.under; };
|
||||
if (vt != nil) {
|
||||
if (vt.kind == tykind.TY_PTR) { return i; };
|
||||
};
|
||||
};
|
||||
p = p.tnext;
|
||||
i += 1;
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
|
||||
// voidvariantindex — find the 0-based index of the `void` variant in a
|
||||
|
||||
@@ -12588,19 +12588,29 @@ export fn isnullabletype(t: *node) bool = {
|
||||
};
|
||||
|
||||
// nullableptrtag — 0-based index of the *T variant in a nullable
|
||||
// union. The void variant takes the other slot (0 or 1). AST-keyed
|
||||
// for now: tinfofornode doesn't populate TY_TAGGED.params yet
|
||||
// (check.ww:1287-1337 sets size/align/nullable but not the variant
|
||||
// chain), so the tinfo equivalent of cstage cgen.c:405
|
||||
// `nullable_ptr_tag` can't read params today. Graduates to a pure
|
||||
// tinfo helper in A.6.3f (#50) alongside the variant-index work and
|
||||
// the tparam-population glue.
|
||||
// union. Mirror of cstage cgen.c:404-416 `nullable_ptr_tag`: linear
|
||||
// scan ti.params, strip TY_NAMED on each variant, return idx of first
|
||||
// TY_PTR. Phase 1 (26724fe) populated the chain in tinfofornode's
|
||||
// TTAGGED arm so this walk could retire the AST-keyed predecessor.
|
||||
export fn nullableptrtag(t: *node) i32 = {
|
||||
if (t == nil) { return 0; };
|
||||
if (t.kind != nkind.N_TTAGGED) { return 0; };
|
||||
let a: *node = t.list;
|
||||
if (a != nil) { if (a.kind == nkind.N_TPTR) { return 0; }; };
|
||||
return 1;
|
||||
let ti: *tinfo = t.type_: *tinfo;
|
||||
if (ti == nil) { return 0; };
|
||||
if (ti.kind != tykind.TY_TAGGED) { return 0; };
|
||||
let p: *tparam = ti.params;
|
||||
let i: i32 = 0;
|
||||
for (p != nil) {
|
||||
let vt: *tinfo = p.type_;
|
||||
if (vt != nil) {
|
||||
if (vt.kind == tykind.TY_NAMED) { vt = vt.under; };
|
||||
if (vt != nil) {
|
||||
if (vt.kind == tykind.TY_PTR) { return i; };
|
||||
};
|
||||
};
|
||||
p = p.tnext;
|
||||
i += 1;
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
|
||||
// voidvariantindex — find the 0-based index of the `void` variant in a
|
||||
|
||||
Reference in New Issue
Block a user