wwstage: name vararg-gather slots via mklabel; graduate fmt 777/780/781 (#227)
wwstage named variadic-gather slots with mkvarargname off a separate varargseq counter, never bumping the shared labelseq that names match labels. cstage names them via mklabel (cmd/w6c/cgen.c:5427,5431), which advances labelseq twice per gather. So by the time main.main reached its `match (wr)`, wwstage's match-label counter ran two behind cstage's (_4/_5/_6 vs _6/_7/_8) — a pure label-numbering divergence that kept fmt cs/ww byte-id failing. Drop varargseq and the mkvarargname helper; call the existing mklabel for the two gather slots, matching cstage's order (vararg_d only when nvar>0, vararg_sl always). The slot names are locals-table keys only — they resolve to BP offsets and never reach the asm — so only the labelseq advance is observable, which is exactly what realigns the downstream match labels. cstage untouched (align wwstage up). This was the match-label half of fmt's divergence; with the earlier compound-assign fix it completes fmt byte-identity. Graduate 777/780/781 to STAGE_CS|STAGE_WW with byte_id, and drop the now-stale (void)asm_byte_identical guard in 777.
This commit is contained in:
@@ -15041,34 +15041,6 @@ fn callee_variadic_param(c: *cgen, callee: *node, nfixed_out: *i32) *node = {
|
|||||||
return findvariadicparam(ps, nfixed_out);
|
return findvariadicparam(ps, nfixed_out);
|
||||||
};
|
};
|
||||||
|
|
||||||
// mkvarargname — fresh local-slot name "<prefix><seq>". Used for
|
|
||||||
// the per-variadic-call scratch buffers (`@vararg_d_N` for the
|
|
||||||
// element-data buffer, `@vararg_sl_N` for the 24B slice descriptor).
|
|
||||||
// N is recorded on the N_CALL node at first emit so re-entry into
|
|
||||||
// cgcall picks the same names regardless of walk order.
|
|
||||||
fn mkvarargname(c: *cgen, prefix: str, seq: i32) str = {
|
|
||||||
let buf: [128]u8;
|
|
||||||
let i: i32 = 0;
|
|
||||||
let j: i32 = 0;
|
|
||||||
for (j < prefix.len) {
|
|
||||||
buf[i] = prefix[j];
|
|
||||||
i += 1; j += 1;
|
|
||||||
};
|
|
||||||
let ns: str = strconv.i64tos(seq: i64, strconv.base.DEC);
|
|
||||||
let n: i32 = ns.len;
|
|
||||||
let dk: i32 = 0;
|
|
||||||
for (dk < n) { buf[i + dk] = ns.ptr[dk]; dk += 1; };
|
|
||||||
let total: i32 = i + n;
|
|
||||||
let p: []u8 = alloc([], (total: u64) + 1u64)!;
|
|
||||||
let k: i32 = 0;
|
|
||||||
for (k < total) { p[k] = buf[k]; k += 1; };
|
|
||||||
p[total] = 0u8;
|
|
||||||
let r: str;
|
|
||||||
r.ptr = p.ptr;
|
|
||||||
r.len = total;
|
|
||||||
return r;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ---- expression cgen -------------------------------------------------
|
// ---- expression cgen -------------------------------------------------
|
||||||
|
|
||||||
// pushargsrev — recursively walks the arg list, evaluates rightmost
|
// pushargsrev — recursively walks the arg list, evaluates rightmost
|
||||||
@@ -22469,15 +22441,16 @@ fn cgcall(c: *cgen, n: *node) void = {
|
|||||||
}; };
|
}; };
|
||||||
};
|
};
|
||||||
// Hare-style variadic last param: gather N tail args into a
|
// Hare-style variadic last param: gather N tail args into a
|
||||||
// frame-resident [N]T (`@vararg_d_<seq>`) plus a 24B slice
|
// frame-resident [N]T (vararg_d slot) plus a 24B slice
|
||||||
// descriptor (`@vararg_sl_<seq>`), then splice a synthesised
|
// descriptor (vararg_sl slot), then splice a synthesised
|
||||||
// N_IDENT pointing at the descriptor into n.list so the rest
|
// N_IDENT pointing at the descriptor into n.list so the rest
|
||||||
// of the call machinery sees one slice slot for the variadic.
|
// of the call machinery sees one slice slot for the variadic.
|
||||||
// Forwarding shape (`xs...`) skips the gather: the spread's
|
// Forwarding shape (`xs...`) skips the gather: the spread's
|
||||||
// inner slice expression replaces the wrapper in place. Empty
|
// inner slice expression replaces the wrapper in place. Empty
|
||||||
// (no trailing args) writes a {nil, 0, 0} descriptor. Per-call
|
// (no trailing args) writes a {nil, 0, 0} descriptor. Slot
|
||||||
// seq comes from c.varargseq bumped at gather emit (mirrors
|
// names come from mklabel (mirrors cstage cgen.c:5427/5431) so
|
||||||
// cstage's mklabel("vararg_d/sl") freshness).
|
// the shared labelseq advances in lockstep — vararg_d only when
|
||||||
|
// nvar>0, vararg_sl always — keeping later match labels aligned.
|
||||||
{
|
{
|
||||||
let nfixed_v: i32 = 0;
|
let nfixed_v: i32 = 0;
|
||||||
let varp: *node = callee_variadic_param(c, callee, &nfixed_v);
|
let varp: *node = callee_variadic_param(c, callee, &nfixed_v);
|
||||||
@@ -22515,10 +22488,6 @@ fn cgcall(c: *cgen, n: *node) void = {
|
|||||||
if (prev == nil) { n.list = inner; }
|
if (prev == nil) { n.list = inner; }
|
||||||
else { prev.next = inner; };
|
else { prev.next = inner; };
|
||||||
} else {
|
} else {
|
||||||
let seq: i32 = c.varargseq;
|
|
||||||
c.varargseq += 1;
|
|
||||||
let dname: str = mkvarargname(c, "@vararg_d_", seq);
|
|
||||||
let sname: str = mkvarargname(c, "@vararg_sl_", seq);
|
|
||||||
// Use raw element size, not stack-padded
|
// Use raw element size, not stack-padded
|
||||||
// slotsize. cstage cmd/w6c/cgen.c cgcall
|
// slotsize. cstage cmd/w6c/cgen.c cgcall
|
||||||
// gathers a `T...` slice at velem->size stride
|
// gathers a `T...` slice at velem->size stride
|
||||||
@@ -22555,6 +22524,11 @@ fn cgcall(c: *cgen, n: *node) void = {
|
|||||||
let velemslice: bool = isslicetype(c, velem);
|
let velemslice: bool = isslicetype(c, velem);
|
||||||
let doff: i32 = 0;
|
let doff: i32 = 0;
|
||||||
if (nvar > 0) {
|
if (nvar > 0) {
|
||||||
|
// mklabel, not a separate vararg counter, so
|
||||||
|
// labelseq advances with cstage cgen.c:5427 — the
|
||||||
|
// slot name never reaches asm, but the shared
|
||||||
|
// counter numbers later match labels.
|
||||||
|
let dname: str = mklabel(c, "vararg_d");
|
||||||
doff = localadd(c, dname, nvar * esz, nil);
|
doff = localadd(c, dname, nvar * esz, nil);
|
||||||
};
|
};
|
||||||
// #60: vararg gather builds a {ptr,len,cap} slice
|
// #60: vararg gather builds a {ptr,len,cap} slice
|
||||||
@@ -22562,6 +22536,9 @@ fn cgcall(c: *cgen, n: *node) void = {
|
|||||||
// slice-header bump propagates here. varp.lhs is
|
// slice-header bump propagates here. varp.lhs is
|
||||||
// already the []T wrap from installparams, so we
|
// already the []T wrap from installparams, so we
|
||||||
// consume it directly (re-slicewrap → [][]T).
|
// consume it directly (re-slicewrap → [][]T).
|
||||||
|
// vararg_sl always allocated (cstage cgen.c:5431),
|
||||||
|
// bumping labelseq whether or not nvar>0.
|
||||||
|
let sname: str = mklabel(c, "vararg_sl");
|
||||||
let soff: i32 = localadd(c, sname, tyslicesize(): i32,
|
let soff: i32 = localadd(c, sname, tyslicesize(): i32,
|
||||||
varp.lhs);
|
varp.lhs);
|
||||||
let aa2: *node = n.list;
|
let aa2: *node = n.list;
|
||||||
@@ -29104,13 +29081,6 @@ type cgen = struct {
|
|||||||
yieldbuf: []str, // stack of match end labels for yield
|
yieldbuf: []str, // stack of match end labels for yield
|
||||||
defertop: i32,
|
defertop: i32,
|
||||||
deferbuf: []*node, // stack of deferred exprs (LIFO at return)
|
deferbuf: []*node, // stack of deferred exprs (LIFO at return)
|
||||||
// Variadic-call gather state. cgcall bumps this on each gather
|
|
||||||
// emit and uses it to mint `@vararg_d_N` / `@vararg_sl_N` per
|
|
||||||
// callsite; mirrors cstage's mklabel("vararg_d/sl") freshness
|
|
||||||
// so two variadic callsites with different arities in one fn
|
|
||||||
// get distinct slots (the shared slot fail-louds under #15's
|
|
||||||
// @-prefix grow-on-pin discipline).
|
|
||||||
varargseq: i32,
|
|
||||||
// System V AMD64 sret discipline (#23). Plain TY_STRUCT returns
|
// System V AMD64 sret discipline (#23). Plain TY_STRUCT returns
|
||||||
// with size > 24B are passed via a hidden first-arg pointer
|
// with size > 24B are passed via a hidden first-arg pointer
|
||||||
// (RDI) to a caller-prealloc dest; the callee writes through
|
// (RDI) to a caller-prealloc dest; the callee writes through
|
||||||
@@ -29160,7 +29130,6 @@ fn cgeninit(c: *cgen) void = {
|
|||||||
c.frame = 0;
|
c.frame = 0;
|
||||||
c.lastwasreturn = 0;
|
c.lastwasreturn = 0;
|
||||||
c.labelseq = 0;
|
c.labelseq = 0;
|
||||||
c.varargseq = 0;
|
|
||||||
c.sretdestoff = 0;
|
c.sretdestoff = 0;
|
||||||
c.sretdestnode = nil;
|
c.sretdestnode = nil;
|
||||||
c.sretforward = 0;
|
c.sretforward = 0;
|
||||||
|
|||||||
@@ -491,13 +491,6 @@ type cgen = struct {
|
|||||||
yieldbuf: []str, // stack of match end labels for yield
|
yieldbuf: []str, // stack of match end labels for yield
|
||||||
defertop: i32,
|
defertop: i32,
|
||||||
deferbuf: []*node, // stack of deferred exprs (LIFO at return)
|
deferbuf: []*node, // stack of deferred exprs (LIFO at return)
|
||||||
// Variadic-call gather state. cgcall bumps this on each gather
|
|
||||||
// emit and uses it to mint `@vararg_d_N` / `@vararg_sl_N` per
|
|
||||||
// callsite; mirrors cstage's mklabel("vararg_d/sl") freshness
|
|
||||||
// so two variadic callsites with different arities in one fn
|
|
||||||
// get distinct slots (the shared slot fail-louds under #15's
|
|
||||||
// @-prefix grow-on-pin discipline).
|
|
||||||
varargseq: i32,
|
|
||||||
// System V AMD64 sret discipline (#23). Plain TY_STRUCT returns
|
// System V AMD64 sret discipline (#23). Plain TY_STRUCT returns
|
||||||
// with size > 24B are passed via a hidden first-arg pointer
|
// with size > 24B are passed via a hidden first-arg pointer
|
||||||
// (RDI) to a caller-prealloc dest; the callee writes through
|
// (RDI) to a caller-prealloc dest; the callee writes through
|
||||||
@@ -547,7 +540,6 @@ fn cgeninit(c: *cgen) void = {
|
|||||||
c.frame = 0;
|
c.frame = 0;
|
||||||
c.lastwasreturn = 0;
|
c.lastwasreturn = 0;
|
||||||
c.labelseq = 0;
|
c.labelseq = 0;
|
||||||
c.varargseq = 0;
|
|
||||||
c.sretdestoff = 0;
|
c.sretdestoff = 0;
|
||||||
c.sretdestnode = nil;
|
c.sretdestnode = nil;
|
||||||
c.sretforward = 0;
|
c.sretforward = 0;
|
||||||
|
|||||||
@@ -3828,15 +3828,16 @@ fn cgcall(c: *cgen, n: *node) void = {
|
|||||||
}; };
|
}; };
|
||||||
};
|
};
|
||||||
// Hare-style variadic last param: gather N tail args into a
|
// Hare-style variadic last param: gather N tail args into a
|
||||||
// frame-resident [N]T (`@vararg_d_<seq>`) plus a 24B slice
|
// frame-resident [N]T (vararg_d slot) plus a 24B slice
|
||||||
// descriptor (`@vararg_sl_<seq>`), then splice a synthesised
|
// descriptor (vararg_sl slot), then splice a synthesised
|
||||||
// N_IDENT pointing at the descriptor into n.list so the rest
|
// N_IDENT pointing at the descriptor into n.list so the rest
|
||||||
// of the call machinery sees one slice slot for the variadic.
|
// of the call machinery sees one slice slot for the variadic.
|
||||||
// Forwarding shape (`xs...`) skips the gather: the spread's
|
// Forwarding shape (`xs...`) skips the gather: the spread's
|
||||||
// inner slice expression replaces the wrapper in place. Empty
|
// inner slice expression replaces the wrapper in place. Empty
|
||||||
// (no trailing args) writes a {nil, 0, 0} descriptor. Per-call
|
// (no trailing args) writes a {nil, 0, 0} descriptor. Slot
|
||||||
// seq comes from c.varargseq bumped at gather emit (mirrors
|
// names come from mklabel (mirrors cstage cgen.c:5427/5431) so
|
||||||
// cstage's mklabel("vararg_d/sl") freshness).
|
// the shared labelseq advances in lockstep — vararg_d only when
|
||||||
|
// nvar>0, vararg_sl always — keeping later match labels aligned.
|
||||||
{
|
{
|
||||||
let nfixed_v: i32 = 0;
|
let nfixed_v: i32 = 0;
|
||||||
let varp: *node = callee_variadic_param(c, callee, &nfixed_v);
|
let varp: *node = callee_variadic_param(c, callee, &nfixed_v);
|
||||||
@@ -3874,10 +3875,6 @@ fn cgcall(c: *cgen, n: *node) void = {
|
|||||||
if (prev == nil) { n.list = inner; }
|
if (prev == nil) { n.list = inner; }
|
||||||
else { prev.next = inner; };
|
else { prev.next = inner; };
|
||||||
} else {
|
} else {
|
||||||
let seq: i32 = c.varargseq;
|
|
||||||
c.varargseq += 1;
|
|
||||||
let dname: str = mkvarargname(c, "@vararg_d_", seq);
|
|
||||||
let sname: str = mkvarargname(c, "@vararg_sl_", seq);
|
|
||||||
// Use raw element size, not stack-padded
|
// Use raw element size, not stack-padded
|
||||||
// slotsize. cstage cmd/w6c/cgen.c cgcall
|
// slotsize. cstage cmd/w6c/cgen.c cgcall
|
||||||
// gathers a `T...` slice at velem->size stride
|
// gathers a `T...` slice at velem->size stride
|
||||||
@@ -3914,6 +3911,11 @@ fn cgcall(c: *cgen, n: *node) void = {
|
|||||||
let velemslice: bool = isslicetype(c, velem);
|
let velemslice: bool = isslicetype(c, velem);
|
||||||
let doff: i32 = 0;
|
let doff: i32 = 0;
|
||||||
if (nvar > 0) {
|
if (nvar > 0) {
|
||||||
|
// mklabel, not a separate vararg counter, so
|
||||||
|
// labelseq advances with cstage cgen.c:5427 — the
|
||||||
|
// slot name never reaches asm, but the shared
|
||||||
|
// counter numbers later match labels.
|
||||||
|
let dname: str = mklabel(c, "vararg_d");
|
||||||
doff = localadd(c, dname, nvar * esz, nil);
|
doff = localadd(c, dname, nvar * esz, nil);
|
||||||
};
|
};
|
||||||
// #60: vararg gather builds a {ptr,len,cap} slice
|
// #60: vararg gather builds a {ptr,len,cap} slice
|
||||||
@@ -3921,6 +3923,9 @@ fn cgcall(c: *cgen, n: *node) void = {
|
|||||||
// slice-header bump propagates here. varp.lhs is
|
// slice-header bump propagates here. varp.lhs is
|
||||||
// already the []T wrap from installparams, so we
|
// already the []T wrap from installparams, so we
|
||||||
// consume it directly (re-slicewrap → [][]T).
|
// consume it directly (re-slicewrap → [][]T).
|
||||||
|
// vararg_sl always allocated (cstage cgen.c:5431),
|
||||||
|
// bumping labelseq whether or not nvar>0.
|
||||||
|
let sname: str = mklabel(c, "vararg_sl");
|
||||||
let soff: i32 = localadd(c, sname, tyslicesize(): i32,
|
let soff: i32 = localadd(c, sname, tyslicesize(): i32,
|
||||||
varp.lhs);
|
varp.lhs);
|
||||||
let aa2: *node = n.list;
|
let aa2: *node = n.list;
|
||||||
|
|||||||
@@ -86,34 +86,6 @@ fn callee_variadic_param(c: *cgen, callee: *node, nfixed_out: *i32) *node = {
|
|||||||
return findvariadicparam(ps, nfixed_out);
|
return findvariadicparam(ps, nfixed_out);
|
||||||
};
|
};
|
||||||
|
|
||||||
// mkvarargname — fresh local-slot name "<prefix><seq>". Used for
|
|
||||||
// the per-variadic-call scratch buffers (`@vararg_d_N` for the
|
|
||||||
// element-data buffer, `@vararg_sl_N` for the 24B slice descriptor).
|
|
||||||
// N is recorded on the N_CALL node at first emit so re-entry into
|
|
||||||
// cgcall picks the same names regardless of walk order.
|
|
||||||
fn mkvarargname(c: *cgen, prefix: str, seq: i32) str = {
|
|
||||||
let buf: [128]u8;
|
|
||||||
let i: i32 = 0;
|
|
||||||
let j: i32 = 0;
|
|
||||||
for (j < prefix.len) {
|
|
||||||
buf[i] = prefix[j];
|
|
||||||
i += 1; j += 1;
|
|
||||||
};
|
|
||||||
let ns: str = strconv.i64tos(seq: i64, strconv.base.DEC);
|
|
||||||
let n: i32 = ns.len;
|
|
||||||
let dk: i32 = 0;
|
|
||||||
for (dk < n) { buf[i + dk] = ns.ptr[dk]; dk += 1; };
|
|
||||||
let total: i32 = i + n;
|
|
||||||
let p: []u8 = alloc([], (total: u64) + 1u64)!;
|
|
||||||
let k: i32 = 0;
|
|
||||||
for (k < total) { p[k] = buf[k]; k += 1; };
|
|
||||||
p[total] = 0u8;
|
|
||||||
let r: str;
|
|
||||||
r.ptr = p.ptr;
|
|
||||||
r.len = total;
|
|
||||||
return r;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ---- expression cgen -------------------------------------------------
|
// ---- expression cgen -------------------------------------------------
|
||||||
|
|
||||||
// pushargsrev — recursively walks the arg list, evaluates rightmost
|
// pushargsrev — recursively walks the arg list, evaluates rightmost
|
||||||
|
|||||||
@@ -15041,34 +15041,6 @@ fn callee_variadic_param(c: *cgen, callee: *node, nfixed_out: *i32) *node = {
|
|||||||
return findvariadicparam(ps, nfixed_out);
|
return findvariadicparam(ps, nfixed_out);
|
||||||
};
|
};
|
||||||
|
|
||||||
// mkvarargname — fresh local-slot name "<prefix><seq>". Used for
|
|
||||||
// the per-variadic-call scratch buffers (`@vararg_d_N` for the
|
|
||||||
// element-data buffer, `@vararg_sl_N` for the 24B slice descriptor).
|
|
||||||
// N is recorded on the N_CALL node at first emit so re-entry into
|
|
||||||
// cgcall picks the same names regardless of walk order.
|
|
||||||
fn mkvarargname(c: *cgen, prefix: str, seq: i32) str = {
|
|
||||||
let buf: [128]u8;
|
|
||||||
let i: i32 = 0;
|
|
||||||
let j: i32 = 0;
|
|
||||||
for (j < prefix.len) {
|
|
||||||
buf[i] = prefix[j];
|
|
||||||
i += 1; j += 1;
|
|
||||||
};
|
|
||||||
let ns: str = strconv.i64tos(seq: i64, strconv.base.DEC);
|
|
||||||
let n: i32 = ns.len;
|
|
||||||
let dk: i32 = 0;
|
|
||||||
for (dk < n) { buf[i + dk] = ns.ptr[dk]; dk += 1; };
|
|
||||||
let total: i32 = i + n;
|
|
||||||
let p: []u8 = alloc([], (total: u64) + 1u64)!;
|
|
||||||
let k: i32 = 0;
|
|
||||||
for (k < total) { p[k] = buf[k]; k += 1; };
|
|
||||||
p[total] = 0u8;
|
|
||||||
let r: str;
|
|
||||||
r.ptr = p.ptr;
|
|
||||||
r.len = total;
|
|
||||||
return r;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ---- expression cgen -------------------------------------------------
|
// ---- expression cgen -------------------------------------------------
|
||||||
|
|
||||||
// pushargsrev — recursively walks the arg list, evaluates rightmost
|
// pushargsrev — recursively walks the arg list, evaluates rightmost
|
||||||
@@ -22469,15 +22441,16 @@ fn cgcall(c: *cgen, n: *node) void = {
|
|||||||
}; };
|
}; };
|
||||||
};
|
};
|
||||||
// Hare-style variadic last param: gather N tail args into a
|
// Hare-style variadic last param: gather N tail args into a
|
||||||
// frame-resident [N]T (`@vararg_d_<seq>`) plus a 24B slice
|
// frame-resident [N]T (vararg_d slot) plus a 24B slice
|
||||||
// descriptor (`@vararg_sl_<seq>`), then splice a synthesised
|
// descriptor (vararg_sl slot), then splice a synthesised
|
||||||
// N_IDENT pointing at the descriptor into n.list so the rest
|
// N_IDENT pointing at the descriptor into n.list so the rest
|
||||||
// of the call machinery sees one slice slot for the variadic.
|
// of the call machinery sees one slice slot for the variadic.
|
||||||
// Forwarding shape (`xs...`) skips the gather: the spread's
|
// Forwarding shape (`xs...`) skips the gather: the spread's
|
||||||
// inner slice expression replaces the wrapper in place. Empty
|
// inner slice expression replaces the wrapper in place. Empty
|
||||||
// (no trailing args) writes a {nil, 0, 0} descriptor. Per-call
|
// (no trailing args) writes a {nil, 0, 0} descriptor. Slot
|
||||||
// seq comes from c.varargseq bumped at gather emit (mirrors
|
// names come from mklabel (mirrors cstage cgen.c:5427/5431) so
|
||||||
// cstage's mklabel("vararg_d/sl") freshness).
|
// the shared labelseq advances in lockstep — vararg_d only when
|
||||||
|
// nvar>0, vararg_sl always — keeping later match labels aligned.
|
||||||
{
|
{
|
||||||
let nfixed_v: i32 = 0;
|
let nfixed_v: i32 = 0;
|
||||||
let varp: *node = callee_variadic_param(c, callee, &nfixed_v);
|
let varp: *node = callee_variadic_param(c, callee, &nfixed_v);
|
||||||
@@ -22515,10 +22488,6 @@ fn cgcall(c: *cgen, n: *node) void = {
|
|||||||
if (prev == nil) { n.list = inner; }
|
if (prev == nil) { n.list = inner; }
|
||||||
else { prev.next = inner; };
|
else { prev.next = inner; };
|
||||||
} else {
|
} else {
|
||||||
let seq: i32 = c.varargseq;
|
|
||||||
c.varargseq += 1;
|
|
||||||
let dname: str = mkvarargname(c, "@vararg_d_", seq);
|
|
||||||
let sname: str = mkvarargname(c, "@vararg_sl_", seq);
|
|
||||||
// Use raw element size, not stack-padded
|
// Use raw element size, not stack-padded
|
||||||
// slotsize. cstage cmd/w6c/cgen.c cgcall
|
// slotsize. cstage cmd/w6c/cgen.c cgcall
|
||||||
// gathers a `T...` slice at velem->size stride
|
// gathers a `T...` slice at velem->size stride
|
||||||
@@ -22555,6 +22524,11 @@ fn cgcall(c: *cgen, n: *node) void = {
|
|||||||
let velemslice: bool = isslicetype(c, velem);
|
let velemslice: bool = isslicetype(c, velem);
|
||||||
let doff: i32 = 0;
|
let doff: i32 = 0;
|
||||||
if (nvar > 0) {
|
if (nvar > 0) {
|
||||||
|
// mklabel, not a separate vararg counter, so
|
||||||
|
// labelseq advances with cstage cgen.c:5427 — the
|
||||||
|
// slot name never reaches asm, but the shared
|
||||||
|
// counter numbers later match labels.
|
||||||
|
let dname: str = mklabel(c, "vararg_d");
|
||||||
doff = localadd(c, dname, nvar * esz, nil);
|
doff = localadd(c, dname, nvar * esz, nil);
|
||||||
};
|
};
|
||||||
// #60: vararg gather builds a {ptr,len,cap} slice
|
// #60: vararg gather builds a {ptr,len,cap} slice
|
||||||
@@ -22562,6 +22536,9 @@ fn cgcall(c: *cgen, n: *node) void = {
|
|||||||
// slice-header bump propagates here. varp.lhs is
|
// slice-header bump propagates here. varp.lhs is
|
||||||
// already the []T wrap from installparams, so we
|
// already the []T wrap from installparams, so we
|
||||||
// consume it directly (re-slicewrap → [][]T).
|
// consume it directly (re-slicewrap → [][]T).
|
||||||
|
// vararg_sl always allocated (cstage cgen.c:5431),
|
||||||
|
// bumping labelseq whether or not nvar>0.
|
||||||
|
let sname: str = mklabel(c, "vararg_sl");
|
||||||
let soff: i32 = localadd(c, sname, tyslicesize(): i32,
|
let soff: i32 = localadd(c, sname, tyslicesize(): i32,
|
||||||
varp.lhs);
|
varp.lhs);
|
||||||
let aa2: *node = n.list;
|
let aa2: *node = n.list;
|
||||||
@@ -29104,13 +29081,6 @@ type cgen = struct {
|
|||||||
yieldbuf: []str, // stack of match end labels for yield
|
yieldbuf: []str, // stack of match end labels for yield
|
||||||
defertop: i32,
|
defertop: i32,
|
||||||
deferbuf: []*node, // stack of deferred exprs (LIFO at return)
|
deferbuf: []*node, // stack of deferred exprs (LIFO at return)
|
||||||
// Variadic-call gather state. cgcall bumps this on each gather
|
|
||||||
// emit and uses it to mint `@vararg_d_N` / `@vararg_sl_N` per
|
|
||||||
// callsite; mirrors cstage's mklabel("vararg_d/sl") freshness
|
|
||||||
// so two variadic callsites with different arities in one fn
|
|
||||||
// get distinct slots (the shared slot fail-louds under #15's
|
|
||||||
// @-prefix grow-on-pin discipline).
|
|
||||||
varargseq: i32,
|
|
||||||
// System V AMD64 sret discipline (#23). Plain TY_STRUCT returns
|
// System V AMD64 sret discipline (#23). Plain TY_STRUCT returns
|
||||||
// with size > 24B are passed via a hidden first-arg pointer
|
// with size > 24B are passed via a hidden first-arg pointer
|
||||||
// (RDI) to a caller-prealloc dest; the callee writes through
|
// (RDI) to a caller-prealloc dest; the callee writes through
|
||||||
@@ -29160,7 +29130,6 @@ fn cgeninit(c: *cgen) void = {
|
|||||||
c.frame = 0;
|
c.frame = 0;
|
||||||
c.lastwasreturn = 0;
|
c.lastwasreturn = 0;
|
||||||
c.labelseq = 0;
|
c.labelseq = 0;
|
||||||
c.varargseq = 0;
|
|
||||||
c.sretdestoff = 0;
|
c.sretdestoff = 0;
|
||||||
c.sretdestnode = nil;
|
c.sretdestnode = nil;
|
||||||
c.sretforward = 0;
|
c.sretforward = 0;
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ static const struct row rows[] = {
|
|||||||
" return 42;\n"
|
" return 42;\n"
|
||||||
"};\n",
|
"};\n",
|
||||||
42,
|
42,
|
||||||
STAGE_CS, 0 },
|
STAGE_CS | STAGE_WW, 1 },
|
||||||
{ "fprintln_file_multi",
|
{ "fprintln_file_multi",
|
||||||
"package main;\n"
|
"package main;\n"
|
||||||
"import os;\n"
|
"import os;\n"
|
||||||
@@ -145,7 +145,7 @@ static const struct row rows[] = {
|
|||||||
" return 43;\n"
|
" return 43;\n"
|
||||||
"};\n",
|
"};\n",
|
||||||
43,
|
43,
|
||||||
STAGE_CS, 0 },
|
STAGE_CS | STAGE_WW, 1 },
|
||||||
{ "fprint_file_raw",
|
{ "fprint_file_raw",
|
||||||
"package main;\n"
|
"package main;\n"
|
||||||
"import os;\n"
|
"import os;\n"
|
||||||
@@ -173,7 +173,7 @@ static const struct row rows[] = {
|
|||||||
" return 44;\n"
|
" return 44;\n"
|
||||||
"};\n",
|
"};\n",
|
||||||
44,
|
44,
|
||||||
STAGE_CS, 0 },
|
STAGE_CS | STAGE_WW, 1 },
|
||||||
{ "branched_fprintf",
|
{ "branched_fprintf",
|
||||||
"package main;\n"
|
"package main;\n"
|
||||||
"import os;\n"
|
"import os;\n"
|
||||||
@@ -206,7 +206,7 @@ static const struct row rows[] = {
|
|||||||
" return 45;\n"
|
" return 45;\n"
|
||||||
"};\n",
|
"};\n",
|
||||||
45,
|
45,
|
||||||
STAGE_CS, 0 },
|
STAGE_CS | STAGE_WW, 1 },
|
||||||
{ "fprintf_stream",
|
{ "fprintf_stream",
|
||||||
"package main;\n"
|
"package main;\n"
|
||||||
"import os;\n"
|
"import os;\n"
|
||||||
@@ -230,7 +230,7 @@ static const struct row rows[] = {
|
|||||||
" return 46;\n"
|
" return 46;\n"
|
||||||
"};\n",
|
"};\n",
|
||||||
46,
|
46,
|
||||||
STAGE_CS, 0 },
|
STAGE_CS | STAGE_WW, 1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -357,7 +357,6 @@ main(void)
|
|||||||
int total = 0, fail = 0;
|
int total = 0, fail = 0;
|
||||||
int wwpresent = (access(wdrv, X_OK) == 0);
|
int wwpresent = (access(wdrv, X_OK) == 0);
|
||||||
int seq = 0;
|
int seq = 0;
|
||||||
(void)asm_byte_identical; /* cstage-only until #226/#227 land */
|
|
||||||
|
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
if (rows[i].stage_mask & STAGE_CS) {
|
if (rows[i].stage_mask & STAGE_CS) {
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ static const struct row rows[] = {
|
|||||||
" return 50;\n"
|
" return 50;\n"
|
||||||
"};\n",
|
"};\n",
|
||||||
50,
|
50,
|
||||||
STAGE_CS, 0 },
|
STAGE_CS | STAGE_WW, 1 },
|
||||||
{ "precision",
|
{ "precision",
|
||||||
"package main;\n"
|
"package main;\n"
|
||||||
"import os;\n"
|
"import os;\n"
|
||||||
@@ -143,7 +143,7 @@ static const struct row rows[] = {
|
|||||||
" return 51;\n"
|
" return 51;\n"
|
||||||
"};\n",
|
"};\n",
|
||||||
51,
|
51,
|
||||||
STAGE_CS, 0 },
|
STAGE_CS | STAGE_WW, 1 },
|
||||||
{ "base_hex",
|
{ "base_hex",
|
||||||
"package main;\n"
|
"package main;\n"
|
||||||
"import os;\n"
|
"import os;\n"
|
||||||
@@ -171,7 +171,7 @@ static const struct row rows[] = {
|
|||||||
" return 52;\n"
|
" return 52;\n"
|
||||||
"};\n",
|
"};\n",
|
||||||
52,
|
52,
|
||||||
STAGE_CS, 0 },
|
STAGE_CS | STAGE_WW, 1 },
|
||||||
{ "sign_plus",
|
{ "sign_plus",
|
||||||
"package main;\n"
|
"package main;\n"
|
||||||
"import os;\n"
|
"import os;\n"
|
||||||
@@ -199,7 +199,7 @@ static const struct row rows[] = {
|
|||||||
" return 53;\n"
|
" return 53;\n"
|
||||||
"};\n",
|
"};\n",
|
||||||
53,
|
53,
|
||||||
STAGE_CS, 0 },
|
STAGE_CS | STAGE_WW, 1 },
|
||||||
{ "zero_pad",
|
{ "zero_pad",
|
||||||
"package main;\n"
|
"package main;\n"
|
||||||
"import os;\n"
|
"import os;\n"
|
||||||
@@ -227,7 +227,7 @@ static const struct row rows[] = {
|
|||||||
" return 54;\n"
|
" return 54;\n"
|
||||||
"};\n",
|
"};\n",
|
||||||
54,
|
54,
|
||||||
STAGE_CS, 0 },
|
STAGE_CS | STAGE_WW, 1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ static const struct row rows[] = {
|
|||||||
" return 60;\n"
|
" return 60;\n"
|
||||||
"};\n",
|
"};\n",
|
||||||
60,
|
60,
|
||||||
STAGE_CS, 0 },
|
STAGE_CS | STAGE_WW, 1 },
|
||||||
{ "fprintfln_file_fmt",
|
{ "fprintfln_file_fmt",
|
||||||
"package main;\n"
|
"package main;\n"
|
||||||
"import os;\n"
|
"import os;\n"
|
||||||
@@ -153,7 +153,7 @@ static const struct row rows[] = {
|
|||||||
" return 61;\n"
|
" return 61;\n"
|
||||||
"};\n",
|
"};\n",
|
||||||
61,
|
61,
|
||||||
STAGE_CS, 0 },
|
STAGE_CS | STAGE_WW, 1 },
|
||||||
{ "fprintln_basic",
|
{ "fprintln_basic",
|
||||||
"package main;\n"
|
"package main;\n"
|
||||||
"import os;\n"
|
"import os;\n"
|
||||||
@@ -180,7 +180,7 @@ static const struct row rows[] = {
|
|||||||
" return 64;\n"
|
" return 64;\n"
|
||||||
"};\n",
|
"};\n",
|
||||||
64,
|
64,
|
||||||
STAGE_CS, 0 },
|
STAGE_CS | STAGE_WW, 1 },
|
||||||
{ "fprintfln_basic",
|
{ "fprintfln_basic",
|
||||||
"package main;\n"
|
"package main;\n"
|
||||||
"import os;\n"
|
"import os;\n"
|
||||||
@@ -205,7 +205,7 @@ static const struct row rows[] = {
|
|||||||
" return 65;\n"
|
" return 65;\n"
|
||||||
"};\n",
|
"};\n",
|
||||||
65,
|
65,
|
||||||
STAGE_CS, 0 },
|
STAGE_CS | STAGE_WW, 1 },
|
||||||
{ "bsprintf_basic",
|
{ "bsprintf_basic",
|
||||||
"package main;\n"
|
"package main;\n"
|
||||||
"import os;\n"
|
"import os;\n"
|
||||||
@@ -226,7 +226,7 @@ static const struct row rows[] = {
|
|||||||
" return 62;\n"
|
" return 62;\n"
|
||||||
"};\n",
|
"};\n",
|
||||||
62,
|
62,
|
||||||
STAGE_CS, 0 },
|
STAGE_CS | STAGE_WW, 1 },
|
||||||
{ "asprintf_basic",
|
{ "asprintf_basic",
|
||||||
"package main;\n"
|
"package main;\n"
|
||||||
"import os;\n"
|
"import os;\n"
|
||||||
@@ -242,7 +242,7 @@ static const struct row rows[] = {
|
|||||||
" return 63;\n"
|
" return 63;\n"
|
||||||
"};\n",
|
"};\n",
|
||||||
63,
|
63,
|
||||||
STAGE_CS, 0 },
|
STAGE_CS | STAGE_WW, 1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|||||||
Reference in New Issue
Block a user