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. */
19 extern void *mapaccess (struct __go_map_type
*, void *, void *)
20 __asm__ (GOSYM_PREFIX
"reflect.mapaccess");
23 mapaccess (struct __go_map_type
*mt
, void *m
, void *key
)
25 struct __go_map
*map
= (struct __go_map
*) m
;
27 __go_assert (mt
->__common
.__code
== GO_MAP
);
31 return __go_map_index (map
, key
, 0);
34 extern void mapassign (struct __go_map_type
*, void *, void *, void *)
35 __asm__ (GOSYM_PREFIX
"reflect.mapassign");
38 mapassign (struct __go_map_type
*mt
, void *m
, void *key
, void *val
)
40 struct __go_map
*map
= (struct __go_map
*) m
;
43 __go_assert (mt
->__common
.__code
== GO_MAP
);
45 runtime_panicstring ("assignment to entry in nil map");
46 p
= __go_map_index (map
, key
, 1);
47 __builtin_memcpy (p
, val
, mt
->__val_type
->__size
);
50 extern void mapdelete (struct __go_map_type
*, void *, void *)
51 __asm__ (GOSYM_PREFIX
"reflect.mapdelete");
54 mapdelete (struct __go_map_type
*mt
, void *m
, void *key
)
56 struct __go_map
*map
= (struct __go_map
*) m
;
58 __go_assert (mt
->__common
.__code
== GO_MAP
);
61 __go_map_delete (map
, key
);
64 extern int32_t maplen (void *) __asm__ (GOSYM_PREFIX
"reflect.maplen");
69 struct __go_map
*map
= (struct __go_map
*) m
;
73 return (int32_t) map
->__element_count
;
76 extern unsigned char *mapiterinit (struct __go_map_type
*, void *)
77 __asm__ (GOSYM_PREFIX
"reflect.mapiterinit");
80 mapiterinit (struct __go_map_type
*mt
, void *m
)
82 struct __go_hash_iter
*it
;
84 __go_assert (mt
->__common
.__code
== GO_MAP
);
85 it
= __go_alloc (sizeof (struct __go_hash_iter
));
86 __go_mapiterinit ((struct __go_map
*) m
, it
);
87 return (unsigned char *) it
;
90 extern void mapiternext (void *) __asm__ (GOSYM_PREFIX
"reflect.mapiternext");
93 mapiternext (void *it
)
95 __go_mapiternext ((struct __go_hash_iter
*) it
);
98 extern void *mapiterkey (void *) __asm__ (GOSYM_PREFIX
"reflect.mapiterkey");
101 mapiterkey (void *ita
)
103 struct __go_hash_iter
*it
= (struct __go_hash_iter
*) ita
;
104 const struct __go_type_descriptor
*key_descriptor
;
107 if (it
->entry
== NULL
)
110 key_descriptor
= it
->map
->__descriptor
->__map_descriptor
->__key_type
;
111 key
= __go_alloc (key_descriptor
->__size
);
112 __go_mapiter1 (it
, key
);
116 /* Make a new map. We have to build our own map descriptor. */
118 extern struct __go_map
*makemap (const struct __go_map_type
*)
119 __asm__ (GOSYM_PREFIX
"reflect.makemap");
122 makemap (const struct __go_map_type
*t
)
124 struct __go_map_descriptor
*md
;
126 const struct __go_type_descriptor
*kt
;
127 const struct __go_type_descriptor
*vt
;
129 md
= (struct __go_map_descriptor
*) __go_alloc (sizeof (*md
));
130 md
->__map_descriptor
= t
;
133 o
= (o
+ kt
->__field_align
- 1) & ~ (kt
->__field_align
- 1);
134 md
->__key_offset
= o
;
137 o
= (o
+ vt
->__field_align
- 1) & ~ (vt
->__field_align
- 1);
138 md
->__val_offset
= o
;
140 o
= (o
+ sizeof (void *) - 1) & ~ (sizeof (void *) - 1);
141 o
= (o
+ kt
->__field_align
- 1) & ~ (kt
->__field_align
- 1);
142 o
= (o
+ vt
->__field_align
- 1) & ~ (vt
->__field_align
- 1);
143 md
->__entry_size
= o
;
145 return __go_new_map (md
, 0);
148 extern _Bool
ismapkey (const struct __go_type_descriptor
*)
149 __asm__ (GOSYM_PREFIX
"reflect.ismapkey");
152 ismapkey (const struct __go_type_descriptor
*typ
)
154 return typ
!= NULL
&& typ
->__hashfn
!= __go_type_hash_error
;