wcc/ww: str-to-slice cap synth keys on the source type
Casting a global str to []u8 dropped the cap=len synth (the trailing MOVQ BX,CX) — the synth was gated on a local-ident source shape. Key it on the source type so local/global/field/call sources all get the header. Review item #19.
This commit is contained in:
@@ -24161,19 +24161,13 @@ fn cgcast(c: *cgen, n: *node) void = {
|
||||
// str → []T: cgexpr left (AX=ptr, BX=len). Slice register
|
||||
// convention is (AX=ptr, BX=len, CX=cap); synthesise cap = len
|
||||
// so downstream arg-push / let-init paths see the canonical
|
||||
// triple. Detect via dst-is-slice + src-ident's local-tnode
|
||||
// being str (the common shape; non-ident sources rare).
|
||||
// triple. Type-keyed on the stamped src/dst types (dst-is-slice +
|
||||
// src-is-str), mirroring cstage cgen.c N_CAST (type_chase_named →
|
||||
// TY_SLICE/TY_STR). The prior local-ident-source gate (#19) missed
|
||||
// every non-local str source — global ident, struct field, call
|
||||
// result — leaving CX = the str's stale word-16 garbage cap.
|
||||
if (isslicetype(c, n.rhs)) {
|
||||
let srcstr: bool = false;
|
||||
if (n.lhs != nil) {
|
||||
if (n.lhs.kind == nkind.N_IDENT) {
|
||||
let lc: *local = localfindnode(c, n.lhs.str);
|
||||
if (lc != nil) {
|
||||
if (isstrtype(c, lc.tnode)) { srcstr = true; };
|
||||
};
|
||||
};
|
||||
};
|
||||
if (srcstr) { emitline("\tMOVQ\tBX, CX\n"); };
|
||||
if (isstrtype(c, n.lhs)) { emitline("\tMOVQ\tBX, CX\n"); };
|
||||
};
|
||||
// 0=int, 1=f32, 2=f64. CVT picks one direction per combo;
|
||||
// int↔int casts narrow via an explicit clamp before the early
|
||||
|
||||
@@ -1010,19 +1010,13 @@ fn cgcast(c: *cgen, n: *node) void = {
|
||||
// str → []T: cgexpr left (AX=ptr, BX=len). Slice register
|
||||
// convention is (AX=ptr, BX=len, CX=cap); synthesise cap = len
|
||||
// so downstream arg-push / let-init paths see the canonical
|
||||
// triple. Detect via dst-is-slice + src-ident's local-tnode
|
||||
// being str (the common shape; non-ident sources rare).
|
||||
// triple. Type-keyed on the stamped src/dst types (dst-is-slice +
|
||||
// src-is-str), mirroring cstage cgen.c N_CAST (type_chase_named →
|
||||
// TY_SLICE/TY_STR). The prior local-ident-source gate (#19) missed
|
||||
// every non-local str source — global ident, struct field, call
|
||||
// result — leaving CX = the str's stale word-16 garbage cap.
|
||||
if (isslicetype(c, n.rhs)) {
|
||||
let srcstr: bool = false;
|
||||
if (n.lhs != nil) {
|
||||
if (n.lhs.kind == nkind.N_IDENT) {
|
||||
let lc: *local = localfindnode(c, n.lhs.str);
|
||||
if (lc != nil) {
|
||||
if (isstrtype(c, lc.tnode)) { srcstr = true; };
|
||||
};
|
||||
};
|
||||
};
|
||||
if (srcstr) { emitline("\tMOVQ\tBX, CX\n"); };
|
||||
if (isstrtype(c, n.lhs)) { emitline("\tMOVQ\tBX, CX\n"); };
|
||||
};
|
||||
// 0=int, 1=f32, 2=f64. CVT picks one direction per combo;
|
||||
// int↔int casts narrow via an explicit clamp before the early
|
||||
|
||||
@@ -24161,19 +24161,13 @@ fn cgcast(c: *cgen, n: *node) void = {
|
||||
// str → []T: cgexpr left (AX=ptr, BX=len). Slice register
|
||||
// convention is (AX=ptr, BX=len, CX=cap); synthesise cap = len
|
||||
// so downstream arg-push / let-init paths see the canonical
|
||||
// triple. Detect via dst-is-slice + src-ident's local-tnode
|
||||
// being str (the common shape; non-ident sources rare).
|
||||
// triple. Type-keyed on the stamped src/dst types (dst-is-slice +
|
||||
// src-is-str), mirroring cstage cgen.c N_CAST (type_chase_named →
|
||||
// TY_SLICE/TY_STR). The prior local-ident-source gate (#19) missed
|
||||
// every non-local str source — global ident, struct field, call
|
||||
// result — leaving CX = the str's stale word-16 garbage cap.
|
||||
if (isslicetype(c, n.rhs)) {
|
||||
let srcstr: bool = false;
|
||||
if (n.lhs != nil) {
|
||||
if (n.lhs.kind == nkind.N_IDENT) {
|
||||
let lc: *local = localfindnode(c, n.lhs.str);
|
||||
if (lc != nil) {
|
||||
if (isstrtype(c, lc.tnode)) { srcstr = true; };
|
||||
};
|
||||
};
|
||||
};
|
||||
if (srcstr) { emitline("\tMOVQ\tBX, CX\n"); };
|
||||
if (isstrtype(c, n.lhs)) { emitline("\tMOVQ\tBX, CX\n"); };
|
||||
};
|
||||
// 0=int, 1=f32, 2=f64. CVT picks one direction per combo;
|
||||
// int↔int casts narrow via an explicit clamp before the early
|
||||
|
||||
Reference in New Issue
Block a user