ref: 4d79fc86e2b3b90faea794feb00fb6841c0957e7
parent: 77c9b908500a4dd502cd94758c51260ec8dda8eb
author: Ori Bernstein <ori@eigenstate.org>
date: Sat May 26 09:24:07 EDT 2018
Initialize the closure before a recursive capture.
--- a/6/simp.c
+++ b/6/simp.c
@@ -960,7 +960,7 @@
capture(Simp *s, Node *n, Node *dst)
{
Node *fn, *t, *f, *e, *val, *dcl, *fp, *envsz;
- size_t nenv, nenvt, off, i;
+ size_t nenv, nenvt, off, sz, i;
Type **envt;
Node **env;
@@ -972,12 +972,15 @@
forcelocal(s, dcl);
}
fp = addr(s, dst, exprtype(dst));
+ assignat(s, fp, Ptrsz, f);
env = getclosure(fn->func.scope, &nenv);
if (env) {
- /* we need these in a deterministic order so that we can
- put them in the right place both when we use them and
- when we capture them. */
+ /*
+ * we need these in a deterministic order so that we can
+ * put them in the right place both when we use them and
+ * when we capture them.
+ */
qsort(env, nenv, sizeof(Node*), envcmp);
/* make the tuple that will hold the environment */
@@ -985,12 +988,19 @@
nenvt = 0;
/* reserve space for size */
lappend(&envt, &nenvt, tyintptr);
- for (i = 0; i < nenv; i++)
+ sz = Ptrsz;
+ for (i = 0; i < nenv; i++) {
lappend(&envt, &nenvt, decltype(env[i]));
+ sz += size(env[i]);
+ }
t = gentemp(n->loc, mktytuple(n->loc, envt, nenvt), &dcl);
forcelocal(s, dcl);
e = addr(s, t, exprtype(t));
+ envsz = mkintlit(n->loc, sz);
+ envsz->expr.type = tyintptr;
+ assignat(s, e, 0, envsz);
+ assignat(s, fp, 0, e);
off = Ptrsz; /* we start with the size of the env */
for (i = 0; i < nenv; i++) {
@@ -1002,10 +1012,6 @@
off += size(env[i]);
}
free(env);
- envsz = mkintlit(n->loc, off);
- envsz->expr.type = tyintptr;
- assignat(s, e, 0, envsz);
- assignat(s, fp, 0, e);
} else {
/*
* We need to zero out the environment, so that
@@ -1016,7 +1022,6 @@
e->expr.type = tyintptr;
assignat(s, fp, 0, e);
}
- assignat(s, fp, Ptrsz, f);
return dst;
}