ref: 90cb266f109bb3ed87c2306e3d3def1325dc313a
parent: aa1fc1c605dde3cc533e353a25343dd344ea4ba8
author: Ori Bernstein <ori@eigenstate.org>
date: Wed Feb 25 08:19:25 EST 2015
Implement type description dumping.
--- a/6/gengas.c
+++ b/6/gengas.c
@@ -38,6 +38,7 @@
static size_t writeblob(FILE *fd, Htab *globls, Htab *strtab, Node *blob);
static void locprint(FILE *fd, Loc *l, char spec);
+static void gentydesc(FILE *fd, Type *ty);
static void fillglobls(Stab *st, Htab *globls)
{
@@ -433,7 +434,6 @@
}
}
-
static void writeasm(FILE *fd, Isel *s, Func *fn)
{
size_t i, j;
@@ -487,6 +487,120 @@
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$%zd$%s%s%s", ty->tid, ns, sep, ty->name->name.name);
+ return buf;
+}
+
+static void genstructmemb(FILE *fd, Node *sdecl)
+{
+ fprintf(fd, ".ascii \"%s\" /* struct member */\n", namestr(sdecl->decl.name));
+ gentydesc(fd, sdecl->decl.type);
+}
+
+static void genunionmemb(FILE *fd, Ucon *ucon)
+{
+ fprintf(fd, ".ascii \"%s\" /* union constructor */\n", namestr(ucon->name));
+ if (ucon->etype)
+ gentydesc(fd, ucon->etype);
+ else
+ fprintf(fd, ".byte %d /* no union type */\n", Tybad);
+}
+
+/* on x86, unaligned pointers are cheap. we shouldn't be introspecting too
+ * much, so tentatively, we'll just generate packed data.
+ */
+static void gentydesc(FILE *fd, Type *ty)
+{
+ char buf[512];
+ Node *sz;
+ size_t i;
+
+ fprintf(fd, ".byte %d /* type: %s */\n", ty->type, tidstr[ty->type]);
+ switch (ty->type) {
+ case Ntypes: case Tyvar: case Tybad: case Typaram:
+ case Tygeneric: case Tyunres:
+ die("invalid type in tydesc"); break;
+
+ case Tyvoid: case Tychar: case Tybool: case Tyint8:
+ case Tyint16: case Tyint: case Tyint32: case Tyint64:
+ case Tylong: case Tybyte: case Tyuint8: case Tyuint16:
+ case Tyuint: case Tyuint32: case Tyuint64: case Tyulong:
+ case Tyflt32: case Tyflt64: case Tyvalist:
+ break;
+
+ case Typtr:
+ gentydesc(fd, ty->sub[0]);
+ break;
+ case Tyslice:
+ gentydesc(fd, ty->sub[0]);
+ break;
+ case Tyarray:
+ ty->asize = fold(ty->asize, 1);
+ sz = ty->asize;
+ if (sz) {
+ assert(sz->type == Nexpr);
+ sz = sz->expr.args[0];
+ assert(sz->type == Nlit && sz->lit.littype == Lint);
+ fprintf(fd, ".quad %lld /* array size */\n", (vlong)sz->lit.intval);
+ } else {
+ fprintf(fd, ".quad -1 /* array size */\n");
+ }
+
+ gentydesc(fd, ty->sub[0]);
+ break;
+ case Tyfunc:
+ fprintf(fd, ".byte %zd /* nargs + ret */\n", ty->nsub);
+ for (i = 0; i < ty->nsub; i++)
+ gentydesc(fd, ty->sub[i]);
+ break;
+ case Tytuple:
+ for (i = 0; i < ty->nsub; i++)
+ gentydesc(fd, ty->sub[i]);
+ break;
+ case Tystruct:
+ for (i = 0; i < ty->nmemb; i++)
+ genstructmemb(fd, ty->sdecls[i]);
+ break;
+ case Tyunion:
+ for (i = 0; i < ty->nmemb; i++)
+ genunionmemb(fd, ty->udecls[i]);
+ break;
+ case Tyname:
+ fprintf(fd, ".quad %s\n", tydescid(buf, sizeof buf, ty));
+ break;
+ }
+}
+
+void gentype(FILE *fd, Type *ty)
+{
+ char buf[512];
+
+ if (ty->type == Tyname) {
+ if (hasparams(ty))
+ return;
+ tydescid(buf, sizeof buf, ty);
+ if (ty->vis == Visexport)
+ fprintf(fd, ".globl %s\n", buf);
+ fprintf(fd, "%s:\n", buf);
+ gentydesc(fd, ty->sub[0]);
+ } else {
+ gentydesc(fd, ty);
+ }
+}
+
void gengas(Node *file, char *out)
{
Htab *globls, *strtab;
@@ -540,6 +654,8 @@
fprintf(fd, ".text\n");
for (i = 0; i < nfn; i++)
genfunc(fd, fn[i], globls, strtab);
+ for (i = 0; i < file->file.ntydefs; i++)
+ gentype(fd, file->file.tydefs[i]);
genstrings(fd, strtab);
fclose(fd);
}
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -281,7 +281,7 @@
;
package : Tpkg optident Tasn pkgbody Tendblk {
- if (file->file.globls->_name)
+ if (file->file.globls->name)
lfatal($1->loc, "Package already declared\n");
if ($2) {
updatens(file->file.globls, $2->id);
@@ -406,6 +406,7 @@
$$ = $2;
if ($$.nparams == 0) {
$$.type = mktyname($2.loc, mkname($2.loc, $2.name), $4);
+ lappend(&file->file.tydefs, &file->file.ntydefs, $$.type);
} else {
$$.type = mktygeneric($2.loc, mkname($2.loc, $2.name), $2.params, $2.nparams, $4);
}
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1471,8 +1471,8 @@
to do namespace dependent comparisons for specializing, we need to set the
namespace here.
*/
- if (file->file.globls->_name)
- setns(dcl->decl.name, file->file.globls->_name);
+ if (file->file.globls->name)
+ setns(dcl->decl.name, file->file.globls->name);
for (j = 0; j < t->nfuncs; j++) {
if (nameeq(dcl->decl.name, t->funcs[j]->decl.name)) {
proto = t->funcs[j];
@@ -1703,11 +1703,13 @@
for (i = 0; i < t->nsub; i++)
t->sub[i] = tyfix(st, ctx, t->sub[i]);
}
+
if (t->type == Tyvar) {
if (debugopt['T'])
dump(file, stdout);
lfatal(t->loc, "underconstrained type %s near %s", tyfmt(buf, 1024, t), ctxstr(st, ctx));
}
+
if (debugopt['u'] && !tyeq(orig, t)) {
from = tystr(orig);
to = tystr(t);
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -123,7 +123,7 @@
struct Stab {
Stab *super;
- char *_name;
+ char *name;
/* Contents of stab.
* types and values are in separate namespaces. */
@@ -166,9 +166,11 @@
Node **sdecls; /* Tystruct: decls in struct */
Ucon **udecls; /* Tyunion: decls in union */
};
- char issynth; /* Tyname: whether this is synthesized or not */
- char ishidden; /* Tyname: whether this is hidden or not */
- char ispkglocal; /* Tyname: whether this is package local or not */
+
+ char issynth; /* Tyname: whether this is synthesized or not */
+ char ishidden; /* Tyname: whether this is hidden or not */
+ char ispkglocal; /* Tyname: whether this is package local or not */
+ char isimport; /* Tyname: whether tyis type was imported. */
};
struct Ucon {
@@ -211,6 +213,8 @@
Node **stmts;
size_t nstmts;
Stab *globls;
+ size_t ntydefs;
+ Type **tydefs;
} file;
struct {
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -52,6 +52,7 @@
htput(tsmap, t, ret);
for (i = 0; i < t->ngparam; i++)
lappend(&ret->arg, &ret->narg, tyspecialize(t->gparam[i], tsmap, delayed));
+ lappend(&file->file.tydefs, &file->file.ntydefs, ret);
break;
case Tyname:
arg = NULL;
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -191,7 +191,7 @@
Stab *s;
do {
- if (streq(st->_name, name))
+ if (streq(st->name, name))
return st;
if ((s = htget(st->ns, name)))
return s;
@@ -263,8 +263,8 @@
}
void forcedcl (Stab *st, Node *s) {
- if (st->_name)
- setns(s->decl.name, st->_name);
+ if (st->name)
+ setns(s->decl.name, st->name);
htput(st->dcl, s->decl.name, s);
assert(htget(st->dcl, s->decl.name) != NULL);
}
@@ -304,10 +304,10 @@
Tydefn *td;
Type *ty;
- if (st->_name)
- setns(n, st->_name);
- if (st->_name && t && t->name)
- setns(t->name, st->_name);
+ if (st->name)
+ setns(n, st->name);
+ if (st->name && t && t->name)
+ setns(t->name, st->name);
ty = gettype(st, n);
if (!ty) {
@@ -387,8 +387,8 @@
fatal(n, "Trait %s already implemented over %s at %s:%d",
namestr(n->impl.traitname), tystr(n->impl.type),
fname(n->loc), lnum(n->loc));
- if (st->_name)
- setns(n->impl.traitname, st->_name);
+ if (st->name)
+ setns(n->impl.traitname, st->name);
htput(st->impl, n, n);
}
@@ -408,10 +408,10 @@
{
Stab *s;
- s = getns_str(st, scope->_name);
+ s = getns_str(st, scope->name);
if (s)
- lfatal(Zloc, "Namespace %s already defined", st->_name);
- htput(st->ns, scope->_name, scope);
+ lfatal(Zloc, "Namespace %s already defined", st->name);
+ htput(st->ns, scope->name, scope);
}
/*
@@ -425,9 +425,9 @@
size_t i, nk;
Tydefn *td;
- if (st->_name)
- die("Stab %s already has namespace; Can't set to %s", st->_name, name);
- st->_name = strdup(name);
+ if (st->name)
+ die("Stab %s already has namespace; Can't set to %s", st->name, name);
+ st->name = strdup(name);
k = htkeys(st->dcl, &nk);
for (i = 0; i < nk; i++)
setns(k[i], name);
--- a/parse/use.c
+++ b/parse/use.c
@@ -48,7 +48,7 @@
size_t n, i;
void **keys;
- wrstr(fd, val->_name);
+ wrstr(fd, val->name);
/* write decls */
keys = htkeys(val->dcl, &n);
@@ -86,7 +86,7 @@
/* read dcls */
st = mkstab();
- st->_name = rdstr(fd);
+ st->name = rdstr(fd);
n = rdint(fd);
for (i = 0; i < n; i++)
putdcl(st, rdsym(fd, NULL));
@@ -340,6 +340,7 @@
t = rdbyte(fd);
ty = mktype(Zloc, t);
+ ty->isimport = 1;
if (rdbyte(fd) == Vishidden)
ty->ishidden = 1;
/* tid is generated; don't write */
@@ -704,7 +705,7 @@
Stab *s;
if (!pkg) {
- if (!st->_name)
+ if (!st->name)
return st;
else
return NULL;
@@ -713,7 +714,7 @@
s = getns_str(st, pkg);
if (!s) {
s = mkstab();
- s->_name = strdup(pkg);
+ s->name = strdup(pkg);
putns(st, s);
}
return s;
@@ -827,8 +828,8 @@
/* if the package names match up, or the usefile has no declared
* package, then we simply add to the current stab. Otherwise,
* we add a new stab under the current one */
- if (st->_name) {
- if (pkg && !strcmp(pkg, st->_name)) {
+ if (st->name) {
+ if (pkg && !strcmp(pkg, st->name)) {
s = st;
} else {
s = findstab(st, pkg);
@@ -841,7 +842,7 @@
}
}
if (!s) {
- printf("could not find matching package for merge: %s\n", st->_name);
+ printf("could not find matching package for merge: %s\n", st->name);
exit(1);
}
tidmap = mkht(ptrhash, ptreq);
@@ -964,8 +965,8 @@
/* usefile name */
wrbyte(f, 'U');
wrint(f, Useversion); /* use version */
- if (st->_name)
- wrstr(f, st->_name);
+ if (st->name)
+ wrstr(f, st->name);
else
wrstr(f, NULL);