ref: cb0c1ccdd7525db9d777c86010dc08e7edb4820c
parent: 0e624db312994ed6e74a63187ecf8f3ac6babeb5
author: Ori Bernstein <[email protected]>
date: Mon Jul 16 07:50:01 EDT 2012
Make nested functions work.
--- a/8/asm.h
+++ b/8/asm.h
@@ -31,7 +31,8 @@
Locreg, /* register */
Locmem, /* reg offset mem */
Locmeml, /* label offset mem */
- Loclit,
+ Loclit, /* literal value */
+ // FIXME: later. Loclitl /* label address */
} LocType;
typedef enum {
@@ -178,6 +179,7 @@
Loc *locmems(long disp, Loc *base, Loc *idx, int scale, Mode mode);
Loc *locmemls(char *disp, Loc *base, Loc *idx, int scale, Mode mode);
Loc *loclit(long val);
+/*Loc *loclitl(char *lbl); FIXME: later */
void locprint(FILE *fd, Loc *l, char spec);
void iprintf(FILE *fd, Insn *insn);
--- a/8/insns.def
+++ b/8/insns.def
@@ -54,6 +54,7 @@
/* branch instructions */
Insn(Icall, "\tcall %v\n", Use(.l={1}), Def())
+Insn(Icallind, "\tcall *%v\n", Use(.l={1}), Def())
Insn(Ijmp, "\tjmp %v\n", Use(.l={1}), Def())
Insn(Ijz, "\tjz %v\n", Use(.l={1}), Def())
Insn(Ijnz, "\tjnz %v\n", Use(.l={1}), Def())
--- a/8/isel.c
+++ b/8/isel.c
@@ -396,7 +396,10 @@
argoff += size(n->expr.args[i]);
}
fn = selexpr(s, n->expr.args[0]);
- g(s, Icall, fn, NULL);
+ if (fn->type == Loclbl)
+ g(s, Icall, fn, NULL);
+ else
+ g(s, Icallind, inr(s, fn), NULL);
if (argsz)
g(s, Iadd, stkbump, esp, NULL);
return eax;
@@ -405,7 +408,7 @@
Loc *selexpr(Isel *s, Node *n)
{
Loc *a, *b, *c, *d, *r;
- Loc *eax, *edx, *cl; /* x86 wanst some hard-coded regs */
+ Loc *eax, *edx, *cl; /* x86 wants some hard-coded regs */
Node **args;
args = n->expr.args;
--- a/8/simp.c
+++ b/8/simp.c
@@ -490,19 +490,25 @@
}
}
-static Node *bloblit(Simp *s, Node *lit)
+static Node *lowerlit(Simp *s, Node *lit, Node ***l, size_t *nl)
{
- Node *n, *t, *r;
+ Node *n, *d, *r;
char lbl[128];
n = mkname(lit->line, genlblstr(lbl, 128));
- t = mkdecl(lit->line, n, lit->expr.type);
+ d = mkdecl(lit->line, n, lit->expr.type);
r = mkexpr(lit->line, Ovar, n, NULL);
+
+ d->decl.init = lit;
+ d->decl.type = lit->expr.type;
+ d->decl.isconst = 1;
+ r->expr.did = d->decl.did;
r->expr.type = lit->expr.type;
- r->expr.did = t->decl.did;
- t->decl.init = lit;
- htput(s->globls, t, strdup(lbl));
- lappend(&s->blobs, &s->nblobs, t);
+ if (tybase(r->expr.type)->type == Tyfunc)
+ r = addr(r, tybase(r->expr.type));
+
+ htput(s->globls, d, strdup(lbl));
+ lappend(l, nl, d);
return r;
}
@@ -935,10 +941,10 @@
r = n;
break;
case Lstr: case Lseq: case Lflt:
- r = bloblit(s, n);
+ r = lowerlit(s, n, &s->blobs, &s->nblobs);
break;
case Lfunc:
- die("Func lits not handled yet");
+ r = lowerlit(s, n, &file->file.stmts, &file->file.nstmts);
break;
}
break;
@@ -1177,9 +1183,9 @@
void gen(Node *file, char *out)
{
Htab *globls;
- Node **n, **blob;
+ Node *n, **blob;
Func **fn;
- size_t nn, nfn, nblob;
+ size_t nfn, nblob;
size_t i;
FILE *fd;
@@ -1195,22 +1201,21 @@
nfn = 0;
blob = NULL;
nblob = 0;
- n = file->file.stmts;
- nn = file->file.nstmts;
globls = mkht(dclhash, dcleq);
/* We need to define all global variables before use */
fillglobls(file->file.globls, globls);
- for (i = 0; i < nn; i++) {
- switch (n[i]->type) {
+ for (i = 0; i < file->file.nstmts; i++) {
+ n = file->file.stmts[i];
+ switch (n->type) {
case Nuse: /* nothing to do */
break;
case Ndecl:
- lowerdcl(n[i], globls, &fn, &nfn, &blob, &nblob);
+ lowerdcl(n, globls, &fn, &nfn, &blob, &nblob);
break;
default:
- die("Bad node %s in toplevel", nodestr(n[i]->type));
+ die("Bad node %s in toplevel", nodestr(n->type));
break;
}
}