| // 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) { |
| runtime·mapaccess((Hmap*)map, key, val, &pres); |
| } |
| |
| func mapassign(map *byte, key *byte, val *byte) { |
| runtime·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*)runtime·newmapiterinit((Hmap*)map); |
| } |
| |
| func mapiternext(it *byte) { |
| runtime·mapiternext((struct hash_iter*)it); |
| } |
| |
| func mapiterkey(it *byte, key *byte) (ok bool) { |
| ok = runtime·mapiterkey((struct hash_iter*)it, key); |
| } |
| |
| func makemap(typ *byte) (map *byte) { |
| MapType *t; |
| |
| t = (MapType*)gettype(typ); |
| map = (byte*)runtime·makemap_c(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*)runtime·makechan_c(t->elem, size); |
| } |
| |
| func chansend(ch *byte, val *byte, pres *bool) { |
| runtime·chansend((Hchan*)ch, val, pres); |
| } |
| |
| func chanrecv(ch *byte, val *byte, pres *bool) { |
| runtime·chanrecv((Hchan*)ch, val, pres); |
| } |
| |
| func chanclose(ch *byte) { |
| runtime·chanclose((Hchan*)ch); |
| } |
| |
| func chanclosed(ch *byte) (r bool) { |
| r = runtime·chanclosed((Hchan*)ch); |
| } |
| |
| func chanlen(ch *byte) (r int32) { |
| r = runtime·chanlen((Hchan*)ch); |
| } |
| |
| func chancap(ch *byte) (r int32) { |
| r = runtime·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; |
| } |
| runtime·ifaceE2I((InterfaceType*)gettype(typ), *(Eface*)x, (Iface*)ret); |
| } |