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. */
11 #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 __go_panic_msg ("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
;