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]));
}