wcc/ww: def-dim array slice takes len and cap from the type table

Slicing an array whose dimension is a def constant gave len 0 — the
default-hi and cgbasecap arms only read an N_INTLIT dimension. Route
the dimension through the type table (one root, four arms: default-hi
and cgbasecap, local and global each), byte-identical for the def-dim
SLICE shape. The def-dim array .len/.ptr FIELD-read keeps the
N_INTLIT-only limitation — filed as task #56 (cgdot sibling).
Review item #21.
This commit is contained in:
2026-06-13 00:21:21 +09:00
parent ffb858bba6
commit 75c1b278e6
5 changed files with 387 additions and 66 deletions

View File

@@ -25683,14 +25683,28 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = {
if (tn == nil) { return false; };
if (tn.kind == nkind.N_TARRAY) {
let lenn: *node = tn.rhs;
if (lenn == nil) { return false; };
if (lenn.kind != nkind.N_INTLIT) { return false; };
emitline("\tMOVQ\t$");
emituint(lenn.uval);
emitline(", ");
emitline(dst);
emitline("\n");
return true;
if (lenn != nil && lenn.kind == nkind.N_INTLIT) {
emitline("\tMOVQ\t$");
emituint(lenn.uval);
emitline(", ");
emitline(dst);
emitline("\n");
return true;
};
// #21: a def/const array dim — non-N_INTLIT — reads its cap
// from the stamped array tinfo (rule-13), the cap twin of the
// default-hi fix; pre-fix cgbasecap returned false here and the
// caller fell to cap=len (cs computes base_cap-lo from bu->alen).
let abt: *tinfo = tichase(base.type_: *tinfo);
if (abt != nil && abt.kind == tykind.TY_ARRAY) {
emitline("\tMOVQ\t$");
emitint(abt.alen: i64);
emitline(", ");
emitline(dst);
emitline("\n");
return true;
};
return false;
};
if (tn.kind == nkind.N_TSLICE) {
emitline("\tMOVQ\t");
@@ -25741,14 +25755,25 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = {
if (gt == nil) { return false; };
if (gt.kind == nkind.N_TARRAY) {
let lenn: *node = gt.rhs;
if (lenn == nil) { return false; };
if (lenn.kind != nkind.N_INTLIT) { return false; };
emitline("\tMOVQ\t$");
emituint(lenn.uval);
emitline(", ");
emitline(dst);
emitline("\n");
return true;
if (lenn != nil && lenn.kind == nkind.N_INTLIT) {
emitline("\tMOVQ\t$");
emituint(lenn.uval);
emitline(", ");
emitline(dst);
emitline("\n");
return true;
};
// #21: def/const global array dim cap — twin of the local arm.
let abt: *tinfo = tichase(base.type_: *tinfo);
if (abt != nil && abt.kind == tykind.TY_ARRAY) {
emitline("\tMOVQ\t$");
emitint(abt.alen: i64);
emitline(", ");
emitline(dst);
emitline("\n");
return true;
};
return false;
};
if (gt.kind == nkind.N_TSLICE) {
emitline("\tLEAQ\t");
@@ -25990,10 +26015,21 @@ fn cgslice(c: *cgen, n: *node) void = {
if (tn != nil) {
if (tn.kind == nkind.N_TARRAY) {
let lenn: *node = tn.rhs;
if (lenn != nil) {
if (lenn.kind == nkind.N_INTLIT) {
if (lenn != nil && lenn.kind == nkind.N_INTLIT) {
emitline("\tMOVQ\t$");
emituint(lenn.uval);
emitline(", AX\n");
handled = true;
} else {
// #21: a def/const array dim (`[MAX]u8`) is not an
// N_INTLIT node, so the literal read above misses it
// (MOVQ $0 default-hi -> len 0 / underflow, exit 255).
// Read the resolved length from the stamped array
// tinfo (rule-13), mirroring cstage's bu->alen.
let abt: *tinfo = tichase(base.type_: *tinfo);
if (abt != nil && abt.kind == tykind.TY_ARRAY) {
emitline("\tMOVQ\t$");
emituint(lenn.uval);
emitint(abt.alen: i64);
emitline(", AX\n");
handled = true;
};
@@ -26034,10 +26070,19 @@ fn cgslice(c: *cgen, n: *node) void = {
let handled: bool = false;
if (globaltn.kind == nkind.N_TARRAY) {
let lenn: *node = globaltn.rhs;
if (lenn != nil) {
if (lenn.kind == nkind.N_INTLIT) {
if (lenn != nil && lenn.kind == nkind.N_INTLIT) {
emitline("\tMOVQ\t$");
emituint(lenn.uval);
emitline(", AX\n");
handled = true;
} else {
// #21: a def/const global array dim — non-N_INTLIT, read the
// resolved length off the stamped array tinfo (rule-13), the
// twin of the local arm above (cstage's bu->alen).
let abt: *tinfo = tichase(base.type_: *tinfo);
if (abt != nil && abt.kind == tykind.TY_ARRAY) {
emitline("\tMOVQ\t$");
emituint(lenn.uval);
emitint(abt.alen: i64);
emitline(", AX\n");
handled = true;
};