ref: 4be51eb1ffb5b87d36a9910012bbc513d8a0bd2d
parent: da9b21b4313efbb023d6d7da6417941c6275b181
author: Ori Bernstein <[email protected]>
date: Tue Jan 7 14:45:09 EST 2014
Finish support for const slices off arrays. We still don't work for const slices of slices, although theoreticlaly we could fold them. This change extracts subarrays from compound types, and replaces them with slicable declarations. The bounds must be constant.
--- a/6/isel.c
+++ b/6/isel.c
@@ -1071,6 +1071,9 @@
lo = n->expr.args[1];
hi = n->expr.args[2];
+ /* by this point, all slicing operations should have had their bases
+ * pulled out, and we should have vars with their pseudo-decls in their
+ * place */
if (exprop(base) != Ovar || !base->expr.isconst)
fatal(base->line, "slice base is not a constant value");
loval = getintlit(lo, "lower bound in slice is not constant literal");
@@ -1097,8 +1100,9 @@
writeslice(fd, globls, strtab, n);
break;
default:
- die("Nonliteral initializer for global");
- break;
+ dump(n, stdout);
+ die("Nonliteral initializer for global");
+ break;
}
}
--- a/6/simp.c
+++ b/6/simp.c
@@ -693,22 +693,23 @@
popstab();
}
-static Node *simplit(Simp *s, Node *lit, Node ***l, size_t *nl)
+static Node *simpblob(Simp *s, Node *blob, Node ***l, size_t *nl)
{
Node *n, *d, *r;
char lbl[128];
- n = mkname(lit->line, genlblstr(lbl, 128));
- d = mkdecl(lit->line, n, lit->expr.type);
- r = mkexpr(lit->line, Ovar, n, NULL);
+ n = mkname(blob->line, genlblstr(lbl, 128));
+ d = mkdecl(blob->line, n, blob->expr.type);
+ r = mkexpr(blob->line, Ovar, n, NULL);
- d->decl.init = lit;
- d->decl.type = lit->expr.type;
+ d->decl.init = blob;
+ d->decl.type = blob->expr.type;
d->decl.isconst = 1;
htput(s->globls, d, strdup(lbl));
r->expr.did = d->decl.did;
- r->expr.type = lit->expr.type;
+ r->expr.type = blob->expr.type;
+ r->expr.isconst = 1;
lappend(l, nl, d);
return r;
@@ -1336,13 +1337,13 @@
if (args[0]->lit.intval < 0xffffffff)
r = n;
else
- r = simplit(s, n, &s->blobs, &s->nblobs);
+ r = simpblob(s, n, &s->blobs, &s->nblobs);
break;
case Lstr: case Lflt:
- r = simplit(s, n, &s->blobs, &s->nblobs);
+ r = simpblob(s, n, &s->blobs, &s->nblobs);
break;
case Lfunc:
- r = simplit(s, n, &file->file.stmts, &file->file.nstmts);
+ r = simpblob(s, n, &file->file.stmts, &file->file.nstmts);
break;
}
break;
@@ -1394,7 +1395,7 @@
u = mkexpr(n->line, Olit, t, NULL);
t->lit.type = n->expr.type;
u->expr.type = n->expr.type;
- v = simplit(s, u, &s->blobs, &s->nblobs);
+ v = simpblob(s, u, &s->blobs, &s->nblobs);
r = mkexpr(n->line, Ofmul, v, args[0], NULL);
r->expr.type = n->expr.type;
} else {
@@ -1602,6 +1603,25 @@
free(k);
}
+static void extractsub(Simp *s, Node ***blobs, size_t *nblobs, Node *e)
+{
+ size_t i;
+
+ switch (exprop(e)) {
+ case Oslice:
+ if (exprop(e->expr.args[0]) == Oarr)
+ e->expr.args[0] = simpblob(s, e->expr.args[0], blobs, nblobs);
+ break;
+ case Oarr:
+ case Ostruct:
+ for (i = 0; i < e->expr.nargs; i++)
+ extractsub(s, blobs, nblobs, e->expr.args[i]);
+ break;
+ default:
+ break;
+ }
+}
+
static void simpconstinit(Simp *s, Node *dcl)
{
Node *e;
@@ -1610,7 +1630,7 @@
e = dcl->decl.init;
if (e && exprop(e) == Olit) {
if (e->expr.args[0]->lit.littype == Lfunc)
- simplit(s, e->expr.args[0], &file->file.stmts, &file->file.nstmts);
+ simpblob(s, e->expr.args[0], &file->file.stmts, &file->file.nstmts);
else
lappend(&s->blobs, &s->nblobs, dcl);
} else if (dcl->decl.isconst) {
@@ -1618,6 +1638,7 @@
case Oarr:
case Ostruct:
case Oslice:
+ extractsub(s, &s->blobs, &s->nblobs, e);
lappend(&s->blobs, &s->nblobs, dcl);
break;
default:
--- a/test/tests
+++ b/test/tests
@@ -41,7 +41,7 @@
B structasn E 42
B structarray E 42
B structret E 42
-B constslice P 23
+B constslice P 2312345678
B exportmain E 42
B slalloc E 123
B neststruct E 3