ref: c8c4b88ecadf05438561c05f97500e35843218c4
parent: ac306beff772b0a894ca95e0e0d0fe3029c7f8e4
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Sep 27 18:52:17 EDT 2015
Don't index directly off of %rax. We use it for function returns. We also use it for environment of called closures. This means we clobbered it. Oops.
--- a/6/asm.h
+++ b/6/asm.h
@@ -130,7 +130,6 @@
struct Func {
char *name; /* function name */
- int isexport; /* is this exported from the asm? */
Type *type; /* type of function */
Node **args; /* argument list */
@@ -140,7 +139,9 @@
size_t stksz; /* stack size */
Node *ret; /* return value */
- Cfg *cfg; /* flow graph */
+ Cfg *cfg; /* flow graph */
+ char isexport; /* is this exported from the asm? */
+ char hasenv; /* do we have an environment? */
};
struct Asmbb {
@@ -172,6 +173,8 @@
Htab *stkoff; /* decl id => int stkoff */
Htab *envoff; /* decl id => int envoff */
Htab *globls; /* decl id => char *globlname */
+
+ Loc *envp;
/* increased when we spill */
Loc *stksz;
--- a/6/gengas.c
+++ b/6/gengas.c
@@ -351,6 +351,8 @@
is.globls = globls;
is.ret = fn->ret;
is.cfg = fn->cfg;
+ if (fn->hasenv)
+ is.envp = locreg(ModeQ);
selfunc(&is, fn, globls, strtab);
if (debugopt['i'])
--- a/6/genp9.c
+++ b/6/genp9.c
@@ -371,6 +371,8 @@
is.globls = globls;
is.ret = fn->ret;
is.cfg = fn->cfg;
+ if (fn->hasenv)
+ is.envp = locreg(ModeQ);
selfunc(&is, fn, globls, strtab);
if (debugopt['i'])
--- a/6/isel.c
+++ b/6/isel.c
@@ -104,7 +104,7 @@
l = locmeml(htget(s->globls, n), rip, NULL, mode(n));
} else if (hthas(s->envoff, n)) {
off = ptoi(htget(s->envoff, n));
- l = locmem(off, locphysreg(Rrax), NULL, mode(n));
+ l = locmem(off, s->envp, NULL, mode(n));
} else if (hthas(s->stkoff, n)) {
off = ptoi(htget(s->stkoff, n));
l = locmem(-off, locphysreg(Rrbp), NULL, mode(n));
@@ -980,6 +980,8 @@
g(s, Imov, phys, s->calleesave[i], NULL);
}
}
+ if (s->envp)
+ g(s, Imov, locphysreg(Rrax), s->envp, NULL);
addarglocs(s, fn);
s->nsaved = i;
s->stksz = stksz; /* need to update if we spill */
--- a/6/simp.c
+++ b/6/simp.c
@@ -32,7 +32,8 @@
/* return handling */
Node *endlbl;
Node *ret;
- int isbigret;
+ int hasenv;
+ int isbigret;
/* pre/postinc handling */
Node **incqueue;
@@ -1821,11 +1822,14 @@
size_t off;
env = getclosure(fn->func.scope, &nenv);
+ if (!env)
+ return;
/*
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.
*/
+ s->hasenv = 1;
qsort(env, nenv, sizeof(Node*), envcmp);
off = Ptrsz; /* we start with the size of the env */
for (i = 0; i < nenv; i++) {
@@ -1888,6 +1892,7 @@
fn->args = s->args;
fn->nargs = s->nargs;
fn->cfg = cfg;
+ fn->hasenv = s->hasenv;
return fn;
}
@@ -1964,6 +1969,7 @@
s.globls = globls;
s.blobs = *blob;
s.nblobs = *nblob;
+ s.hasenv = 0;
name = asmname(dcl);
if (dcl->decl.isextern || dcl->decl.isgeneric)
--- a/lib/sys/sys+linux-x64.myr
+++ b/lib/sys/sys+linux-x64.myr
@@ -619,7 +619,7 @@
tls : byte#, \
ctid : pid#, \
ptreg : byte#, \
- fn : (-> void) \
+ fn : void# \ /* we need a raw pointer */
-> pid)
const wait4 : (pid:pid, loc:int32#, opt : int64, usage:rusage# -> int64)
const waitpid : (pid:pid, loc:int32#, opt : int64 -> int64)