| // Copyright 2009 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package reflect | |
| #include "runtime.h" | |
| #include "type.h" | |
| static Type* | |
| gettype(void *typ) | |
| { | |
| // typ is a *runtime.Type (or *runtime.MapType, etc), but the Type | |
| // defined in type.h includes an interface value header | |
| // in front of the raw structure. the -2 below backs up | |
| // to the interface value header. | |
| return (Type*)((void**)typ - 2); | |
| } | |
| /* | |
| * Go wrappers around the C functions near the bottom of hashmap.c | |
| * There's no recursion here even though it looks like there is: | |
| * the names after func are in the reflect package name space | |
| * but the names in the C bodies are in the standard C name space. | |
| */ | |
| func mapaccess(map *byte, key *byte, val *byte) (pres bool) { | |
| mapaccess((Hmap*)map, key, val, &pres); | |
| } | |
| func mapassign(map *byte, key *byte, val *byte) { | |
| mapassign((Hmap*)map, key, val); | |
| } | |
| func maplen(map *byte) (len int32) { | |
| // length is first word of map | |
| len = *(uint32*)map; | |
| } | |
| func mapiterinit(map *byte) (it *byte) { | |
| it = (byte*)mapiterinit((Hmap*)map); | |
| } | |
| func mapiternext(it *byte) { | |
| mapiternext((struct hash_iter*)it); | |
| } | |
| func mapiterkey(it *byte, key *byte) (ok bool) { | |
| ok = mapiterkey((struct hash_iter*)it, key); | |
| } | |
| func makemap(typ *byte) (map *byte) { | |
| MapType *t; | |
| t = (MapType*)gettype(typ); | |
| map = (byte*)makemap(t->key, t->elem, 0); | |
| } | |
| /* | |
| * Go wrappers around the C functions in chan.c | |
| */ | |
| func makechan(typ *byte, size uint32) (ch *byte) { | |
| ChanType *t; | |
| // typ is a *runtime.ChanType, but the ChanType | |
| // defined in type.h includes an interface value header | |
| // in front of the raw ChanType. the -2 below backs up | |
| // to the interface value header. | |
| t = (ChanType*)gettype(typ); | |
| ch = (byte*)makechan(t->elem, size); | |
| } | |
| func chansend(ch *byte, val *byte, pres *bool) { | |
| chansend((Hchan*)ch, val, pres); | |
| } | |
| func chanrecv(ch *byte, val *byte, pres *bool) { | |
| chanrecv((Hchan*)ch, val, pres); | |
| } | |
| func chanclose(ch *byte) { | |
| chanclose((Hchan*)ch); | |
| } | |
| func chanclosed(ch *byte) (r bool) { | |
| r = chanclosed((Hchan*)ch); | |
| } | |
| func chanlen(ch *byte) (r int32) { | |
| r = chanlen((Hchan*)ch); | |
| } | |
| func chancap(ch *byte) (r int32) { | |
| r = chancap((Hchan*)ch); | |
| } | |
| /* | |
| * Go wrappers around the functions in iface.c | |
| */ | |
| func setiface(typ *byte, x *byte, ret *byte) { | |
| InterfaceType *t; | |
| t = (InterfaceType*)gettype(typ); | |
| if(t->mhdr.len == 0) { | |
| // already an empty interface | |
| *(Eface*)ret = *(Eface*)x; | |
| return; | |
| } | |
| if(((Eface*)x)->type == nil) { | |
| // can assign nil to any interface | |
| ((Iface*)ret)->tab = nil; | |
| ((Iface*)ret)->data = nil; | |
| return; | |
| } | |
| ifaceE2I((InterfaceType*)gettype(typ), *(Eface*)x, (Iface*)ret); | |
| } |