summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2016-04-25 10:37:27 -0400
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2016-04-25 10:58:11 -0400
commit12755db1aaea6f4ba1f380f5f34842b4e2a28f26 (patch)
treea7cddd2583841fa0328ca9f24affcaca1ec21f68
parentf4e0bfbbb9a69ff4ced213ec10d28411c093e495 (diff)
downloadroux-12755db1aaea6f4ba1f380f5f34842b4e2a28f26.tar.gz
fix type size computations in parser
The type sizes are important to get right because
the ABI relies on them when it emits memory blits
to pass/return structs.
-rw-r--r--all.h2
-rw-r--r--parse.c21
2 files changed, 11 insertions, 12 deletions
diff --git a/all.h b/all.h
index 4190162..5f87466 100644
--- a/all.h
+++ b/all.h
@@ -431,7 +431,7 @@ struct Fn {
 struct Typ {
 	char name[NString];
 	int dark;
-	uint size;
+	ulong size;
 	int align;
 
 	struct {
diff --git a/parse.c b/parse.c
index d4ed3f8..4d6b345 100644
--- a/parse.c
+++ b/parse.c
@@ -791,7 +791,8 @@ static void
 parsetyp()
 {
 	Typ *ty;
-	int t, n, sz, al, s, a, c, flt;
+	int t, n, c, a, al, flt;
+	ulong sz, s;
 
 	if (ntyp >= NTyp)
 		err("too many type definitions");
@@ -851,14 +852,12 @@ parsetyp()
 				t = nextnl();
 			} else
 				c = 1;
-			while (c-- > 0)
-				if (n < NSeg) {
-					ty->seg[n].isflt = flt;
-					ty->seg[n].ispad = 0;
-					ty->seg[n].len = s;
-					sz += a + s;
-					n++;
-				}
+			sz += a + c*s;
+			for (; c>0 && n<NSeg; c--, n++) {
+				ty->seg[n].isflt = flt;
+				ty->seg[n].ispad = 0;
+				ty->seg[n].len = s;
+			}
 			if (t != Tcomma)
 				break;
 			t = nextnl();
@@ -871,8 +870,8 @@ parsetyp()
 			ty->align = al;
 		else
 			al = ty->align;
-		a = (1 << al) - 1;
-		ty->size = (sz + a) & ~a;
+		a = 1 << al;
+		ty->size = (sz + a - 1) & -a;
 	}
 	if (t != Trbrace)
 		err(", or } expected");