summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--all.h3
-rw-r--r--fold.c3
-rw-r--r--parse.c12
-rw-r--r--ssa.c4
-rw-r--r--util.c20
5 files changed, 30 insertions, 12 deletions
diff --git a/all.h b/all.h
index 34ad47e..08056c4 100644
--- a/all.h
+++ b/all.h
@@ -485,7 +485,8 @@ void emit(int, int, Ref, Ref, Ref);
 void emiti(Ins);
 void idup(Ins **, Ins *, ulong);
 Ins *icpy(Ins *, Ins *, ulong);
-void *vnew(ulong, size_t);
+void *vnew(ulong, size_t, void *(size_t));
+void vfree(void *);
 void vgrow(void *, ulong);
 int clsmerge(short *, short);
 int phicls(int, Tmp *);
diff --git a/fold.c b/fold.c
index da566ab..c2a7c12 100644
--- a/fold.c
+++ b/fold.c
@@ -193,7 +193,7 @@ fold(Fn *fn)
 
 	val = emalloc(fn->ntmp * sizeof val[0]);
 	edge = emalloc(fn->nblk * sizeof edge[0]);
-	usewrk = vnew(0, sizeof usewrk[0]);
+	usewrk = vnew(0, sizeof usewrk[0], emalloc);
 
 	for (n=0; n<fn->ntmp; n++)
 		val[n] = Top;
@@ -314,6 +314,7 @@ fold(Fn *fn)
 
 	free(val);
 	free(edge);
+	vfree(usewrk);
 }
 
 /* boring folding code */
diff --git a/parse.c b/parse.c
index 2e7726d..38c212e 100644
--- a/parse.c
+++ b/parse.c
@@ -261,7 +261,7 @@ lex()
 		return Tint;
 	}
 	if (c == '"') {
-		tokval.str = vnew(0, 1);
+		tokval.str = vnew(0, 1, alloc);
 		for (i=0;; i++) {
 			c = fgetc(inf);
 			if (c == EOF)
@@ -425,7 +425,7 @@ parsecls(int *tyn)
 				*tyn = i;
 				return 4;
 			}
-		err("undefined type");
+		err("undefined type :%s", tokval.str);
 	case Tw:
 		return Kw;
 	case Tl:
@@ -752,11 +752,11 @@ parsefn(int export)
 	curf = alloc(sizeof *curf);
 	curf->ntmp = 0;
 	curf->ncon = 1; /* first constant must be 0 */
-	curf->tmp = vnew(curf->ntmp, sizeof curf->tmp[0]);
-	curf->con = vnew(curf->ncon, sizeof curf->con[0]);
+	curf->tmp = vnew(curf->ntmp, sizeof curf->tmp[0], alloc);
+	curf->con = vnew(curf->ncon, sizeof curf->con[0], alloc);
 	for (r=0; r<Tmp0; r++)
 		newtmp(0, r < XMM0 ? Kl : Kd, curf);
-	bmap = vnew(nblk, sizeof bmap[0]);
+	bmap = vnew(nblk, sizeof bmap[0], alloc);
 	curf->con[0].type = CBits;
 	curf->export = export;
 	blink = &curf->start;
@@ -779,7 +779,7 @@ parsefn(int export)
 		err("empty function");
 	if (curb->jmp.type == Jxxx)
 		err("last block misses jump");
-	curf->mem = vnew(0, sizeof curf->mem[0]);
+	curf->mem = vnew(0, sizeof curf->mem[0], alloc);
 	curf->nmem = 0;
 	curf->nblk = nblk;
 	curf->rpo = 0;
diff --git a/ssa.c b/ssa.c
index a2efb28..4b78fe3 100644
--- a/ssa.c
+++ b/ssa.c
@@ -52,7 +52,7 @@ filluse(Fn *fn)
 		tmp[t].phi = 0;
 		tmp[t].cls = 0;
 		if (tmp[t].use == 0)
-			tmp[t].use = vnew(0, sizeof(Use));
+			tmp[t].use = vnew(0, sizeof(Use), alloc);
 	}
 	for (b=fn->start; b; b=b->link) {
 		for (p=b->phi; p; p=p->link) {
@@ -253,7 +253,7 @@ addfron(Blk *a, Blk *b)
 		if (a->fron[n] == b)
 			return;
 	if (!a->nfron)
-		a->fron = vnew(++a->nfron, sizeof a->fron[0]);
+		a->fron = vnew(++a->nfron, sizeof a->fron[0], alloc);
 	else
 		vgrow(&a->fron, ++a->nfron);
 	a->fron[a->nfron-1] = b;
diff --git a/util.c b/util.c
index 527f214..a99e2dd 100644
--- a/util.c
+++ b/util.c
@@ -6,6 +6,7 @@ typedef struct Vec Vec;
 
 struct Vec {
 	ulong mag;
+	void *(*alloc)();
 	size_t esz;
 	ulong cap;
 	union {
@@ -159,7 +160,7 @@ icpy(Ins *d, Ins *s, ulong n)
 }
 
 void *
-vnew(ulong len, size_t esz)
+vnew(ulong len, size_t esz, void *alloc(size_t))
 {
 	ulong cap;
 	Vec *v;
@@ -170,10 +171,24 @@ vnew(ulong len, size_t esz)
 	v->mag = VMag;
 	v->cap = cap;
 	v->esz = esz;
+	v->alloc = alloc;
 	return v + 1;
 }
 
 void
+vfree(void *p)
+{
+	Vec *v;
+
+	v = (Vec *)p - 1;
+	assert(v->mag == VMag);
+	if (v->alloc == emalloc) {
+		v->mag = 0;
+		free(v);
+	}
+}
+
+void
 vgrow(void *vp, ulong len)
 {
 	Vec *v;
@@ -183,8 +198,9 @@ vgrow(void *vp, ulong len)
 	assert(v+1 && v->mag == VMag);
 	if (v->cap >= len)
 		return;
-	v1 = vnew(len, v->esz);
+	v1 = vnew(len, v->esz, v->alloc);
 	memcpy(v1, v+1, v->cap * v->esz);
+	vfree(v+1);
 	*(Vec **)vp = v1;
 }