cgen: default the hi bound of a slice/str-field slice, both stages
x.slicefield[:] / x.strfield[2:] emitted MOVQ $0 for the omitted hi
bound on BOTH stages (N_IDENT-gated dispatch; symmetric, so byte
identity never caught it) in all four sites: cgexpr N_SLICE + pushargs
(cstage), cgslice + pushargsrev (wwstage). The new arm re-evaluates
the pure field read for its {ptr,len,cap} header and takes .len,
covering local, viaptr, dot-chain, (*p), arr[i], and global inners.
Call inners still loud-reject upstream. Sibling of the #252/#257
array-field arms.
This commit is contained in:
@@ -3000,6 +3000,17 @@ fn cgslice(c: *cgen, n: *syntax.node) void = {
|
||||
emitline("\tMOVQ\t$");
|
||||
emitint(dotbu.alen: i64);
|
||||
emitline(", AX\n");
|
||||
} else { if (dotbu != nil && (dotbu.kind == syntax.tykind.TY_SLICE
|
||||
|| dotbu.kind == syntax.tykind.TY_STR)) {
|
||||
// slice/str FIELD base (#252's slice twin): the old
|
||||
// fall-through emitted $0 — silent 0/negative len on BOTH
|
||||
// stages, byteid-blind. Re-evaluate the field read for its
|
||||
// header (pure place: call inners loud-reject upstream;
|
||||
// cgdot's slice/str arms leave AX=ptr, BX=len, CX=cap for
|
||||
// every supported inner) and take .len. Scratch regs are
|
||||
// dead at the hi step. Cstage twin: cgen.c N_SLICE.
|
||||
cgexpr(c, base);
|
||||
emitline("\tMOVQ\tBX, AX\n");
|
||||
} else { if (arrlittn != nil) {
|
||||
// #31: default-hi for the arrlit base = its element count (the
|
||||
// stashed [count]T tnode's .rhs intlit).
|
||||
@@ -3014,7 +3025,7 @@ fn cgslice(c: *cgen, n: *syntax.node) void = {
|
||||
emitline(", AX\n");
|
||||
} else {
|
||||
emitline("\tMOVQ\t$0, AX\n");
|
||||
};};};};};
|
||||
};};};};};};
|
||||
emitline("\tMOVQ\tAX, BX\n");
|
||||
emitline("\tPOPQ\tCX\n");
|
||||
emitline("\tPOPQ\tAX\n");
|
||||
|
||||
@@ -782,9 +782,16 @@ fn pushargsrev(c: *cgen, arg: *syntax.node, param: *syntax.node, memphase: bool,
|
||||
emitline("\tMOVQ\t$");
|
||||
emitint(dotbu.alen: i64);
|
||||
emitline(", AX\n");
|
||||
} else { if (dotbu != nil && (dotbu.kind == syntax.tykind.TY_SLICE
|
||||
|| dotbu.kind == syntax.tykind.TY_STR)) {
|
||||
// slice/str FIELD base — the arg twin of the cgslice
|
||||
// default-hi arm; same re-eval-for-header rationale.
|
||||
// Cstage twin: cgen.c pushargs N_SLICE.
|
||||
cgexpr(c, base);
|
||||
emitline("\tMOVQ\tBX, AX\n");
|
||||
} else {
|
||||
emitline("\tMOVQ\t$0, AX\n");
|
||||
};};};};
|
||||
};};};};};
|
||||
emitline("\tPUSHQ\tAX\n");
|
||||
// lo (default 0) → AX
|
||||
if (lo != nil) { cgexpr(c, lo); }
|
||||
|
||||
Reference in New Issue
Block a user