shithub: mc

Download patch

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)