This commit is contained in:
@@ -15359,6 +15359,25 @@ emit_lets(Cg *c, FILE *out, Node *file)
|
|||||||
Node *r = d->rhs;
|
Node *r = d->rhs;
|
||||||
while (r != NULL && r->kind == N_CAST) r = r->lhs;
|
while (r != NULL && r->kind == N_CAST) r = r->lhs;
|
||||||
if (r == NULL) continue;
|
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
|
/* Same helper as emit_defs (#24): widens
|
||||||
* the gate to cover N_UN(TK_MINUS/TILDE/PLUS,
|
* the gate to cover N_UN(TK_MINUS/TILDE/PLUS,
|
||||||
* leaf) so `let x: i8 = -1i8;` and friends
|
* 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) {
|
if (sz == 8 && !issg && fsz == 0 && !isarr8 && !istup && !istagged) {
|
||||||
let v: u64 = 0u64;
|
let v: u64 = 0u64;
|
||||||
let ok: bool = true;
|
let ok: bool = true;
|
||||||
|
let fnp: bool = false;
|
||||||
|
let r: *node = nil;
|
||||||
if (d.rhs != nil) {
|
if (d.rhs != nil) {
|
||||||
let r: *node = d.rhs;
|
r = d.rhs;
|
||||||
for (r != nil) {
|
for (r != nil) {
|
||||||
if (r.kind != nkind.N_CAST) { break; };
|
if (r.kind != nkind.N_CAST) { break; };
|
||||||
r = r.lhs;
|
r = r.lhs;
|
||||||
@@ -40258,9 +40260,24 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
|||||||
// int leaf folds. `let x: i8 = -1i8;`
|
// int leaf folds. `let x: i8 = -1i8;`
|
||||||
// arrives as N_UN(TK_MINUS, N_INTLIT)
|
// arrives as N_UN(TK_MINUS, N_INTLIT)
|
||||||
// after the typed-AST cast peel.
|
// 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 ");
|
emitline("DATAW ");
|
||||||
emitsymnamehint(c, nm, d.nmod);
|
emitsymnamehint(c, nm, d.nmod);
|
||||||
emitline("(SB),\"");
|
emitline("(SB),\"");
|
||||||
|
|||||||
@@ -2693,8 +2693,10 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
|||||||
if (sz == 8 && !issg && fsz == 0 && !isarr8 && !istup && !istagged) {
|
if (sz == 8 && !issg && fsz == 0 && !isarr8 && !istup && !istagged) {
|
||||||
let v: u64 = 0u64;
|
let v: u64 = 0u64;
|
||||||
let ok: bool = true;
|
let ok: bool = true;
|
||||||
|
let fnp: bool = false;
|
||||||
|
let r: *node = nil;
|
||||||
if (d.rhs != nil) {
|
if (d.rhs != nil) {
|
||||||
let r: *node = d.rhs;
|
r = d.rhs;
|
||||||
for (r != nil) {
|
for (r != nil) {
|
||||||
if (r.kind != nkind.N_CAST) { break; };
|
if (r.kind != nkind.N_CAST) { break; };
|
||||||
r = r.lhs;
|
r = r.lhs;
|
||||||
@@ -2704,9 +2706,24 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
|||||||
// int leaf folds. `let x: i8 = -1i8;`
|
// int leaf folds. `let x: i8 = -1i8;`
|
||||||
// arrives as N_UN(TK_MINUS, N_INTLIT)
|
// arrives as N_UN(TK_MINUS, N_INTLIT)
|
||||||
// after the typed-AST cast peel.
|
// 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 ");
|
emitline("DATAW ");
|
||||||
emitsymnamehint(c, nm, d.nmod);
|
emitsymnamehint(c, nm, d.nmod);
|
||||||
emitline("(SB),\"");
|
emitline("(SB),\"");
|
||||||
|
|||||||
@@ -40247,8 +40247,10 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
|||||||
if (sz == 8 && !issg && fsz == 0 && !isarr8 && !istup && !istagged) {
|
if (sz == 8 && !issg && fsz == 0 && !isarr8 && !istup && !istagged) {
|
||||||
let v: u64 = 0u64;
|
let v: u64 = 0u64;
|
||||||
let ok: bool = true;
|
let ok: bool = true;
|
||||||
|
let fnp: bool = false;
|
||||||
|
let r: *node = nil;
|
||||||
if (d.rhs != nil) {
|
if (d.rhs != nil) {
|
||||||
let r: *node = d.rhs;
|
r = d.rhs;
|
||||||
for (r != nil) {
|
for (r != nil) {
|
||||||
if (r.kind != nkind.N_CAST) { break; };
|
if (r.kind != nkind.N_CAST) { break; };
|
||||||
r = r.lhs;
|
r = r.lhs;
|
||||||
@@ -40258,9 +40260,24 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
|||||||
// int leaf folds. `let x: i8 = -1i8;`
|
// int leaf folds. `let x: i8 = -1i8;`
|
||||||
// arrives as N_UN(TK_MINUS, N_INTLIT)
|
// arrives as N_UN(TK_MINUS, N_INTLIT)
|
||||||
// after the typed-AST cast peel.
|
// 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 ");
|
emitline("DATAW ");
|
||||||
emitsymnamehint(c, nm, d.nmod);
|
emitsymnamehint(c, nm, d.nmod);
|
||||||
emitline("(SB),\"");
|
emitline("(SB),\"");
|
||||||
|
|||||||
@@ -129,6 +129,21 @@ static const struct row rows[] = {
|
|||||||
" if (len(tbl) != 3) { return 1; };\n"
|
" if (len(tbl) != 3) { return 1; };\n"
|
||||||
" return 0;\n"
|
" return 0;\n"
|
||||||
"};\n", 0, K_RUN, NULL },
|
"};\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
|
/* honest boundary (rule 7): a non-tuple aggregate element (here a
|
||||||
* bare []str) stays LOUD, symmetric both stages — #117 is NARROW to
|
* bare []str) stays LOUD, symmetric both stages — #117 is NARROW to
|
||||||
* the (str,*fn) tuple form, not the full slice-of-aggregate family. */
|
* the (str,*fn) tuple form, not the full slice-of-aggregate family. */
|
||||||
|
|||||||
Reference in New Issue
Block a user