wwstage: marshal full slice/str header for deref-source call arg (#9)
nodeisslice/nodeisstr lacked an N_UN(TK_STAR) arm, so a deref-source slice/str call arg (f(*h), h:*[]T) fell to the scalar single-PUSHQ default — marshalling only .ptr and dropping .len/.cap. Add the type-keyed arm (read checker-stamped n.type_, mirror cstage node_isslice/node_isstr and the sibling N_DOT/N_INDEX arms). cgen already loads the full 24B header (C1b c67f362); this fixes only the call-arg push/pop count. wwstage-only align-up; cstage was always correct.
This commit is contained in:
@@ -1371,6 +1371,18 @@ fn nodeisslice(c: *cgen, n: *syntax.node) bool = {
|
||||
if (k == syntax.nkind.N_INDEX) {
|
||||
return syntax.typeisslice(n.type_: *syntax.tinfo);
|
||||
};
|
||||
// #9 (C1c): `*h` where h:*[]T — an N_UN TK_STAR deref whose pointee is
|
||||
// a slice. C1b (c67f362) fixed the 24B header LOAD; this arm fixes the
|
||||
// call-arg push COUNT (pushargsrev's slice arm :1194 and cgcall's pop
|
||||
// sizer cgenexpr.ww:8098 both key off this recognizer). Without it the
|
||||
// deref fell through to the scalar single-PUSHQ default, marshalling
|
||||
// .ptr and dropping .len/.cap. Read the checker-stamped n.type_
|
||||
// (unoptype TK_STAR returns the pointee, check.ww:2967-2981), mirroring
|
||||
// cstage node_isslice = type_isslice(n->type) (cmd/w6c/cgen.c:226-228)
|
||||
// and the N_DOT/N_INDEX arms above.
|
||||
if (k == syntax.nkind.N_UN && n.op == syntax.tkind.TK_STAR) {
|
||||
return syntax.typeisslice(n.type_: *syntax.tinfo);
|
||||
};
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -1385,11 +1397,7 @@ fn nodeisslice(c: *cgen, n: *syntax.node) bool = {
|
||||
// recognizer because the stamp is on a sub-node (callee return / cast
|
||||
// target), not on `n` itself. Covered: N_STRLIT, N_IDENT (local stamp /
|
||||
// def stamp), N_CALL (return type), N_INDEX (element stamp — #46 F7-c2),
|
||||
// N_DOT (n.type_ — #56 A.6.3h), N_CAST.
|
||||
// Not covered (separate bugs / out of scope):
|
||||
// - N_UN(TK_STAR) of `*str` — cgun itself emits only `MOVQ (AX), AX`
|
||||
// and never loads .len into BX; fixing the recognizer alone won't
|
||||
// help. Tracked alongside the broader cgun-load-shape gap.
|
||||
// N_DOT (n.type_ — #56 A.6.3h), N_CAST, N_UN(TK_STAR) (#9 C1c).
|
||||
fn nodeisstr(c: *cgen, n: *syntax.node) bool = {
|
||||
if (n == nil) { return false; };
|
||||
let k: syntax.nkind = n.kind;
|
||||
@@ -1470,6 +1478,14 @@ fn nodeisstr(c: *cgen, n: *syntax.node) bool = {
|
||||
if (k == syntax.nkind.N_CAST) {
|
||||
return isstrtype(c, n.rhs);
|
||||
};
|
||||
// #9 (C1c): `*sp` where sp:*str — the str twin of the N_UN TK_STAR
|
||||
// slice arm in nodeisslice. The same recognizer drives the call-arg
|
||||
// push count and cgcall's pop sizer; reading the checker-stamped
|
||||
// n.type_ (pointee per unoptype TK_STAR, check.ww:2967-2981) mirrors
|
||||
// cstage node_isstr = type_isstr(n->type) (cmd/w6c/cgen.c:213-216).
|
||||
if (k == syntax.nkind.N_UN && n.op == syntax.tkind.TK_STAR) {
|
||||
return syntax.typeisstr(n.type_: *syntax.tinfo);
|
||||
};
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user