6g: use full type in sigt[0].name

sys: add sys.reflect
runtime: add canfail flag for later

R=ken
OCL=17583
CL=17583
This commit is contained in:
Russ Cox 2008-10-21 15:38:26 -07:00
parent 0347e95b63
commit 44b0ecc5ca
5 changed files with 118 additions and 95 deletions

View File

@ -609,8 +609,12 @@ dumpsignatures(void)
p->to.offset = stringo;
ot += widthptr;
// save type name for runtime error message
snprint(buf, sizeof buf, "%T", t);
// save type name for runtime error message.
// TODO(rsc): the * is a botch but right more often than not.
if(et == TINTER)
snprint(buf, sizeof buf, "%#T", t);
else
snprint(buf, sizeof buf, "*%#T", t);
datastring(buf, strlen(buf)+1);
if(et == TINTER) {

View File

@ -32,6 +32,7 @@ export func ifaceT2I(sigi *byte, sigt *byte, elem any) (ret any);
export func ifaceI2T(sigt *byte, iface any) (ret any);
export func ifaceI2I(sigi *byte, iface any) (ret any);
export func ifaceeq(i1 any, i2 any) (ret bool);
export func reflect(i interface { }) (uint64, string);
export func argc() int32;
export func envc() int32;
@ -80,4 +81,3 @@ export func bytestorune(*byte, int32, int32) (int32, int32); // convert bytes to
export func stringtorune(string, int32) (int32, int32); // convert bytes to runes
export func exit(int32);

View File

@ -1,73 +1,66 @@
char *sysimport =
"package sys\n"
"type sys.any any\n"
"type sys.uint32 uint32\n"
"export func sys.mal (? sys.uint32) (? *sys.any)\n"
"export func sys.mal (? uint32) (? *any)\n"
"export func sys.breakpoint ()\n"
"export func sys.throwindex ()\n"
"export func sys.throwreturn ()\n"
"type sys.int32 int32\n"
"export func sys.panicl (? sys.int32)\n"
"type sys.bool bool\n"
"export func sys.printbool (? sys.bool)\n"
"type sys.float64 float64\n"
"export func sys.printfloat (? sys.float64)\n"
"type sys.int64 int64\n"
"export func sys.printint (? sys.int64)\n"
"type sys.string string\n"
"export func sys.printstring (? sys.string)\n"
"export func sys.printpointer (? *sys.any)\n"
"export func sys.printinter (? sys.any)\n"
"export func sys.panicl (? int32)\n"
"export func sys.printbool (? bool)\n"
"export func sys.printfloat (? float64)\n"
"export func sys.printint (? int64)\n"
"export func sys.printstring (? string)\n"
"export func sys.printpointer (? *any)\n"
"export func sys.printinter (? any)\n"
"export func sys.printnl ()\n"
"export func sys.printsp ()\n"
"export func sys.catstring (? sys.string, ? sys.string) (? sys.string)\n"
"export func sys.cmpstring (? sys.string, ? sys.string) (? sys.int32)\n"
"export func sys.slicestring (? sys.string, ? sys.int32, ? sys.int32) (? sys.string)\n"
"type sys.uint8 uint8\n"
"export func sys.indexstring (? sys.string, ? sys.int32) (? sys.uint8)\n"
"export func sys.intstring (? sys.int64) (? sys.string)\n"
"export func sys.byteastring (? *sys.uint8, ? sys.int32) (? sys.string)\n"
"export func sys.arraystring (? *[]sys.uint8) (? sys.string)\n"
"export func sys.ifaceT2I (sigi *sys.uint8, sigt *sys.uint8, elem sys.any) (ret sys.any)\n"
"export func sys.ifaceI2T (sigt *sys.uint8, iface sys.any) (ret sys.any)\n"
"export func sys.ifaceI2I (sigi *sys.uint8, iface sys.any) (ret sys.any)\n"
"export func sys.ifaceeq (i1 sys.any, i2 sys.any) (ret sys.bool)\n"
"export func sys.argc () (? sys.int32)\n"
"export func sys.envc () (? sys.int32)\n"
"export func sys.argv (? sys.int32) (? sys.string)\n"
"export func sys.envv (? sys.int32) (? sys.string)\n"
"export func sys.frexp (? sys.float64) (? sys.float64, ? sys.int32)\n"
"export func sys.ldexp (? sys.float64, ? sys.int32) (? sys.float64)\n"
"export func sys.modf (? sys.float64) (? sys.float64, ? sys.float64)\n"
"export func sys.isInf (? sys.float64, ? sys.int32) (? sys.bool)\n"
"export func sys.isNaN (? sys.float64) (? sys.bool)\n"
"export func sys.Inf (? sys.int32) (? sys.float64)\n"
"export func sys.NaN () (? sys.float64)\n"
"export func sys.newmap (keysize sys.uint32, valsize sys.uint32, keyalg sys.uint32, valalg sys.uint32, hint sys.uint32) (hmap *map[sys.any] sys.any)\n"
"export func sys.mapaccess1 (hmap *map[sys.any] sys.any, key sys.any) (val sys.any)\n"
"export func sys.mapaccess2 (hmap *map[sys.any] sys.any, key sys.any) (val sys.any, pres sys.bool)\n"
"export func sys.mapassign1 (hmap *map[sys.any] sys.any, key sys.any, val sys.any)\n"
"export func sys.mapassign2 (hmap *map[sys.any] sys.any, key sys.any, val sys.any, pres sys.bool)\n"
"export func sys.newchan (elemsize sys.uint32, elemalg sys.uint32, hint sys.uint32) (hchan *chan sys.any)\n"
"export func sys.chanrecv1 (hchan *chan sys.any) (elem sys.any)\n"
"export func sys.chanrecv2 (hchan *chan sys.any) (elem sys.any, pres sys.bool)\n"
"export func sys.chanrecv3 (hchan *chan sys.any, elem *sys.any) (pres sys.bool)\n"
"export func sys.chansend1 (hchan *chan sys.any, elem sys.any)\n"
"export func sys.chansend2 (hchan *chan sys.any, elem sys.any) (pres sys.bool)\n"
"export func sys.newselect (size sys.uint32) (sel *sys.uint8)\n"
"export func sys.selectsend (sel *sys.uint8, hchan *chan sys.any, elem sys.any) (selected sys.bool)\n"
"export func sys.selectrecv (sel *sys.uint8, hchan *chan sys.any, elem *sys.any) (selected sys.bool)\n"
"export func sys.selectgo (sel *sys.uint8)\n"
"export func sys.newarray (nel sys.uint32, cap sys.uint32, width sys.uint32) (ary *[]sys.any)\n"
"export func sys.arraysliced (old *[]sys.any, lb sys.uint32, hb sys.uint32, width sys.uint32) (ary *[]sys.any)\n"
"export func sys.arrayslices (old *sys.any, nel sys.uint32, lb sys.uint32, hb sys.uint32, width sys.uint32) (ary *[]sys.any)\n"
"export func sys.arrays2d (old *sys.any, nel sys.uint32) (ary *[]sys.any)\n"
"export func sys.catstring (? string, ? string) (? string)\n"
"export func sys.cmpstring (? string, ? string) (? int32)\n"
"export func sys.slicestring (? string, ? int32, ? int32) (? string)\n"
"export func sys.indexstring (? string, ? int32) (? uint8)\n"
"export func sys.intstring (? int64) (? string)\n"
"export func sys.byteastring (? *uint8, ? int32) (? string)\n"
"export func sys.arraystring (? *[]uint8) (? string)\n"
"export func sys.ifaceT2I (sigi *uint8, sigt *uint8, elem any) (ret any)\n"
"export func sys.ifaceI2T (sigt *uint8, iface any) (ret any)\n"
"export func sys.ifaceI2I (sigi *uint8, iface any) (ret any)\n"
"export func sys.ifaceeq (i1 any, i2 any) (ret bool)\n"
"export func sys.reflect (i interface { }) (? uint64, ? string)\n"
"export func sys.argc () (? int32)\n"
"export func sys.envc () (? int32)\n"
"export func sys.argv (? int32) (? string)\n"
"export func sys.envv (? int32) (? string)\n"
"export func sys.frexp (? float64) (? float64, ? int32)\n"
"export func sys.ldexp (? float64, ? int32) (? float64)\n"
"export func sys.modf (? float64) (? float64, ? float64)\n"
"export func sys.isInf (? float64, ? int32) (? bool)\n"
"export func sys.isNaN (? float64) (? bool)\n"
"export func sys.Inf (? int32) (? float64)\n"
"export func sys.NaN () (? float64)\n"
"export func sys.newmap (keysize uint32, valsize uint32, keyalg uint32, valalg uint32, hint uint32) (hmap *map[any] any)\n"
"export func sys.mapaccess1 (hmap *map[any] any, key any) (val any)\n"
"export func sys.mapaccess2 (hmap *map[any] any, key any) (val any, pres bool)\n"
"export func sys.mapassign1 (hmap *map[any] any, key any, val any)\n"
"export func sys.mapassign2 (hmap *map[any] any, key any, val any, pres bool)\n"
"export func sys.newchan (elemsize uint32, elemalg uint32, hint uint32) (hchan *chan any)\n"
"export func sys.chanrecv1 (hchan *chan any) (elem any)\n"
"export func sys.chanrecv2 (hchan *chan any) (elem any, pres bool)\n"
"export func sys.chanrecv3 (hchan *chan any, elem *any) (pres bool)\n"
"export func sys.chansend1 (hchan *chan any, elem any)\n"
"export func sys.chansend2 (hchan *chan any, elem any) (pres bool)\n"
"export func sys.newselect (size uint32) (sel *uint8)\n"
"export func sys.selectsend (sel *uint8, hchan *chan any, elem any) (selected bool)\n"
"export func sys.selectrecv (sel *uint8, hchan *chan any, elem *any) (selected bool)\n"
"export func sys.selectgo (sel *uint8)\n"
"export func sys.newarray (nel uint32, cap uint32, width uint32) (ary *[]any)\n"
"export func sys.arraysliced (old *[]any, lb uint32, hb uint32, width uint32) (ary *[]any)\n"
"export func sys.arrayslices (old *any, nel uint32, lb uint32, hb uint32, width uint32) (ary *[]any)\n"
"export func sys.arrays2d (old *any, nel uint32) (ary *[]any)\n"
"export func sys.gosched ()\n"
"export func sys.goexit ()\n"
"export func sys.readfile (? sys.string) (? sys.string, ? sys.bool)\n"
"export func sys.writefile (? sys.string, ? sys.string) (? sys.bool)\n"
"export func sys.bytestorune (? *sys.uint8, ? sys.int32, ? sys.int32) (? sys.int32, ? sys.int32)\n"
"export func sys.stringtorune (? sys.string, ? sys.int32) (? sys.int32, ? sys.int32)\n"
"export func sys.exit (? sys.int32)\n"
"export func sys.readfile (? string) (? string, ? bool)\n"
"export func sys.writefile (? string, ? string) (? bool)\n"
"export func sys.bytestorune (? *uint8, ? int32, ? int32) (? int32, ? int32)\n"
"export func sys.stringtorune (? string, ? int32) (? int32, ? int32)\n"
"export func sys.exit (? int32)\n"
"\n"
"$$\n";

View File

@ -47,24 +47,24 @@ static Map* hash[1009];
#define END nil,0,0,nil
Sigi sys·sigi_inter[2] = { (byte*)"sys·nilinter", 0, 0, nil, 0, 0 };
Sigi sys·sigi_inter[2] = { (byte*)"interface {}", 0, 0, nil, 0, 0 };
Sigt sys·sigt_int8[2] = { (byte*)"sys·int8", ASIMP, 1, nil, END };
Sigt sys·sigt_int16[2] = { (byte*)"sys·int16", ASIMP, 2, nil, END };
Sigt sys·sigt_int32[2] = { (byte*)"sys·int32", ASIMP, 4, nil, END };
Sigt sys·sigt_int64[2] = { (byte*)"sys·int64", ASIMP, 8, nil, END };
Sigt sys·sigt_int8[2] = { (byte*)"int8", ASIMP, 1, nil, END };
Sigt sys·sigt_int16[2] = { (byte*)"int16", ASIMP, 2, nil, END };
Sigt sys·sigt_int32[2] = { (byte*)"int32", ASIMP, 4, nil, END };
Sigt sys·sigt_int64[2] = { (byte*)"int64", ASIMP, 8, nil, END };
Sigt sys·sigt_uint8[2] = { (byte*)"sys·uint8", ASIMP, 1, nil, END };
Sigt sys·sigt_uint16[2] = { (byte*)"sys·uint16", ASIMP, 2, nil, END };
Sigt sys·sigt_uint32[2] = { (byte*)"sys·uint32", ASIMP, 4, nil, END };
Sigt sys·sigt_uint64[2] = { (byte*)"sys·uint64", ASIMP, 8, nil, END };
Sigt sys·sigt_uint8[2] = { (byte*)"uint8", ASIMP, 1, nil, END };
Sigt sys·sigt_uint16[2] = { (byte*)"uint16", ASIMP, 2, nil, END };
Sigt sys·sigt_uint32[2] = { (byte*)"uint32", ASIMP, 4, nil, END };
Sigt sys·sigt_uint64[2] = { (byte*)"uint64", ASIMP, 8, nil, END };
Sigt sys·sigt_float32[2] = { (byte*)"sys·float32", ASIMP, 4, nil, END };
Sigt sys·sigt_float64[2] = { (byte*)"sys·float64", ASIMP, 8, nil, END };
//Sigt sys·sigt_float80[2] = { (byte*)"sys·float80", ASIMP, 0, nil, END };
Sigt sys·sigt_float32[2] = { (byte*)"float32", ASIMP, 4, nil, END };
Sigt sys·sigt_float64[2] = { (byte*)"float64", ASIMP, 8, nil, END };
//Sigt sys·sigt_float80[2] = { (byte*)"float80", ASIMP, 0, nil, END };
Sigt sys·sigt_bool[2] = { (byte*)"sys·bool", ASIMP, 1, nil, END };
Sigt sys·sigt_string[2] = { (byte*)"sys·string", ASTRING, 8, nil, END };
Sigt sys·sigt_bool[2] = { (byte*)"bool", ASIMP, 1, nil, END };
Sigt sys·sigt_string[2] = { (byte*)"string", ASTRING, 8, nil, END };
static void
printsigi(Sigi *si)
@ -130,7 +130,7 @@ printiface(Map *im, void *it)
}
static Map*
hashmap(Sigi *si, Sigt *st)
hashmap(Sigi *si, Sigt *st, int32 canfail)
{
int32 nt, ni;
uint32 ihash, h;
@ -141,7 +141,8 @@ hashmap(Sigi *si, Sigt *st)
for(m=hash[h]; m!=nil; m=m->link) {
if(m->sigi == si && m->sigt == st) {
if(m->bad) {
throw("bad hashmap");
if(!canfail)
throw("bad hashmap");
m = nil;
}
// prints("old hashmap\n");
@ -169,14 +170,16 @@ hashmap(Sigi *si, Sigt *st)
// from structure signature
sname = st[nt].name;
if(sname == nil) {
prints("cannot convert type ");
prints((int8*)st[0].name);
prints(" to interface ");
prints((int8*)si[0].name);
prints(": missing method ");
prints((int8*)iname);
prints("\n");
throw("interface conversion");
if(!canfail) {
prints("cannot convert type ");
prints((int8*)st[0].name);
prints(" to interface ");
prints((int8*)si[0].name);
prints(": missing method ");
prints((int8*)iname);
prints("\n");
throw("interface conversion");
}
m->bad = 1;
m->link = hash[h];
hash[h] = m;
@ -209,7 +212,7 @@ sys·ifaceT2I(Sigi *si, Sigt *st, void *elem, Map *retim, void *retit)
prints("\n");
}
retim = hashmap(si, st);
retim = hashmap(si, st, 0);
// alg = st->hash;
// wid = st->offset;
@ -281,7 +284,7 @@ sys·ifaceI2I(Sigi *si, Map *im, void *it, Map *retim, void *retit)
retit = it;
retim = im;
if(im->sigi != si)
retim = hashmap(si, im->sigt);
retim = hashmap(si, im->sigt, 0);
}
if(debug) {
@ -347,3 +350,26 @@ sys·printinter(Map *im, void *it)
{
printiface(im, it);
}
void
sys·reflect(Map *im, void *it, uint64 retit, string rettype)
{
string s;
int32 n;
byte *type;
if(im == nil) {
retit = 0;
rettype = nil;
} else {
retit = (uint64)it;
type = im->sigt->name;
n = findnull((int8*)type);
s = mal(sizeof *s + n + 1);
s->len = n;
mcpy(s->str, type, n);
rettype = s;
}
FLUSH(&retit);
FLUSH(&rettype);
}

View File

@ -27,7 +27,7 @@ hello, world
*Inst
=========== ./interface2.go
cannot convert type S to interface I: missing method Foo
cannot convert type *main.S_interface2 to interface main.I_interface2: missing method Foo
throw: interface conversion
SIGSEGV: segmentation violation
Faulting address: 0x0
@ -35,7 +35,7 @@ pc: xxx
=========== ./interface3.go
cannot convert type S to interface I2: missing method Name
cannot convert type *main.S_interface3 to interface main.I2_interface3: missing method Name
throw: interface conversion
SIGSEGV: segmentation violation
Faulting address: 0x0
@ -126,12 +126,12 @@ BUG: fails incorrectly
=========== bugs/bug095.go
found 2, expected 1
panic on line 81 PC=xxx
panic on line 74 PC=xxx
BUG wrong result
=========== bugs/bug097.go
panic on line 83 PC=xxx
panic on line 76 PC=xxx
BUG wrong result
=========== bugs/bug098.go