From 8ccda588c69be8ae0264ac0e854ecc8b75f85c56 Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Sat, 23 May 2026 15:41:31 +0900 Subject: [PATCH] selfhost/cmd/wcc/cgenutil: trim rhstaggedabicall N_DOT onto n.type_ (#58, A.6.3i-phase-2) rhstaggedabicall's N_DOT arm re-derived the field type via dotfieldtnode (a base-ident-only structlookup walk) then asked istaggedtype. The checker now stamps the field's resolved type on the N_DOT node itself (check.ww struct-field arm), so read src.type_ directly. typeistagged(nil) is false, preserving the old ft==nil bail. Polarity DOWN per rule 10: cstage's gate was already wide. cg_widen_tagged_ store reads src->type inline, NAMED-resolved, then tests TY_TAGGED (cmd/w6c/cgen.c:1302-1305) -- no standalone helper. Pre-trim wwstage's gate was NARROWER (dotfieldtnode required base==N_IDENT, firing only for `ident.field`); reading src.type_ also fires for chained-dot bases (`a.b.c`) since the checker stamps N_DOT.type_ at any depth. This aligns wwstage UP to cstage's existing coverage. Byte-id 990-997 green confirms the widened shape does not occur in bootstrap sources -- byte-id-neutral. Drops one dotfieldtnode caller; the *node-returning callers (typenodeprimresolved, indexvaluetnode, matchscrutt) stay until their consumers migrate to *tinfo (the closing dotfield* deletion follows once none need *node). First clean slice of that consumer migration; same g/h-style stamp read as #55/#56. Known pre-existing gap (filed, not introduced here): neither stage's chained-DOT read path has a tagged-union leaf branch, so a chained-dot tagged ABI source would store stale DX/CX/R8. Symmetric across stages (byte-id stays green); the retained `cgdot loads AX=tag, DX=word0, ...` comment is accurate only for ident.field bases. make test 133/133 (quiescent tree, byte-id 990-997 green). --- selfhost/cmd/w6c/main.combined.ww | 11 ++++++----- selfhost/cmd/wcc/cgenutil.ww | 11 ++++++----- selfhost/cmd/wwdump/main.combined.ww | 11 ++++++----- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/selfhost/cmd/w6c/main.combined.ww b/selfhost/cmd/w6c/main.combined.ww index dae51232..b2e28622 100644 --- a/selfhost/cmd/w6c/main.combined.ww +++ b/selfhost/cmd/w6c/main.combined.ww @@ -12952,12 +12952,13 @@ fn rhstaggedabicall(c: *cgen, src: *node) bool = { }; // N_DOT of a tagged-typed struct field — cgdot loads // AX=tag, DX=word0, CX=word1[, R8=word2], so downstream - // spill matches the call/index shapes. + // spill matches the call/index shapes. #58 A.6.3i-phase-2: + // read the checker-stamped n.type_ (check.ww N_DOT struct-field + // stamp) instead of re-deriving via dotfieldtnode — matches + // cstage cg_widen_tagged_store reading src->type directly + // (cmd/w6c/cgen.c:1302-1305). typeistagged(nil) is false. if (src.kind == nkind.N_DOT) { - let ft: *node = dotfieldtnode(c, src); - if (ft != nil) { - if (istaggedtype(c, ft)) { return true; }; - }; + if (typeistagged(src.type_: *tinfo)) { return true; }; }; return false; }; diff --git a/selfhost/cmd/wcc/cgenutil.ww b/selfhost/cmd/wcc/cgenutil.ww index 1e0f7e75..debc152d 100644 --- a/selfhost/cmd/wcc/cgenutil.ww +++ b/selfhost/cmd/wcc/cgenutil.ww @@ -2511,12 +2511,13 @@ fn rhstaggedabicall(c: *cgen, src: *node) bool = { }; // N_DOT of a tagged-typed struct field — cgdot loads // AX=tag, DX=word0, CX=word1[, R8=word2], so downstream - // spill matches the call/index shapes. + // spill matches the call/index shapes. #58 A.6.3i-phase-2: + // read the checker-stamped n.type_ (check.ww N_DOT struct-field + // stamp) instead of re-deriving via dotfieldtnode — matches + // cstage cg_widen_tagged_store reading src->type directly + // (cmd/w6c/cgen.c:1302-1305). typeistagged(nil) is false. if (src.kind == nkind.N_DOT) { - let ft: *node = dotfieldtnode(c, src); - if (ft != nil) { - if (istaggedtype(c, ft)) { return true; }; - }; + if (typeistagged(src.type_: *tinfo)) { return true; }; }; return false; }; diff --git a/selfhost/cmd/wwdump/main.combined.ww b/selfhost/cmd/wwdump/main.combined.ww index d76f17e9..f433b852 100644 --- a/selfhost/cmd/wwdump/main.combined.ww +++ b/selfhost/cmd/wwdump/main.combined.ww @@ -12952,12 +12952,13 @@ fn rhstaggedabicall(c: *cgen, src: *node) bool = { }; // N_DOT of a tagged-typed struct field — cgdot loads // AX=tag, DX=word0, CX=word1[, R8=word2], so downstream - // spill matches the call/index shapes. + // spill matches the call/index shapes. #58 A.6.3i-phase-2: + // read the checker-stamped n.type_ (check.ww N_DOT struct-field + // stamp) instead of re-deriving via dotfieldtnode — matches + // cstage cg_widen_tagged_store reading src->type directly + // (cmd/w6c/cgen.c:1302-1305). typeistagged(nil) is false. if (src.kind == nkind.N_DOT) { - let ft: *node = dotfieldtnode(c, src); - if (ft != nil) { - if (istaggedtype(c, ft)) { return true; }; - }; + if (typeistagged(src.type_: *tinfo)) { return true; }; }; return false; };