summaryrefslogtreecommitdiff
path: root/6
diff options
context:
space:
mode:
Diffstat (limited to '6')
-rw-r--r--6/asm.h1
-rw-r--r--6/gen.c24
-rw-r--r--6/gengas.c21
-rw-r--r--6/simp.c51
4 files changed, 79 insertions, 18 deletions
diff --git a/6/asm.h b/6/asm.h
index 50fe20a..31599b2 100644
--- a/6/asm.h
+++ b/6/asm.h
@@ -224,6 +224,7 @@ Loc *locmemls(char *disp, Loc *base, Loc *idx, int scale, Mode mode);
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);
diff --git a/6/gen.c b/6/gen.c
index 2f1a937..d45cb40 100644
--- a/6/gen.c
+++ b/6/gen.c
@@ -74,6 +74,30 @@ char *asmname(Node *dcl)
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)
{
diff --git a/6/gengas.c b/6/gengas.c
index 0cddd57..2013375 100644
--- a/6/gengas.c
+++ b/6/gengas.c
@@ -487,23 +487,6 @@ void genfunc(FILE *fd, Func *fn, Htab *globls, Htab *strtab)
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 @@ static void gentydesc(FILE *fd, Type *ty)
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 @@ void gentype(FILE *fd, Type *ty)
{
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);
}
}
diff --git a/6/simp.c b/6/simp.c
index 6ee4faa..2f8dc4b 100644
--- a/6/simp.c
+++ b/6/simp.c
@@ -1237,6 +1237,55 @@ static Node *compare(Simp *s, Node *n, int fields)
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 @@ static Node *rval(Simp *s, Node *n, Node *dst)
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;