shithub: mc

Download patch

ref: 53f937aeaa1ad2320f61c63933e24f2f6f1f326f
parent: dee37ce8cb666cfe9b60520f595fbf9ae50cee29
author: Ori Bernstein <ori@eigenstate.org>
date: Fri May 22 05:56:31 EDT 2015

Add type size and other info.

--- a/6/asm.h
+++ b/6/asm.h
@@ -270,6 +270,7 @@
 
 /* useful functions */
 size_t tysize(Type *t);
+size_t tyalign(Type *t);
 size_t size(Node *n);
 ssize_t tyoffset(Type *ty, Node *memb);
 ssize_t offset(Node *aggr, Node *memb);
--- a/6/gengas.c
+++ b/6/gengas.c
@@ -494,14 +494,19 @@
     size_t i, shift;
     uint8_t b;
 
+    if (val < 128) {
+        fprintf(fd, "\t.byte %zd\n", val);
+        return;
+    }
+
     for (i = 1; i < 8; i++)
         if (val < 1ULL << (7*i))
             break;
-    shift = 8 - i + 1;
-    b = ~0 << shift;
-    b |= val & ((1 << shift) - 1);
+    shift = 8 - i;
+    b = ~0 << (shift + 1);
+    b |= val & ((1 << (8 - shift)) - 1);
     fprintf(fd, "\t.byte %u\n", b);
-    val >>= shift;
+    val >>=  shift;
     while (val != 0) {
         fprintf(fd, "\t.byte %u\n", (uint)val & 0xff);
         val >>= 8;
@@ -621,13 +626,6 @@
     fprintf(fd, "\n");
 
     genstrings(fd, strtab);
-    /*
-     * workaround for label issue on OSX: we get errors
-     * complaining about how differences involving labels
-     * at the end of functions will generate a non-relocatable
-     * difference. Adding a dummy byte after will fix this.
-     */
-    fprintf(fd, "\t.byte 0 /* dummy to shut up Apple's as */\n");
     fclose(fd);
 }
 
--- a/6/typeinfo.c
+++ b/6/typeinfo.c
@@ -131,6 +131,12 @@
     }
 }
 
+static void encodetypeinfo(Blob ***sub, size_t *nsub, Type *t)
+{
+    lappend(sub, nsub, mkblobi(Btimin, tysize(t)));
+    lappend(sub, nsub, mkblobi(Btimin, tyalign(t)));
+}
+
 Blob *tydescsub(Type *ty)
 {
     Blob **sub, *sz, *bt, *b;
@@ -172,6 +178,7 @@
             lappend(&sub, &nsub, tydescsub(ty->sub[0]));
             break;
         case Tyarray:
+            encodetypeinfo(&sub, &nsub, ty);
             ty->asize = fold(ty->asize, 1);
             len = ty->asize;
             if (len) {
@@ -191,16 +198,19 @@
                 lappend(&sub, &nsub, tydescsub(ty->sub[i]));
             break;
         case Tytuple:
+            encodetypeinfo(&sub, &nsub, ty);
             lappend(&sub, &nsub, mkblobi(Btimin, ty->nsub));
             for (i = 0; i < ty->nsub; i++)
                 lappend(&sub, &nsub, tydescsub(ty->sub[i]));
             break;
         case Tystruct:
+            encodetypeinfo(&sub, &nsub, ty);
             lappend(&sub, &nsub, mkblobi(Btimin, ty->nmemb));
             for (i = 0; i < ty->nmemb; i++)
                 structmemb(&sub, &nsub, ty->sdecls[i]);
             break;
         case Tyunion:
+            encodetypeinfo(&sub, &nsub, ty);
             lappend(&sub, &nsub, mkblobi(Btimin, ty->nmemb));
             for (i = 0; i < ty->nmemb; i++)
                 unionmemb(&sub, &nsub, ty->udecls[i]);
@@ -296,6 +306,8 @@
         case Tyname:
             return tysize(t->sub[0]);
         case Tyarray:
+            if (!t->asize)
+                return 0;
             t->asize = fold(t->asize, 1);
             assert(exprop(t->asize) == Olit);
             return t->asize->expr.args[0]->lit.intval * tysize(t->sub[0]);
@@ -328,6 +340,35 @@
             break;
     }
     return -1;
+}
+
+size_t tyalign(Type *ty)
+{
+    size_t align, i;
+
+    align = 1;
+    switch (ty->type) {
+        case Tyarray:
+            align = tyalign(ty->sub[0]);
+            break;
+        case Tytuple:
+            for (i = 0; i < ty->nsub; i++)
+                align = max(align, tyalign(ty->sub[0]));
+            break;
+        case Tyunion:
+            align = 4;
+            for (i = 0; i < ty->nmemb; i++)
+                if (ty->udecls[i]->etype)
+                    align = max(align, tyalign(ty->udecls[i]->etype));
+            break;
+        case Tystruct:
+            for (i = 0; i < ty->nmemb; i++)
+                align = max(align, tyalign(decltype(ty->sdecls[i])));
+            break;
+        default:
+            align = tysize(ty);
+    }
+    return align;
 }
 
 /* gets the byte offset of 'memb' within the aggregate type 'aggr' */
--- a/libstd/introspect.myr
+++ b/libstd/introspect.myr
@@ -3,7 +3,7 @@
 use "fmt.use"
 
 pkg std =
-	type typeinfo = union
+	type typedesc = union
 		`Tynone
 
 		/* atomic types */
@@ -53,8 +53,15 @@
 		rem	: byte[:]
 	;;
 
+	type typeinfo = struct
+		size	: size
+		align	: size
+	;;
+
 	generic typeof	: (v : @a -> byte[:])
 	const typesof	: (vl : ... -> typecursor)
+	const typedecode	: (e : byte[:] -> typedesc)
+	const typedesc	: (e : byte[:] -> typedesc)
 	const typeinfo	: (e : byte[:] -> typeinfo)
 
 	const tcnext	: (t : typecursor# -> byte[:])
@@ -110,7 +117,8 @@
 	e = getenc(&a castto(byte##))
 	/* we encode the arg pack type as a tuple of the types passed */
 	std.assert(e[0] == Enctuple, "typesof wrong base type")
-	-> lentypecursor(e[1:])
+	e = skiptypeinfo(e[1:])
+	-> lentypecursor(e)
 }
 
 const tcnext = {tc
@@ -152,8 +160,8 @@
 	-> p#[sz:sz+val]
 }
 
-const typeinfo = {ti
-	var len, sz, p
+const typedesc = {ti
+	var len,sz, p
 
 	match ti[0]
 	| Encnone:	-> `Tynone
@@ -178,7 +186,6 @@
 	| Encflt32:	-> `Tyflt32
 	| Encflt64:	-> `Tyflt64
 	| Encvalist:	-> `Tyvalist
-	/* for now */
 
 	/* compound types */
 	| Encptr:	-> `Typtr getsub(ti[1:])
@@ -185,15 +192,23 @@
 	| Encfunc:	-> `Tyfunc lentypecursor(ti[1:])
 	| Encslice:	-> `Tyslice getsub(ti[1:])
 	| Encarray:
-		(len, sz) = getipacked(ti[1:])
-		-> `Tyarray (len, getsub(ti[sz+1:]))
+		ti = skiptypeinfo(ti[1:])
+		(len, sz) = getipacked(ti)
+		-> `Tyarray (len, getsub(ti[sz:]))
 
 
 	/* aggregate types */
-	| Enctuple:	-> `Tytuple lentypecursor(ti[1:])
-	| Encstruct:	-> `Tystruct lennamecursor(ti[1:])
-	| Encunion:	-> `Tyunion lennamecursor(ti[1:])
-	| Encname:	-> `Tyname nameinfo(ti[1:])
+	| Enctuple:
+		ti = skiptypeinfo(ti[1:])
+		-> `Tytuple lentypecursor(ti)
+	| Encstruct:
+		ti = skiptypeinfo(ti[1:])
+		-> `Tystruct lennamecursor(ti)
+	| Encunion:
+		ti = skiptypeinfo(ti[1:])
+		-> `Tyunion lennamecursor(ti)
+	| Encname:
+		-> `Tyname namedesc(ti[1:])
 	| Encindname:
 		/* 
 		ugly hack: the slice contains a pointer to the
@@ -201,12 +216,88 @@
 		pull the indirect value out of the pointer.
 		*/
 		p = ti[1:] castto(byte##)
+		-> typedesc(getenc(p))
+	| _:
+		std.fatal("unknown type encoding")
+	;;
+}
+
+const typeinfo = {ti
+	var p
+
+	match ti[0]
+	| Encnone:	-> [.size=0, .align=1]
+	| Encvoid:	-> [.size=0, .align=1]
+	| Encbool:	-> [.size=0, .align=1]
+	| Encchar:	-> [.size=4, .align=4]
+
+	| Encint8:	-> [.size=1, .align=1]
+	| Encint16:	-> [.size=2, .align=2]
+	| Encint:	-> [.size=4, .align=4]
+	| Encint32:	-> [.size=4, .align=4]
+	| Encint64:	-> [.size=8, .align=8]
+	| Enclong:	-> [.size=8, .align=8]
+
+	| Encbyte:	-> [.size=1, .align=1]
+	| Encuint8:	-> [.size=1, .align=1]
+	| Encuint16:	-> [.size=2, .align=2]
+	| Encuint:	-> [.size=4, .align=4]
+	| Encuint32:	-> [.size=4, .align=4]
+	| Encuint64:	-> [.size=8, .align=8]
+	| Enculong:	-> [.size=8, .align=8]
+	| Encflt32:	-> [.size=4, .align=4]
+	| Encflt64:	-> [.size=8, .align=8]
+	| Encvalist:	-> [.size=8, .align=8]
+
+	/* compound types */
+	| Encptr:	-> [.size=8, .align=8]
+	| Encfunc:	-> [.size=8, .align=8]
+	| Encslice:	-> [.size=16, .align=8]
+
+	| Encarray: 	-> gettypeinfo(ti[1:])
+	| Enctuple:	-> gettypeinfo(ti[1:])
+	| Encstruct:	-> gettypeinfo(ti[1:])
+	| Encunion:	-> gettypeinfo(ti[1:])
+	| Encname:	-> getnameinfo(ti[1:])
+	| Encindname:
+		p = ti[1:] castto(byte##)
 		-> typeinfo(getenc(p))
-	| other:	std.fatal("unsupported type %b\n", other)
+	| _:
+		std.fatal("unknown type encoding")
 	;;
 }
 
-const nameinfo = {e
+const gettypeinfo = {e
+	var size, align, sz
+
+	(size, sz) = getipacked(e)	/* size */
+	e = e[sz:]
+	(align, sz) = getipacked(e)	/* align */
+	-> [.size = size, .align = align]
+}
+
+const skiptypeinfo = {e
+	var ignore, sz
+
+	(ignore, sz) = getipacked(e)	/* size */
+	e = e[sz:]
+	(ignore, sz) = getipacked(e)	/* align */
+	-> e[sz:]
+}
+
+const getnameinfo = {e
+	var n, name, sz, enc
+
+	(n, sz) = getipacked(e)
+	name = e[sz:n+sz]
+	e = e[n+sz:]
+	(n, sz) = getipacked(e)
+	enc = e[sz:n+sz]
+
+	-> typeinfo(enc)
+}
+
+const namedesc = {e
 	var n, sz, name, enc
 
 	(n, sz) = getipacked(e)
@@ -239,7 +330,7 @@
 	-> e[sz:sz+n]
 }
 
-const getipacked = {p : byte[:]
+const getipacked : (p : byte[:] -> (size, size)) = {p : byte[:]
 	var mask, val, len, i
 
 	mask = 0x80
@@ -251,8 +342,9 @@
 		mask |= 0x80
 	;;
 
-	for i = 0; i < len; i++
-		val |= (p[i] castto(size)) << (i*7)
+	val = (p[0] castto(size))  & ~(1 << (8 - len))
+	for i = 1; i < len; i++
+		val |= (p[i] castto(size)) << (i*8 - len)
 	;;
 	-> (val, len)
 }