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:
@@ -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;
|
||||
};
|
||||
|
||||
@@ -2463,14 +2463,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");
|
||||
@@ -2521,14 +2535,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");
|
||||
@@ -2770,10 +2795,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;
|
||||
};
|
||||
@@ -2814,10 +2850,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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user