selfhost/cmd/wcc: route cgalloc CALL through ffiresolve

Wwstage's cgalloc hardcoded `CALL rt_alloc(SB)` at cgenexpr.ww:2747 and
cgenstmt.ww:647. Cstage already routes through ffi_resolve("alloc")
at cmd/w6c/cgen.c:4149 — when a fixture lacks the @symbol("rt_alloc")
decl in scope, cstage falls back to `CALL alloc(SB)` while wwstage
still emits `CALL rt_alloc(SB)`. The divergence is dormant in
ww build (combined.ww always pulls lib/os/os.ww's decl) but activates
under direct `w6c file.ww` and any other single-file path.

Replace the hardcoded line with the ffiresolve(c, "alloc") pattern
already used for user-function calls. The @symbol decl in lib/os/os.ww
is unchanged and propagates via the combine step.

Extends test/wcc/758_cgalloc_str_field.c with 4 table-driven asm rows
that compile a fixture via direct w6c (no combine) and `cmp` the
CALL <sym>(SB) line between stages. The 3 noscope rows fail without
the fix and pass with it; the withsym row pins the positive ffi-hit
path. Test count internal: 12 → 16; total make test: 132/132.
This commit is contained in:
2026-05-20 17:18:32 +09:00
parent af1549d9c5
commit 4c51bce244
5 changed files with 204 additions and 29 deletions

View File

@@ -15953,7 +15953,9 @@ fn cgalloc(c: *cgen, n: *node) void = {
emitline("\tMOVQ\t$");
emitint(sz: i64);
emitline(", DI\n");
emitline("\tCALL\trt_alloc(SB)\n");
emitline("\tCALL\t");
emitline(ffiresolve(c, "alloc"));
emitline("(SB)\n");
emitline("\tCMPQ\t$0, AX\n");
emitline("\tJNE\t"); emitline(okl); emitline("\n");
emitline("\tMOVQ\t$1, AX\n");
@@ -19651,7 +19653,9 @@ fn cglet(c: *cgen, n: *node) void = {
emitline("\tIMULQ\tBX, AX\n");
};
emitline("\tMOVQ\tAX, DI\n");
emitline("\tCALL\trt_alloc(SB)\n");
emitline("\tCALL\t");
emitline(ffiresolve(c, "alloc"));
emitline("(SB)\n");
if (viatryunw) {
let okl: str = mklabel(c, "tryunw_ok");
emitline("\tCMPQ\t$0, AX\n");

View File

@@ -2744,7 +2744,9 @@ fn cgalloc(c: *cgen, n: *node) void = {
emitline("\tMOVQ\t$");
emitint(sz: i64);
emitline(", DI\n");
emitline("\tCALL\trt_alloc(SB)\n");
emitline("\tCALL\t");
emitline(ffiresolve(c, "alloc"));
emitline("(SB)\n");
emitline("\tCMPQ\t$0, AX\n");
emitline("\tJNE\t"); emitline(okl); emitline("\n");
emitline("\tMOVQ\t$1, AX\n");

View File

@@ -644,7 +644,9 @@ fn cglet(c: *cgen, n: *node) void = {
emitline("\tIMULQ\tBX, AX\n");
};
emitline("\tMOVQ\tAX, DI\n");
emitline("\tCALL\trt_alloc(SB)\n");
emitline("\tCALL\t");
emitline(ffiresolve(c, "alloc"));
emitline("(SB)\n");
if (viatryunw) {
let okl: str = mklabel(c, "tryunw_ok");
emitline("\tCMPQ\t$0, AX\n");

View File

@@ -15953,7 +15953,9 @@ fn cgalloc(c: *cgen, n: *node) void = {
emitline("\tMOVQ\t$");
emitint(sz: i64);
emitline(", DI\n");
emitline("\tCALL\trt_alloc(SB)\n");
emitline("\tCALL\t");
emitline(ffiresolve(c, "alloc"));
emitline("(SB)\n");
emitline("\tCMPQ\t$0, AX\n");
emitline("\tJNE\t"); emitline(okl); emitline("\n");
emitline("\tMOVQ\t$1, AX\n");
@@ -19651,7 +19653,9 @@ fn cglet(c: *cgen, n: *node) void = {
emitline("\tIMULQ\tBX, AX\n");
};
emitline("\tMOVQ\tAX, DI\n");
emitline("\tCALL\trt_alloc(SB)\n");
emitline("\tCALL\t");
emitline(ffiresolve(c, "alloc"));
emitline("(SB)\n");
if (viatryunw) {
let okl: str = mklabel(c, "tryunw_ok");
emitline("\tCMPQ\t$0, AX\n");