shithub: mc

Download patch

ref: 63780713d12f169f36b758d1b4cc7a1dc60f459e
parent: 2fecc0b35b964469479c81cab2ebf5359f2bab89
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Mar 26 18:06:47 EDT 2015

Generate type descriptions for valists.

    the formatting test is still broken, but everything else
    seems to be working.

--- a/6/asm.h
+++ b/6/asm.h
@@ -224,6 +224,7 @@
 Loc *loclit(long val, Mode m);
 Loc *loclitl(char *lbl);
 char *asmname(Node *dcl);
+char *tydescid(char *buf, size_t bufsz, Type *ty);
 Loc *coreg(Reg r, Mode m);
 int isfloatmode(Mode m);
 int isintmode(Mode m);
--- a/6/gen.c
+++ b/6/gen.c
@@ -74,6 +74,30 @@
     return strdup(buf);
 }
 
+char *tydescid(char *buf, size_t bufsz, Type *ty)
+{
+    char *sep, *ns;
+
+    sep = "";
+    ns = "";
+    if (ty->type == Tyname) {
+        if (ty->name->name.ns) {
+            ns = ty->name->name.ns;
+            sep = "$";
+        }
+        if (ty->vis == Visexport || ty->isimport)
+            snprintf(buf, bufsz, "_tydesc$%s%s%s", ns, sep, ty->name->name.name);
+        else
+            snprintf(buf, bufsz, "_tydesc$%s%s%s$%d", ns, sep, ty->name->name.name, ty->tid);
+    } else {
+        if (file->file.globls->name) {
+            ns = file->file.globls->name;
+            sep = "$";
+        }
+        snprintf(buf, bufsz, "_tydesc%s%s$%d",sep, ns, ty->tid);
+    }
+    return buf;
+}
 
 void gen(Node *file, char *out)
 {
--- a/6/gengas.c
+++ b/6/gengas.c
@@ -487,23 +487,6 @@
     writeasm(fd, &is, fn);
 }
 
-static char *tydescid(char *buf, size_t bufsz, Type *ty)
-{
-    char *sep, *ns;
-
-    sep = "";
-    ns = "";
-    if (ty->name->name.ns) {
-        ns = ty->name->name.ns;
-        sep = "$";
-    }
-    if (ty->vis == Visexport || ty->isimport)
-        snprintf(buf, bufsz, "_tydesc$%s%s%s", ns, sep, ty->name->name.name);
-    else
-        snprintf(buf, bufsz, "_tydesc$%d$%s%s%s", ty->tid, ns, sep, ty->name->name.name);
-    return buf;
-}
-
 static void genstructmemb(FILE *fd, Node *sdecl)
 {
     fprintf(fd, "\t.ascii \"%s\" /* struct member */\n", namestr(sdecl->decl.name));
@@ -567,6 +550,7 @@
                 gentydesc(fd, ty->sub[i]);
             break;
         case Tytuple:
+            fprintf(fd, "\t.byte %zd\n", ty->nsub);
             for (i = 0; i < ty->nsub; i++)
                 gentydesc(fd, ty->sub[i]);
             break;
@@ -588,15 +572,16 @@
 {
     char buf[512];
 
+    tydescid(buf, sizeof buf, ty);
     if (ty->type == Tyname) {
         if (hasparams(ty))
             return;
-        tydescid(buf, sizeof buf, ty);
         if (ty->vis == Visexport)
             fprintf(fd, ".globl %s /* tid: %d */\n", buf, ty->tid);
         fprintf(fd, "%s:\n", buf);
         gentydesc(fd, ty->sub[0]);
     } else {
+        fprintf(fd, "%s:\n", buf);
         gentydesc(fd, ty);
     }
 }
--- a/6/simp.c
+++ b/6/simp.c
@@ -1237,6 +1237,55 @@
     return r;
 }
 
+static int isvariadic(Node *fn)
+{
+    Type *ty;
+
+    ty = exprtype(fn);
+    return tybase(ty->sub[ty->nsub - 1])->type == Tyvalist;
+}
+
+static void addvatype(Simp *s, Node *n)
+{
+    Node *ti, *tp, *td, *tn;
+    Type *ft, *vt, **st;
+    size_t nst, i;
+    char buf[1024];
+
+    st = NULL;
+    nst = 0;
+    ft = exprtype(n->expr.args[0]);
+    /* The structure of ft->sub:
+     *   [return, normal, args, ...]
+     *
+     * The structure of n->expr.sub:
+     *    [fn, normal, args, , variadic, args]
+     *
+     * We want to start at variadic, so we want
+     * to count from ft->nsub - 1, up to n->expr.nsub.
+     */
+    for (i = ft->nsub - 1; i < n->expr.nargs; i++)
+        lappend(&st, &nst, exprtype(n->expr.args[i]));
+    vt = mktytuple(n->loc, st, nst);
+    vt->isreflect = 1;
+
+    /* make the decl */
+    tn = mkname(Zloc, tydescid(buf, sizeof buf, vt));
+    td = mkdecl(Zloc, tn, mktype(n->loc, Tybyte));
+
+    /* and the var */
+    ti = mkexpr(Zloc, Ovar, tn, NULL);
+    ti->expr.type = td->decl.type;
+    ti->expr.did = td->decl.did;
+
+    /* and the pointer */
+    tp = mkexpr(Zloc, Oaddr, ti);
+    tp->expr.type = mktyptr(n->loc, td->decl.type);
+
+    linsert(&n->expr.args, &n->expr.nargs, ft->nsub - 1, tp);
+    htput(s->globls, td, asmname(td));
+}
+
 static Node *rval(Simp *s, Node *n, Node *dst)
 {
     Node *t, *u, *v; /* temporary nodes */
@@ -1411,6 +1460,8 @@
             r = assign(s, args[0], args[1]);
             break;
         case Ocall:
+            if (isvariadic(n->expr.args[0]))
+                addvatype(s, n);
             if (exprtype(n)->type != Tyvoid && stacktype(exprtype(n))) {
                 if (dst)
                     r = dst;
--- a/libstd/syscall+linux-x64.s
+++ b/libstd/syscall+linux-x64.s
@@ -9,6 +9,7 @@
 	pushq %r9
 	pushq %rcx 
 	pushq %r11 
+
 	/*
 	hack: We load 6 args regardless of
 	how many we actually have. This may
@@ -17,12 +18,12 @@
 	harmless.
 	 */
 	movq 80 (%rsp),%rax
-	movq 88 (%rsp),%rdi
-	movq 96 (%rsp),%rsi
-	movq 104(%rsp),%rdx
-	movq 112(%rsp),%r10
-	movq 120(%rsp),%r8
-	movq 128(%rsp),%r9
+	movq 96 (%rsp),%rdi
+	movq 104(%rsp),%rsi
+	movq 112(%rsp),%rdx
+	movq 120(%rsp),%r10
+	movq 128(%rsp),%r8
+	movq 136(%rsp),%r9
 
 	syscall
 
--- a/libstd/varargs.myr
+++ b/libstd/varargs.myr
@@ -19,7 +19,10 @@
  * force varargs onto the stack regardless.
  */
 const vastart = {args
-	-> args castto(valist)
+	var ap, dump : byte#
+
+	(dump, ap) = vanext(args castto(valist))
+	-> ap
 }
 
 generic vanext = {ap -> (@a, valist)
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -133,6 +133,7 @@
             nargs = n->expr.nargs;
             t1 = NULL;
             t2 = NULL;
+            t3 = NULL;
             if (exprop(n) == Ovar)
                 d = namestr(args[0]);
             else
@@ -184,6 +185,7 @@
             free(t);
             free(t1);
             free(t2);
+            free(t3);
             s = strdup(buf);
             break;
     }
@@ -469,6 +471,7 @@
     int isgeneric;
     Type *t;
 
+    assert(orig != NULL);
     t = tysearch(orig);
     isgeneric = t->type == Tygeneric;
     st->ingeneric += isgeneric;
@@ -906,6 +909,14 @@
     return r;
 }
 
+static void markvatypes(Type **types, size_t ntypes)
+{
+    size_t i;
+
+    for (i = 0; i < ntypes; i++)
+        types[i]->isreflect = 1;
+}
+
 /* Applies unifications to function calls.
  * Funciton application requires a slightly
  * different approach to unification. */
@@ -933,8 +944,10 @@
             fatal(n, "%s arity mismatch (expected %zd args, got %zd)",
                   ctxstr(st, n->expr.args[0]), ft->nsub - 1, n->expr.nargs - 1);
 
-        if (ft->sub[i]->type == Tyvalist)
+        if (ft->sub[i]->type == Tyvalist) {
+            markvatypes(&ft->sub[i], ft->nsub - i);
             break;
+        }
         inferexpr(st, &n->expr.args[i], NULL, NULL);
         unify(st, n->expr.args[0], ft->sub[i], type(st, n->expr.args[i]));
     }