1 /* go-reflect-map.c -- map reflection support for Go.
3 Copyright 2009, 2010 The Go Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style
5 license that can be found in the LICENSE file. */
12 #include "go-assert.h"
16 /* This file implements support for reflection on maps. These
17 functions are called from reflect/value.go. */
25 extern struct mapaccess_ret mapaccess (struct __go_map_type *, uintptr_t,
27 asm ("libgo_reflect.reflect.mapaccess");
30 mapaccess (struct __go_map_type *mt, uintptr_t m, uintptr_t key_i)
32 struct __go_map *map = (struct __go_map *) m;
34 const struct __go_type_descriptor *key_descriptor;
36 const struct __go_type_descriptor *val_descriptor;
37 struct mapaccess_ret ret;
41 __go_assert (mt->__common.__code == GO_MAP);
43 key_descriptor = mt->__key_type;
44 if (__go_is_pointer_type (key_descriptor))
52 p = __go_map_index (map, key, 0);
54 val_descriptor = mt->__val_type;
55 if (__go_is_pointer_type (val_descriptor))
62 val = __go_alloc (val_descriptor->__size);
70 __builtin_memcpy (pv, p, val_descriptor->__size);
74 ret.val = (uintptr_t) val;
78 extern void mapassign (struct __go_map_type *, uintptr_t, uintptr_t,
80 asm ("libgo_reflect.reflect.mapassign");
83 mapassign (struct __go_map_type *mt, uintptr_t m, uintptr_t key_i,
84 uintptr_t val_i, _Bool pres)
86 struct __go_map *map = (struct __go_map *) m;
87 const struct __go_type_descriptor *key_descriptor;
90 __go_assert (mt->__common.__code == GO_MAP);
93 runtime_panicstring ("assignment to entry in nil map");
95 key_descriptor = mt->__key_type;
96 if (__go_is_pointer_type (key_descriptor))
102 __go_map_delete (map, key);
106 const struct __go_type_descriptor *val_descriptor;
109 p = __go_map_index (map, key, 1);
111 val_descriptor = mt->__val_type;
112 if (__go_is_pointer_type (val_descriptor))
116 __builtin_memcpy (p, pv, val_descriptor->__size);
120 extern int32_t maplen (uintptr_t)
121 asm ("libgo_reflect.reflect.maplen");
126 struct __go_map *map = (struct __go_map *) m;
130 return (int32_t) map->__element_count;
133 extern unsigned char *mapiterinit (struct __go_map_type *, uintptr_t)
134 asm ("libgo_reflect.reflect.mapiterinit");
137 mapiterinit (struct __go_map_type *mt, uintptr_t m)
139 struct __go_hash_iter *it;
141 __go_assert (mt->__common.__code == GO_MAP);
142 it = __go_alloc (sizeof (struct __go_hash_iter));
143 __go_mapiterinit ((struct __go_map *) m, it);
144 return (unsigned char *) it;
147 extern void mapiternext (unsigned char *)
148 asm ("libgo_reflect.reflect.mapiternext");
151 mapiternext (unsigned char *it)
153 __go_mapiternext ((struct __go_hash_iter *) it);
156 struct mapiterkey_ret
162 extern struct mapiterkey_ret mapiterkey (unsigned char *)
163 asm ("libgo_reflect.reflect.mapiterkey");
165 struct mapiterkey_ret
166 mapiterkey (unsigned char *ita)
168 struct __go_hash_iter *it = (struct __go_hash_iter *) ita;
169 struct mapiterkey_ret ret;
171 if (it->entry == NULL)
178 const struct __go_type_descriptor *key_descriptor;
182 key_descriptor = it->map->__descriptor->__map_descriptor->__key_type;
183 if (__go_is_pointer_type (key_descriptor))
190 key = __go_alloc (key_descriptor->__size);
194 __go_mapiter1 (it, pk);
196 ret.key = (uintptr_t) key;
203 /* Make a new map. We have to build our own map descriptor. */
205 extern uintptr_t makemap (const struct __go_map_type *)
206 asm ("libgo_reflect.reflect.makemap");
209 makemap (const struct __go_map_type *t)
211 struct __go_map_descriptor *md;
213 const struct __go_type_descriptor *kt;
214 const struct __go_type_descriptor *vt;
215 struct __go_map* map;
218 /* FIXME: Reference count. */
219 md = (struct __go_map_descriptor *) __go_alloc (sizeof (*md));
220 md->__map_descriptor = t;
223 o = (o + kt->__field_align - 1) & ~ (kt->__field_align - 1);
224 md->__key_offset = o;
227 o = (o + vt->__field_align - 1) & ~ (vt->__field_align - 1);
228 md->__val_offset = o;
230 o = (o + sizeof (void *) - 1) & ~ (sizeof (void *) - 1);
231 o = (o + kt->__field_align - 1) & ~ (kt->__field_align - 1);
232 o = (o + vt->__field_align - 1) & ~ (vt->__field_align - 1);
233 md->__entry_size = o;
235 map = __go_new_map (md, 0);
237 ret = __go_alloc (sizeof (void *));
238 __builtin_memcpy (ret, &map, sizeof (void *));
239 return (uintptr_t) ret;