This commit is contained in:
@@ -15359,6 +15359,25 @@ emit_lets(Cg *c, FILE *out, Node *file)
|
||||
Node *r = d->rhs;
|
||||
while (r != NULL && r->kind == N_CAST) r = r->lhs;
|
||||
if (r == NULL) continue;
|
||||
/* #119: a scalar `&fn` global — 8B zero ptr
|
||||
* placeholder + the &fn->DATAR reloc (the #117
|
||||
* helper at its second consumer). Pre-#119 this
|
||||
* fell through fold_int_literal -> continue -> no
|
||||
* DATA -> undefined ref / garbage deref. */
|
||||
{
|
||||
const char *fsym = node_fnptr_sym(c, r);
|
||||
if (fsym != NULL) {
|
||||
const char *sym = mod_mangle_value(c,
|
||||
d->str, d->module);
|
||||
fprintf(out, "DATAW %s(SB),\"", sym);
|
||||
for (int i = 0; i < 8; i++)
|
||||
emit_data_byte(out, 0);
|
||||
fputs("\"\n", out);
|
||||
fprintf(out, "DATAR %s+0(SB),%s(SB)\n",
|
||||
sym, fsym);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* Same helper as emit_defs (#24): widens
|
||||
* the gate to cover N_UN(TK_MINUS/TILDE/PLUS,
|
||||
* leaf) so `let x: i8 = -1i8;` and friends
|
||||
|
||||
@@ -40247,8 +40247,10 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
if (sz == 8 && !issg && fsz == 0 && !isarr8 && !istup && !istagged) {
|
||||
let v: u64 = 0u64;
|
||||
let ok: bool = true;
|
||||
let fnp: bool = false;
|
||||
let r: *node = nil;
|
||||
if (d.rhs != nil) {
|
||||
let r: *node = d.rhs;
|
||||
r = d.rhs;
|
||||
for (r != nil) {
|
||||
if (r.kind != nkind.N_CAST) { break; };
|
||||
r = r.lhs;
|
||||
@@ -40258,9 +40260,24 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
// int leaf folds. `let x: i8 = -1i8;`
|
||||
// arrives as N_UN(TK_MINUS, N_INTLIT)
|
||||
// after the typed-AST cast peel.
|
||||
ok = foldintliteral(r, &v);
|
||||
// #119: a scalar `&fn` global — the &fn->DATAR
|
||||
// reloc (the #117 helper at its second consumer).
|
||||
if (nodefnptr(c, r)) { fnp = true; }
|
||||
else { ok = foldintliteral(r, &v); };
|
||||
};
|
||||
if (ok) {
|
||||
if (fnp) {
|
||||
emitline("DATAW ");
|
||||
emitsymnamehint(c, nm, d.nmod);
|
||||
emitline("(SB),\"");
|
||||
let zi: i32 = 0;
|
||||
for (zi < 8) { emitdatawbyte(0u8); zi += 1; };
|
||||
emitline("\"\n");
|
||||
emitline("DATAR ");
|
||||
emitsymnamehint(c, nm, d.nmod);
|
||||
emitline("+0(SB),");
|
||||
emitfnname(c, r.lhs.str, c.curmod);
|
||||
emitline("(SB)\n");
|
||||
} else if (ok) {
|
||||
emitline("DATAW ");
|
||||
emitsymnamehint(c, nm, d.nmod);
|
||||
emitline("(SB),\"");
|
||||
|
||||
@@ -2693,8 +2693,10 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
if (sz == 8 && !issg && fsz == 0 && !isarr8 && !istup && !istagged) {
|
||||
let v: u64 = 0u64;
|
||||
let ok: bool = true;
|
||||
let fnp: bool = false;
|
||||
let r: *node = nil;
|
||||
if (d.rhs != nil) {
|
||||
let r: *node = d.rhs;
|
||||
r = d.rhs;
|
||||
for (r != nil) {
|
||||
if (r.kind != nkind.N_CAST) { break; };
|
||||
r = r.lhs;
|
||||
@@ -2704,9 +2706,24 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
// int leaf folds. `let x: i8 = -1i8;`
|
||||
// arrives as N_UN(TK_MINUS, N_INTLIT)
|
||||
// after the typed-AST cast peel.
|
||||
ok = foldintliteral(r, &v);
|
||||
// #119: a scalar `&fn` global — the &fn->DATAR
|
||||
// reloc (the #117 helper at its second consumer).
|
||||
if (nodefnptr(c, r)) { fnp = true; }
|
||||
else { ok = foldintliteral(r, &v); };
|
||||
};
|
||||
if (ok) {
|
||||
if (fnp) {
|
||||
emitline("DATAW ");
|
||||
emitsymnamehint(c, nm, d.nmod);
|
||||
emitline("(SB),\"");
|
||||
let zi: i32 = 0;
|
||||
for (zi < 8) { emitdatawbyte(0u8); zi += 1; };
|
||||
emitline("\"\n");
|
||||
emitline("DATAR ");
|
||||
emitsymnamehint(c, nm, d.nmod);
|
||||
emitline("+0(SB),");
|
||||
emitfnname(c, r.lhs.str, c.curmod);
|
||||
emitline("(SB)\n");
|
||||
} else if (ok) {
|
||||
emitline("DATAW ");
|
||||
emitsymnamehint(c, nm, d.nmod);
|
||||
emitline("(SB),\"");
|
||||
|
||||
@@ -40247,8 +40247,10 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
if (sz == 8 && !issg && fsz == 0 && !isarr8 && !istup && !istagged) {
|
||||
let v: u64 = 0u64;
|
||||
let ok: bool = true;
|
||||
let fnp: bool = false;
|
||||
let r: *node = nil;
|
||||
if (d.rhs != nil) {
|
||||
let r: *node = d.rhs;
|
||||
r = d.rhs;
|
||||
for (r != nil) {
|
||||
if (r.kind != nkind.N_CAST) { break; };
|
||||
r = r.lhs;
|
||||
@@ -40258,9 +40260,24 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
||||
// int leaf folds. `let x: i8 = -1i8;`
|
||||
// arrives as N_UN(TK_MINUS, N_INTLIT)
|
||||
// after the typed-AST cast peel.
|
||||
ok = foldintliteral(r, &v);
|
||||
// #119: a scalar `&fn` global — the &fn->DATAR
|
||||
// reloc (the #117 helper at its second consumer).
|
||||
if (nodefnptr(c, r)) { fnp = true; }
|
||||
else { ok = foldintliteral(r, &v); };
|
||||
};
|
||||
if (ok) {
|
||||
if (fnp) {
|
||||
emitline("DATAW ");
|
||||
emitsymnamehint(c, nm, d.nmod);
|
||||
emitline("(SB),\"");
|
||||
let zi: i32 = 0;
|
||||
for (zi < 8) { emitdatawbyte(0u8); zi += 1; };
|
||||
emitline("\"\n");
|
||||
emitline("DATAR ");
|
||||
emitsymnamehint(c, nm, d.nmod);
|
||||
emitline("+0(SB),");
|
||||
emitfnname(c, r.lhs.str, c.curmod);
|
||||
emitline("(SB)\n");
|
||||
} else if (ok) {
|
||||
emitline("DATAW ");
|
||||
emitsymnamehint(c, nm, d.nmod);
|
||||
emitline("(SB),\"");
|
||||
|
||||
@@ -129,6 +129,21 @@ static const struct row rows[] = {
|
||||
" if (len(tbl) != 3) { return 1; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
/* #119: scalar &fn module-globals — DISTINCT fns, each called back
|
||||
* through the reloc (pre-#119: no DATA → undefined ref / garbage). */
|
||||
{ "scalar_fnptr",
|
||||
"package main;\n"
|
||||
"fn fa(c: rune) bool = { return c == 'a'; };\n"
|
||||
"fn fz(c: rune) bool = { return c == 'z'; };\n"
|
||||
"let pf: *fn(c: rune) bool = &fa;\n"
|
||||
"let pg: *fn(c: rune) bool = &fz;\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" if (!(*pf)('a')) { return 1; };\n"
|
||||
" if ((*pf)('z')) { return 2; };\n"
|
||||
" if (!(*pg)('z')) { return 3; };\n"
|
||||
" if ((*pg)('a')) { return 4; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
/* honest boundary (rule 7): a non-tuple aggregate element (here a
|
||||
* bare []str) stays LOUD, symmetric both stages — #117 is NARROW to
|
||||
* the (str,*fn) tuple form, not the full slice-of-aggregate family. */
|
||||
|
||||
Reference in New Issue
Block a user