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)
}