selfhost/cmd/wcc: variadic param N_TSLICE wrap at installparams (cascade Commit 3, #25/#41)
installparams normalises `T...` p.lhs to []T so N_IDENT lookups
(s.decl.lhs) and cgen's variadic-slot synthesis see the effective
slice — mirrors cstage check.c:455 `tp->type = type_slice(c->a, pt)`
and harec check_func_type. cgendecl/cgenexpr drop the on-the-fly
slicewrap and consume p.lhs directly; cgenexpr cgcall peels the
N_TSLICE wrap when reading the element predicates / esz (Ken's
gate: cstage cgen.c:4352 `vsu->kind == TY_SLICE`), and passes
`velem` — not the wrap — into cgwidentaggedstore (cstage cgen.c
:4382). Closes the 22 N_DOT + 9 N_INDEX fires from #36 with the
cascade absorbed by e662156 (#39 arm-6 recursion). Class B "case:
not a variant of scrutinee" did NOT fire post-#39, so Commit 2
(#40 tagged_select_subtype) was not needed.
This commit is contained in:
@@ -9690,6 +9690,20 @@ fn installparams(c: *checker, params: *node) void = {
|
||||
let p: *node = params;
|
||||
for (p != nil) {
|
||||
if (p.kind == nkind.N_PARAM) {
|
||||
// Hare-style variadic `T...`: normalize p.lhs to []T so
|
||||
// downstream consumers (N_IDENT exprtype lookups via
|
||||
// s.decl.lhs, cgen's variadic-slot synthesis) see the
|
||||
// effective slice type. Mirrors cstage check.c:455
|
||||
// `tp->type = type_slice(c->a, pt)` and harec
|
||||
// check_func_type. Surface-fidelity preserved: wwdump
|
||||
// -a runs parser only and never reaches this mutation.
|
||||
if (p.op == tkind.TK_ELLIPSIS) {
|
||||
if (p.lhs != nil && p.lhs.kind != nkind.N_TSLICE) {
|
||||
let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0);
|
||||
sl.lhs = p.lhs;
|
||||
p.lhs = sl;
|
||||
};
|
||||
};
|
||||
let nm: str = p.str;
|
||||
if (nm.len > 0) {
|
||||
checkmoduleshadow(c, nm, "param");
|
||||
@@ -17127,29 +17141,42 @@ fn cgcall(c: *cgen, n: *node) void = {
|
||||
// scalars to 8, mismatching the stride at the
|
||||
// callee read site — runtime miscompile in
|
||||
// `(rune...)` callees per #36.
|
||||
// check.ww installparams promotes varp.lhs to
|
||||
// []T (mirrors cstage check.c:455 tp->type
|
||||
// wrap). Element predicates / esz read varp.lhs
|
||||
// .lhs; Ken's gate: only deref when the wrap
|
||||
// shape is confirmed N_TSLICE (mirrors cstage
|
||||
// cgen.c:4352 `vsu->kind == TY_SLICE` guard).
|
||||
let velem: *node = varp.lhs;
|
||||
if (varp.lhs != nil
|
||||
&& varp.lhs.kind == nkind.N_TSLICE) {
|
||||
velem = varp.lhs.lhs;
|
||||
};
|
||||
let esz: i32 = 8;
|
||||
if (varp.lhs != nil) {
|
||||
if (varp.lhs.kind == nkind.N_TNAME) {
|
||||
let ps: i32 = primsize(varp.lhs.str);
|
||||
if (velem != nil) {
|
||||
if (velem.kind == nkind.N_TNAME) {
|
||||
let ps: i32 = primsize(velem.str);
|
||||
if (ps > 0) { esz = ps; }
|
||||
else { esz = slotsize(c, varp.lhs); };
|
||||
else { esz = slotsize(c, velem); };
|
||||
} else {
|
||||
esz = slotsize(c, varp.lhs);
|
||||
esz = slotsize(c, velem);
|
||||
};
|
||||
};
|
||||
if (esz < 1) { esz = 1; };
|
||||
let velemtagged: bool = istaggedtype(c, varp.lhs);
|
||||
let velemstr: bool = isstrtype(c, varp.lhs);
|
||||
let velemslice: bool = isslicetype(c, varp.lhs);
|
||||
let velemtagged: bool = istaggedtype(c, velem);
|
||||
let velemstr: bool = isstrtype(c, velem);
|
||||
let velemslice: bool = isslicetype(c, velem);
|
||||
let doff: i32 = 0;
|
||||
if (nvar > 0) {
|
||||
doff = localadd(c, dname, nvar * esz, nil);
|
||||
};
|
||||
// #60: vararg gather builds a {ptr,len,cap} slice
|
||||
// descriptor — route through tyslicesize so #34's
|
||||
// slice-header bump propagates here.
|
||||
// slice-header bump propagates here. varp.lhs is
|
||||
// already the []T wrap from installparams, so we
|
||||
// consume it directly (re-slicewrap → [][]T).
|
||||
let soff: i32 = localadd(c, sname, tyslicesize(): i32,
|
||||
slicewrap(c, varp.lhs));
|
||||
varp.lhs);
|
||||
let aa2: *node = n.list;
|
||||
let kk3: i32 = 0;
|
||||
for (kk3 < nfixed_v) {
|
||||
@@ -17169,7 +17196,10 @@ fn cgcall(c: *cgen, n: *node) void = {
|
||||
for (aa2 != nil) {
|
||||
let slot: i32 = doff + j * esz;
|
||||
if (velemtagged) {
|
||||
cgwidentaggedstore(c, varp.lhs,
|
||||
// dst is the per-element tagged type;
|
||||
// pass velem (cstage cgen.c:4382 passes
|
||||
// velem, not the slice wrap vsu).
|
||||
cgwidentaggedstore(c, velem,
|
||||
aa2, "BP", slot, esz);
|
||||
} else { if (velemstr) {
|
||||
cgexpr(c, aa2);
|
||||
@@ -21541,11 +21571,13 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
||||
if (p.kind == nkind.N_PARAM) {
|
||||
let nm: str = p.str;
|
||||
// Hare-style variadic `T...`: callee receives a []T
|
||||
// slice (3 register words / 24B). Mirror the slice-
|
||||
// param spill below but use a synthesised TSLICE
|
||||
// tnode so body references see the slot as a slice.
|
||||
// slice (3 register words / 24B). p.lhs is already
|
||||
// the []T wrap installed by check.ww installparams
|
||||
// (mirrors cstage check.c:455 tp->type promotion), so
|
||||
// we consume it directly — re-wrapping via slicewrap
|
||||
// would yield [][]T.
|
||||
if (p.op == tkind.TK_ELLIPSIS) {
|
||||
let tn: *node = slicewrap(c, p.lhs);
|
||||
let tn: *node = p.lhs;
|
||||
if (idx + 3 <= 6) {
|
||||
let off: i32 = localadd(c, nm, tyslicesize(): i32, tn);
|
||||
emitline("\tMOVQ\t");
|
||||
|
||||
@@ -39,11 +39,13 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
||||
if (p.kind == nkind.N_PARAM) {
|
||||
let nm: str = p.str;
|
||||
// Hare-style variadic `T...`: callee receives a []T
|
||||
// slice (3 register words / 24B). Mirror the slice-
|
||||
// param spill below but use a synthesised TSLICE
|
||||
// tnode so body references see the slot as a slice.
|
||||
// slice (3 register words / 24B). p.lhs is already
|
||||
// the []T wrap installed by check.ww installparams
|
||||
// (mirrors cstage check.c:455 tp->type promotion), so
|
||||
// we consume it directly — re-wrapping via slicewrap
|
||||
// would yield [][]T.
|
||||
if (p.op == tkind.TK_ELLIPSIS) {
|
||||
let tn: *node = slicewrap(c, p.lhs);
|
||||
let tn: *node = p.lhs;
|
||||
if (idx + 3 <= 6) {
|
||||
let off: i32 = localadd(c, nm, tyslicesize(): i32, tn);
|
||||
emitline("\tMOVQ\t");
|
||||
|
||||
@@ -3078,29 +3078,42 @@ fn cgcall(c: *cgen, n: *node) void = {
|
||||
// scalars to 8, mismatching the stride at the
|
||||
// callee read site — runtime miscompile in
|
||||
// `(rune...)` callees per #36.
|
||||
// check.ww installparams promotes varp.lhs to
|
||||
// []T (mirrors cstage check.c:455 tp->type
|
||||
// wrap). Element predicates / esz read varp.lhs
|
||||
// .lhs; Ken's gate: only deref when the wrap
|
||||
// shape is confirmed N_TSLICE (mirrors cstage
|
||||
// cgen.c:4352 `vsu->kind == TY_SLICE` guard).
|
||||
let velem: *node = varp.lhs;
|
||||
if (varp.lhs != nil
|
||||
&& varp.lhs.kind == nkind.N_TSLICE) {
|
||||
velem = varp.lhs.lhs;
|
||||
};
|
||||
let esz: i32 = 8;
|
||||
if (varp.lhs != nil) {
|
||||
if (varp.lhs.kind == nkind.N_TNAME) {
|
||||
let ps: i32 = primsize(varp.lhs.str);
|
||||
if (velem != nil) {
|
||||
if (velem.kind == nkind.N_TNAME) {
|
||||
let ps: i32 = primsize(velem.str);
|
||||
if (ps > 0) { esz = ps; }
|
||||
else { esz = slotsize(c, varp.lhs); };
|
||||
else { esz = slotsize(c, velem); };
|
||||
} else {
|
||||
esz = slotsize(c, varp.lhs);
|
||||
esz = slotsize(c, velem);
|
||||
};
|
||||
};
|
||||
if (esz < 1) { esz = 1; };
|
||||
let velemtagged: bool = istaggedtype(c, varp.lhs);
|
||||
let velemstr: bool = isstrtype(c, varp.lhs);
|
||||
let velemslice: bool = isslicetype(c, varp.lhs);
|
||||
let velemtagged: bool = istaggedtype(c, velem);
|
||||
let velemstr: bool = isstrtype(c, velem);
|
||||
let velemslice: bool = isslicetype(c, velem);
|
||||
let doff: i32 = 0;
|
||||
if (nvar > 0) {
|
||||
doff = localadd(c, dname, nvar * esz, nil);
|
||||
};
|
||||
// #60: vararg gather builds a {ptr,len,cap} slice
|
||||
// descriptor — route through tyslicesize so #34's
|
||||
// slice-header bump propagates here.
|
||||
// slice-header bump propagates here. varp.lhs is
|
||||
// already the []T wrap from installparams, so we
|
||||
// consume it directly (re-slicewrap → [][]T).
|
||||
let soff: i32 = localadd(c, sname, tyslicesize(): i32,
|
||||
slicewrap(c, varp.lhs));
|
||||
varp.lhs);
|
||||
let aa2: *node = n.list;
|
||||
let kk3: i32 = 0;
|
||||
for (kk3 < nfixed_v) {
|
||||
@@ -3120,7 +3133,10 @@ fn cgcall(c: *cgen, n: *node) void = {
|
||||
for (aa2 != nil) {
|
||||
let slot: i32 = doff + j * esz;
|
||||
if (velemtagged) {
|
||||
cgwidentaggedstore(c, varp.lhs,
|
||||
// dst is the per-element tagged type;
|
||||
// pass velem (cstage cgen.c:4382 passes
|
||||
// velem, not the slice wrap vsu).
|
||||
cgwidentaggedstore(c, velem,
|
||||
aa2, "BP", slot, esz);
|
||||
} else { if (velemstr) {
|
||||
cgexpr(c, aa2);
|
||||
|
||||
@@ -2726,6 +2726,20 @@ fn installparams(c: *checker, params: *node) void = {
|
||||
let p: *node = params;
|
||||
for (p != nil) {
|
||||
if (p.kind == nkind.N_PARAM) {
|
||||
// Hare-style variadic `T...`: normalize p.lhs to []T so
|
||||
// downstream consumers (N_IDENT exprtype lookups via
|
||||
// s.decl.lhs, cgen's variadic-slot synthesis) see the
|
||||
// effective slice type. Mirrors cstage check.c:455
|
||||
// `tp->type = type_slice(c->a, pt)` and harec
|
||||
// check_func_type. Surface-fidelity preserved: wwdump
|
||||
// -a runs parser only and never reaches this mutation.
|
||||
if (p.op == tkind.TK_ELLIPSIS) {
|
||||
if (p.lhs != nil && p.lhs.kind != nkind.N_TSLICE) {
|
||||
let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0);
|
||||
sl.lhs = p.lhs;
|
||||
p.lhs = sl;
|
||||
};
|
||||
};
|
||||
let nm: str = p.str;
|
||||
if (nm.len > 0) {
|
||||
checkmoduleshadow(c, nm, "param");
|
||||
|
||||
@@ -9690,6 +9690,20 @@ fn installparams(c: *checker, params: *node) void = {
|
||||
let p: *node = params;
|
||||
for (p != nil) {
|
||||
if (p.kind == nkind.N_PARAM) {
|
||||
// Hare-style variadic `T...`: normalize p.lhs to []T so
|
||||
// downstream consumers (N_IDENT exprtype lookups via
|
||||
// s.decl.lhs, cgen's variadic-slot synthesis) see the
|
||||
// effective slice type. Mirrors cstage check.c:455
|
||||
// `tp->type = type_slice(c->a, pt)` and harec
|
||||
// check_func_type. Surface-fidelity preserved: wwdump
|
||||
// -a runs parser only and never reaches this mutation.
|
||||
if (p.op == tkind.TK_ELLIPSIS) {
|
||||
if (p.lhs != nil && p.lhs.kind != nkind.N_TSLICE) {
|
||||
let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0);
|
||||
sl.lhs = p.lhs;
|
||||
p.lhs = sl;
|
||||
};
|
||||
};
|
||||
let nm: str = p.str;
|
||||
if (nm.len > 0) {
|
||||
checkmoduleshadow(c, nm, "param");
|
||||
@@ -17127,29 +17141,42 @@ fn cgcall(c: *cgen, n: *node) void = {
|
||||
// scalars to 8, mismatching the stride at the
|
||||
// callee read site — runtime miscompile in
|
||||
// `(rune...)` callees per #36.
|
||||
// check.ww installparams promotes varp.lhs to
|
||||
// []T (mirrors cstage check.c:455 tp->type
|
||||
// wrap). Element predicates / esz read varp.lhs
|
||||
// .lhs; Ken's gate: only deref when the wrap
|
||||
// shape is confirmed N_TSLICE (mirrors cstage
|
||||
// cgen.c:4352 `vsu->kind == TY_SLICE` guard).
|
||||
let velem: *node = varp.lhs;
|
||||
if (varp.lhs != nil
|
||||
&& varp.lhs.kind == nkind.N_TSLICE) {
|
||||
velem = varp.lhs.lhs;
|
||||
};
|
||||
let esz: i32 = 8;
|
||||
if (varp.lhs != nil) {
|
||||
if (varp.lhs.kind == nkind.N_TNAME) {
|
||||
let ps: i32 = primsize(varp.lhs.str);
|
||||
if (velem != nil) {
|
||||
if (velem.kind == nkind.N_TNAME) {
|
||||
let ps: i32 = primsize(velem.str);
|
||||
if (ps > 0) { esz = ps; }
|
||||
else { esz = slotsize(c, varp.lhs); };
|
||||
else { esz = slotsize(c, velem); };
|
||||
} else {
|
||||
esz = slotsize(c, varp.lhs);
|
||||
esz = slotsize(c, velem);
|
||||
};
|
||||
};
|
||||
if (esz < 1) { esz = 1; };
|
||||
let velemtagged: bool = istaggedtype(c, varp.lhs);
|
||||
let velemstr: bool = isstrtype(c, varp.lhs);
|
||||
let velemslice: bool = isslicetype(c, varp.lhs);
|
||||
let velemtagged: bool = istaggedtype(c, velem);
|
||||
let velemstr: bool = isstrtype(c, velem);
|
||||
let velemslice: bool = isslicetype(c, velem);
|
||||
let doff: i32 = 0;
|
||||
if (nvar > 0) {
|
||||
doff = localadd(c, dname, nvar * esz, nil);
|
||||
};
|
||||
// #60: vararg gather builds a {ptr,len,cap} slice
|
||||
// descriptor — route through tyslicesize so #34's
|
||||
// slice-header bump propagates here.
|
||||
// slice-header bump propagates here. varp.lhs is
|
||||
// already the []T wrap from installparams, so we
|
||||
// consume it directly (re-slicewrap → [][]T).
|
||||
let soff: i32 = localadd(c, sname, tyslicesize(): i32,
|
||||
slicewrap(c, varp.lhs));
|
||||
varp.lhs);
|
||||
let aa2: *node = n.list;
|
||||
let kk3: i32 = 0;
|
||||
for (kk3 < nfixed_v) {
|
||||
@@ -17169,7 +17196,10 @@ fn cgcall(c: *cgen, n: *node) void = {
|
||||
for (aa2 != nil) {
|
||||
let slot: i32 = doff + j * esz;
|
||||
if (velemtagged) {
|
||||
cgwidentaggedstore(c, varp.lhs,
|
||||
// dst is the per-element tagged type;
|
||||
// pass velem (cstage cgen.c:4382 passes
|
||||
// velem, not the slice wrap vsu).
|
||||
cgwidentaggedstore(c, velem,
|
||||
aa2, "BP", slot, esz);
|
||||
} else { if (velemstr) {
|
||||
cgexpr(c, aa2);
|
||||
@@ -21541,11 +21571,13 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
||||
if (p.kind == nkind.N_PARAM) {
|
||||
let nm: str = p.str;
|
||||
// Hare-style variadic `T...`: callee receives a []T
|
||||
// slice (3 register words / 24B). Mirror the slice-
|
||||
// param spill below but use a synthesised TSLICE
|
||||
// tnode so body references see the slot as a slice.
|
||||
// slice (3 register words / 24B). p.lhs is already
|
||||
// the []T wrap installed by check.ww installparams
|
||||
// (mirrors cstage check.c:455 tp->type promotion), so
|
||||
// we consume it directly — re-wrapping via slicewrap
|
||||
// would yield [][]T.
|
||||
if (p.op == tkind.TK_ELLIPSIS) {
|
||||
let tn: *node = slicewrap(c, p.lhs);
|
||||
let tn: *node = p.lhs;
|
||||
if (idx + 3 <= 6) {
|
||||
let off: i32 = localadd(c, nm, tyslicesize(): i32, tn);
|
||||
emitline("\tMOVQ\t");
|
||||
|
||||
Reference in New Issue
Block a user