wcc: build generated labels at their exact size
This commit is contained in:
@@ -822,40 +822,35 @@ fn emitoff(v: i64) void = {
|
||||
// avoid cross-module same-leaf collisions (task #13); w6a accepts
|
||||
// '.' in label-cont (lex.c:18).
|
||||
fn mklabel(c: *cgen, prefix: str) str = {
|
||||
let buf: [128]u8;
|
||||
let i: i32 = 0;
|
||||
let mname: str = c.curmod;
|
||||
let fname: str = c.fnname;
|
||||
let ns: str = strconv.i64tos(c.labelseq: i64, strconv.base.DEC);
|
||||
c.labelseq += 1;
|
||||
let total: i32 = mname.len + fname.len + prefix.len + ns.len + 2;
|
||||
if (mname.len > 0) { total += 1; };
|
||||
let p: []u8 = alloc([], (total: u64) + 1u64)!;
|
||||
let i: i32 = 0;
|
||||
let j: i32 = 0;
|
||||
for (j < mname.len) {
|
||||
buf[i] = mname[j];
|
||||
p[i] = mname[j];
|
||||
i += 1; j += 1;
|
||||
};
|
||||
if (mname.len > 0) { buf[i] = '.'; i += 1; };
|
||||
let fname: str = c.fnname;
|
||||
if (mname.len > 0) { p[i] = '.'; i += 1; };
|
||||
j = 0;
|
||||
for (j < fname.len) {
|
||||
buf[i] = fname[j];
|
||||
p[i] = fname[j];
|
||||
i += 1; j += 1;
|
||||
};
|
||||
buf[i] = '_'; i += 1;
|
||||
p[i] = '_'; i += 1;
|
||||
j = 0;
|
||||
for (j < prefix.len) {
|
||||
buf[i] = prefix[j];
|
||||
p[i] = prefix[j];
|
||||
i += 1; j += 1;
|
||||
};
|
||||
buf[i] = '_'; i += 1;
|
||||
let ns: str = strconv.i64tos(c.labelseq: i64, strconv.base.DEC);
|
||||
p[i] = '_'; i += 1;
|
||||
let n: i32 = ns.len;
|
||||
let dk: i32 = 0;
|
||||
for (dk < n) { buf[i + dk] = ns.ptr[dk]; dk += 1; };
|
||||
c.labelseq += 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;
|
||||
};
|
||||
for (dk < n) { p[i + dk] = ns.ptr[dk]; dk += 1; };
|
||||
p[total] = 0u8;
|
||||
let r: str;
|
||||
r.ptr = p.ptr;
|
||||
@@ -917,22 +912,20 @@ fn internstrlit(c: *cgen, bytes: str) str = {
|
||||
// #49: per-unit prefix so two str-bearing packages don't both emit
|
||||
// `_S_0`.. and collide at w6l link. Pure function of the module path
|
||||
// (matching mklabel's spelling), so the self-host fixed-point holds.
|
||||
let buf: [128]u8;
|
||||
let i: i32 = 0;
|
||||
let mname: str = c.curmod;
|
||||
let j: i32 = 0;
|
||||
for (j < mname.len) { buf[i] = mname[j]; i += 1; j += 1; };
|
||||
if (mname.len > 0) { buf[i] = '.'; i += 1; };
|
||||
buf[i] = 95u8; i += 1; buf[i] = 83u8; i += 1; buf[i] = 95u8; i += 1; // "_S_"
|
||||
let ns: str = strconv.i64tos(c.strlitseq: i64, strconv.base.DEC);
|
||||
c.strlitseq += 1;
|
||||
let total: i32 = mname.len + ns.len + 3;
|
||||
if (mname.len > 0) { total += 1; };
|
||||
let p: []u8 = alloc([], (total: u64) + 1u64)!;
|
||||
let i: i32 = 0;
|
||||
let j: i32 = 0;
|
||||
for (j < mname.len) { p[i] = mname[j]; i += 1; j += 1; };
|
||||
if (mname.len > 0) { p[i] = '.'; i += 1; };
|
||||
p[i] = 95u8; i += 1; p[i] = 83u8; i += 1; p[i] = 95u8; i += 1;
|
||||
let n: i32 = ns.len;
|
||||
let dk: i32 = 0;
|
||||
for (dk < n) { buf[i + dk] = ns.ptr[dk]; dk += 1; };
|
||||
c.strlitseq += 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; };
|
||||
for (dk < n) { p[i + dk] = ns.ptr[dk]; dk += 1; };
|
||||
p[total] = 0u8;
|
||||
let lab: str;
|
||||
lab.ptr = p.ptr;
|
||||
|
||||
@@ -338,3 +338,65 @@ fn strdefcheck(label: str, stage: str, s: str, sym: str, wantlea: str,
|
||||
"export fn main() i32 = { return 0; };\n"),
|
||||
"TEXT beta.bfn", "LEAQ\tbeta._S_", "alpha.MSG(SB)");
|
||||
};
|
||||
|
||||
fn longident(prefix: str) str = {
|
||||
let run: str = "nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn";
|
||||
return strings.concat(prefix, run, run, run);
|
||||
};
|
||||
|
||||
@test fn longgeneratednames() void = {
|
||||
let fnname: str = longident("f");
|
||||
let fsrc: str = strings.concat(
|
||||
"package main;\n",
|
||||
"fn ", fnname, "() i32 = {\n",
|
||||
" if (true) { return 42; };\n",
|
||||
" return 1;\n",
|
||||
"};\n",
|
||||
"export fn main() i32 = { return ", fnname, "(); };\n");
|
||||
let ftd: str = testenv.fresh();
|
||||
testenv.writefile(strings.concat(ftd, "/src.ww"), fsrc);
|
||||
emitstage(ftd, "long_function_label", "cstage",
|
||||
testenv.driver("w6c"), "cs.s");
|
||||
emitstage(ftd, "long_function_label", "wwstage",
|
||||
testenv.driver("w6c_ww"), "ws.s");
|
||||
let fcs: str = testenv.readfile(strings.concat(ftd, "/cs.s"));
|
||||
let fws: str = testenv.readfile(strings.concat(ftd, "/ws.s"));
|
||||
let textneedle: str = strings.concat("TEXT main.", fnname, ",$0");
|
||||
let labelneedle: str = strings.concat("main.", fnname, "_end_");
|
||||
if (!testenv.has(fcs, textneedle) || !testenv.has(fws, textneedle)
|
||||
|| !testenv.has(fcs, labelneedle) || !testenv.has(fws, labelneedle)) {
|
||||
fail("long_function_label", "full generated label missing");
|
||||
};
|
||||
if (!testenv.same(fcs, fws)) {
|
||||
fail("long_function_label", "cstage vs wwstage asm differs");
|
||||
};
|
||||
testenv.clean(ftd);
|
||||
|
||||
let modname: str = longident("p");
|
||||
let ssrc: str = strings.concat(
|
||||
"package ", modname, ";\n",
|
||||
"export fn f() i32 = {\n",
|
||||
" let s: str = \"x\";\n",
|
||||
" return s.len;\n",
|
||||
"};\n");
|
||||
let std: str = testenv.fresh();
|
||||
testenv.writefile(strings.concat(std, "/src.ww"), ssrc);
|
||||
emitstage(std, "long_strlit_label", "cstage",
|
||||
testenv.driver("w6c"), "cs.s");
|
||||
emitstage(std, "long_strlit_label", "wwstage",
|
||||
testenv.driver("w6c_ww"), "ws.s");
|
||||
let scs: str = testenv.readfile(strings.concat(std, "/cs.s"));
|
||||
let sws: str = testenv.readfile(strings.concat(std, "/ws.s"));
|
||||
let leaneedle: str = strings.concat("LEAQ\t", modname,
|
||||
"._S_0(SB), AX");
|
||||
let dataneedle: str = strings.concat("DATA ", modname,
|
||||
"._S_0(SB),\"x\\x00\"");
|
||||
if (!testenv.has(scs, leaneedle) || !testenv.has(sws, leaneedle)
|
||||
|| !testenv.has(scs, dataneedle) || !testenv.has(sws, dataneedle)) {
|
||||
fail("long_strlit_label", "full DATA/LEAQ label missing");
|
||||
};
|
||||
if (!testenv.same(scs, sws)) {
|
||||
fail("long_strlit_label", "cstage vs wwstage asm differs");
|
||||
};
|
||||
testenv.clean(std);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user