ref: f991cf4a837be41c1e4972e06066815cdd67b140
parent: d2a28cc46d5101760733f1b831287f6b9fcf1be1
author: Ori Bernstein <ori@eigenstate.org>
date: Mon May 9 11:39:26 EDT 2016
Avoid infinite recursion when priting bad types. We sometimes error on bad types. Let's not crash when we do that.
--- a/parse/type.c
+++ b/parse/type.c
@@ -31,7 +31,7 @@
static Htab *tydeduptab;
/* Built in type constraints */
static Trait *traits[Ntypes + 1][4];
-static int tybfmt(char *buf, size_t len, Type *t);
+static int tybfmt(char *buf, size_t len, Bitset *visted, Type *t);
char stackness[] = {
#define Ty(t, n, stk) stk,
@@ -465,11 +465,12 @@
return p - buf;
}
-static int fmtstruct(char *buf, size_t len, Type *t)
+static int fmtstruct(char *buf, size_t len, Bitset *visited, Type *t)
{
size_t i;
char *end, *p;
- char *name, *ty;
+ char *name;
+ char subbuf[512];
p = buf;
end = p + len;
@@ -476,19 +477,19 @@
p += bprintf(p, end - p, "struct\n");
for (i = 0; i < t->nmemb; i++) {
name = declname(t->sdecls[i]);
- ty = tystr(decltype(t->sdecls[i]));
- p += bprintf(p, end - p, "\t%s:%s\n ", name, ty);
- free(ty);
+ tybfmt(subbuf, sizeof subbuf, visited, decltype(t->sdecls[i]));
+ p += bprintf(p, end - p, "\t%s:%s\n ", name, subbuf);
}
p += bprintf(p, end - p, ";;");
return p - buf;
}
-static int fmtunion(char *buf, size_t len, Type *t)
+static int fmtunion(char *buf, size_t len, Bitset *visited, Type *t)
{
size_t i;
char *end, *p;
- char *name, *ty;
+ char *name;
+ char subbuf[512];
p = buf;
end = p + len;
@@ -496,9 +497,8 @@
for (i = 0; i < t->nmemb; i++) {
name = namestr(t->udecls[i]->name);
if (t->udecls[i]->etype) {
- ty = tystr(t->udecls[i]->etype);
- p += bprintf(p, end - p, "\t`%s %s\n", name, ty);
- free(ty);
+ tybfmt(subbuf, sizeof subbuf, visited, t->udecls[i]->etype);
+ p += bprintf(p, end - p, "\t`%s %s\n", name, subbuf);
} else {
p += bprintf(p, end - p, "\t`%s\n", name);
}
@@ -507,7 +507,7 @@
return p - buf;
}
-static int fmtlist(char *buf, size_t len, Type **arg, size_t narg)
+static int fmtlist(char *buf, size_t len, Bitset *visited, Type **arg, size_t narg)
{
char *end, *p, *sep;
size_t i;
@@ -518,7 +518,7 @@
p += bprintf(p, end - p, "(");
for (i = 0; i < narg; i++) {
p += bprintf(p, end - p, "%s", sep);
- p += tybfmt(p, end - p, arg[i]);
+ p += tybfmt(p, end - p, visited, arg[i]);
sep = ", ";
}
p += bprintf(p, end - p, ")");
@@ -525,7 +525,7 @@
return p - buf;
}
-static int tybfmt(char *buf, size_t len, Type *t)
+static int tybfmt(char *buf, size_t len, Bitset *visited, Type *t)
{
size_t i;
char *p;
@@ -534,13 +534,21 @@
if (t)
t = tysearch(t);
+
sep = "";
p = buf;
end = p + len;
+
if (!t) {
p += bprintf(p, end - p, "tynil");
return len - (end - p);
}
+
+ if (bshas(visited, t->tid)) {
+ p += bprintf(buf, len, "<...>");
+ return len - (end - p);
+ }
+ bsput(visited, t->tid);
switch (t->type) {
case Tybad: p += bprintf(p, end - p, "BAD"); break;
case Tyvoid: p += bprintf(p, end - p, "void"); break;
@@ -563,15 +571,15 @@
case Tyvar: p += bprintf(p, end - p, "$%d", t->tid); break;
case Typtr:
- p += tybfmt(p, end - p, t->sub[0]);
+ p += tybfmt(p, end - p, visited, t->sub[0]);
p += bprintf(p, end - p, "#");
break;
case Tyslice:
- p += tybfmt(p, end - p, t->sub[0]);
+ p += tybfmt(p, end - p, visited, t->sub[0]);
p += bprintf(p, end - p, "[:]");
break;
case Tyarray:
- p += tybfmt(p, end - p, t->sub[0]);
+ p += tybfmt(p, end - p, visited, t->sub[0]);
if (t->asize) {
i = t->asize->expr.args[0]->lit.intval;
p += bprintf(p, end - p, "[%zd]", i);
@@ -584,11 +592,11 @@
p += bprintf(p, end - p, "(");
for (i = 1; i < t->nsub; i++) {
p += bprintf(p, end - p, "%s", sep);
- p += tybfmt(p, end - p, t->sub[i]);
+ p += tybfmt(p, end - p, visited, t->sub[i]);
sep = ", ";
}
p += bprintf(p, end - p, " -> ");
- p += tybfmt(p, end - p, t->sub[0]);
+ p += tybfmt(p, end - p, visited, t->sub[0]);
p += bprintf(p, end - p, ")");
break;
case Tytuple:
@@ -595,7 +603,7 @@
p += bprintf(p, end - p, "(");
for (i = 0; i < t->nsub; i++) {
p += bprintf(p, end - p, "%s", sep);
- p += tybfmt(p, end - p, t->sub[i]);
+ p += tybfmt(p, end - p, visited, t->sub[i]);
sep = ",";
}
p += bprintf(p, end - p, ")");
@@ -604,7 +612,7 @@
case Tyunres:
p += namefmt(p, end - p, t->name);
if (t->narg)
- p += fmtlist(p, end - p, t->arg, t->narg);
+ p += fmtlist(p, end - p, visited, t->arg, t->narg);
break;
case Tyname:
if (t->name->name.ns)
@@ -611,7 +619,7 @@
p += bprintf(p, end - p, "%s.", t->name->name.ns);
p += bprintf(p, end - p, "%s", namestr(t->name));
if (t->narg)
- p += fmtlist(p, end - p, t->arg, t->narg);
+ p += fmtlist(p, end - p, visited, t->arg, t->narg);
break;
case Tygeneric:
if (t->name->name.ns)
@@ -618,10 +626,10 @@
p += bprintf(p, end - p, "%s.", t->name->name.ns);
p += bprintf(p, end - p, "%s", namestr(t->name));
if (t->ngparam)
- p += fmtlist(p, end - p, t->gparam, t->ngparam);
+ p += fmtlist(p, end - p, visited, t->gparam, t->ngparam);
break;
- case Tystruct: p += fmtstruct(p, end - p, t); break;
- case Tyunion: p += fmtunion(p, end - p, t); break;
+ case Tystruct: p += fmtstruct(p, end - p, visited, t); break;
+ case Tyunion: p += fmtunion(p, end - p, visited, t); break;
case Ntypes: die("Ntypes is not a type"); break;
}
@@ -634,7 +642,11 @@
char *tyfmt(char *buf, size_t len, Type *t)
{
- tybfmt(buf, len, t);
+ Bitset *bs;
+
+ bs = mkbs();
+ tybfmt(buf, len, bs, t);
+ bsfree(bs);
return buf;
}