wwstage: C-FFI variadic call codegen parity with cstage (#10)
Mirror cstage's C-variadic call handling in the ww self-host: parse a bare `...` param (decl.ww), skip param-keyed desugar for it to avoid a nil-deref (check.ww), and emit AL = XMM-reg count plus CVTSS2SD promotion of f32 args in the variadic tail (cgenutil.ww, cgenexpr.ww). Closes the cat-A wwstage silent miscompile (AL=0, unpromoted f32 tail). Parse/check/cgen are one atomic align-up (parse alone miscompiles, so not bisect-splittable). 989_ffivariadic now runs dual-stage (cstage ww + wwstage ww_ww), 12/12; w6c==w6c_ww byte-identical. Byte-id alone is blind here (the bootstrap calls no float-bearing C variadic), so the ww_ww runtime rows are the real net.
This commit is contained in:
@@ -5610,6 +5610,18 @@ fn desugarcallargs(c: *checker, n: *syntax.node) void = {
|
||||
let nexta: *syntax.node = a.next;
|
||||
if (param != nil) {
|
||||
if (param.kind == syntax.nkind.N_PARAM) {
|
||||
// C-style FFI variadic (bare `...`): str=="...",
|
||||
// op != TK_ELLIPSIS, lhs == nil. The `...` absorbs
|
||||
// every remaining arg untyped — mirror cstage
|
||||
// check.c:1860 `if (!u->variadic) ...; continue`.
|
||||
// MANDATORY: this param's lhs is nil, so the per-arg
|
||||
// coercerunelit / checkarrlitfits / desugararrayslice
|
||||
// calls below would deref nil on a rune-literal or
|
||||
// array-literal variadic arg.
|
||||
if (syntax.streq(param.str, "...")
|
||||
&& param.op != syntax.tkind.TK_ELLIPSIS) {
|
||||
break;
|
||||
};
|
||||
if (param.op != syntax.tkind.TK_ELLIPSIS) {
|
||||
let atype: *syntax.node = exprtype(c, a, nil);
|
||||
// #29: a rune literal narrowing into an integer param
|
||||
|
||||
Reference in New Issue
Block a user