From 44b0ecc5caf0b700c0452429bdbc345111778fce Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 21 Oct 2008 15:38:26 -0700 Subject: [PATCH] 6g: use full type in sigt[0].name sys: add sys.reflect runtime: add canfail flag for later R=ken OCL=17583 CL=17583 --- src/cmd/6g/obj.c | 8 ++- src/cmd/gc/sys.go | 2 +- src/cmd/gc/sysimport.c | 117 +++++++++++++++++++---------------------- src/runtime/iface.c | 78 ++++++++++++++++++--------- test/golden.out | 8 +-- 5 files changed, 118 insertions(+), 95 deletions(-) diff --git a/src/cmd/6g/obj.c b/src/cmd/6g/obj.c index b4f44bbc3f..39e0b95574 100644 --- a/src/cmd/6g/obj.c +++ b/src/cmd/6g/obj.c @@ -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) { diff --git a/src/cmd/gc/sys.go b/src/cmd/gc/sys.go index c3c81a2db3..7aba0668b2 100644 --- a/src/cmd/gc/sys.go +++ b/src/cmd/gc/sys.go @@ -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); - diff --git a/src/cmd/gc/sysimport.c b/src/cmd/gc/sysimport.c index a5bbd073e6..2c16bc1e91 100644 --- a/src/cmd/gc/sysimport.c +++ b/src/cmd/gc/sysimport.c @@ -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"; diff --git a/src/runtime/iface.c b/src/runtime/iface.c index e4ec9d8e99..c73bd6d23e 100644 --- a/src/runtime/iface.c +++ b/src/runtime/iface.c @@ -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); +} diff --git a/test/golden.out b/test/golden.out index 472e2e670b..d7c87598a3 100644 --- a/test/golden.out +++ b/test/golden.out @@ -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 -- 2.48.1