re PR lto/48086 (bootstrap-lto creates c-common.s with too many sections on x86_64...
[official-gcc.git] / libgo / runtime / go-reflect-map.c
blob67960dee41e114215a7d8c2e74554c0cf3444f5f
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. */
7 #include <stdlib.h>
8 #include <stdint.h>
10 #include "go-alloc.h"
11 #include "go-type.h"
12 #include "map.h"
14 /* This file implements support for reflection on maps. These
15 functions are called from reflect/value.go. */
17 extern _Bool mapaccess (unsigned char *, unsigned char *, unsigned char *)
18 asm ("libgo_reflect.reflect.mapaccess");
20 _Bool
21 mapaccess (unsigned char *m, unsigned char *key, unsigned char *val)
23 struct __go_map *map = (struct __go_map *) m;
24 void *p;
25 const struct __go_type_descriptor *val_descriptor;
27 p = __go_map_index (map, key, 0);
28 if (p == NULL)
29 return 0;
30 else
32 val_descriptor = map->__descriptor->__map_descriptor->__val_type;
33 __builtin_memcpy (val, p, val_descriptor->__size);
34 return 1;
38 extern void mapassign (unsigned char *, unsigned char *, unsigned char *)
39 asm ("libgo_reflect.reflect.mapassign");
41 void
42 mapassign (unsigned char *m, unsigned char *key, unsigned char *val)
44 struct __go_map *map = (struct __go_map *) m;
46 if (val == NULL)
47 __go_map_delete (map, key);
48 else
50 void *p;
51 const struct __go_type_descriptor *val_descriptor;
53 p = __go_map_index (map, key, 1);
54 val_descriptor = map->__descriptor->__map_descriptor->__val_type;
55 __builtin_memcpy (p, val, val_descriptor->__size);
59 extern int32_t maplen (unsigned char *)
60 asm ("libgo_reflect.reflect.maplen");
62 int32_t
63 maplen (unsigned char *m __attribute__ ((unused)))
65 struct __go_map *map = (struct __go_map *) m;
66 return (int32_t) map->__element_count;
69 extern unsigned char *mapiterinit (unsigned char *)
70 asm ("libgo_reflect.reflect.mapiterinit");
72 unsigned char *
73 mapiterinit (unsigned char *m)
75 struct __go_hash_iter *it;
77 it = __go_alloc (sizeof (struct __go_hash_iter));
78 __go_mapiterinit ((struct __go_map *) m, it);
79 return (unsigned char *) it;
82 extern void mapiternext (unsigned char *)
83 asm ("libgo_reflect.reflect.mapiternext");
85 void
86 mapiternext (unsigned char *it)
88 __go_mapiternext ((struct __go_hash_iter *) it);
91 extern _Bool mapiterkey (unsigned char *, unsigned char *)
92 asm ("libgo_reflect.reflect.mapiterkey");
94 _Bool
95 mapiterkey (unsigned char *ita, unsigned char *key)
97 struct __go_hash_iter *it = (struct __go_hash_iter *) ita;
99 if (it->entry == NULL)
100 return 0;
101 else
103 __go_mapiter1 (it, key);
104 return 1;
108 /* Make a new map. We have to build our own map descriptor. */
110 extern unsigned char *makemap (const struct __go_map_type *)
111 asm ("libgo_reflect.reflect.makemap");
113 unsigned char *
114 makemap (const struct __go_map_type *t)
116 struct __go_map_descriptor *md;
117 unsigned int o;
118 const struct __go_type_descriptor *kt;
119 const struct __go_type_descriptor *vt;
121 /* FIXME: Reference count. */
122 md = (struct __go_map_descriptor *) __go_alloc (sizeof (*md));
123 md->__map_descriptor = t;
124 o = sizeof (void *);
125 kt = t->__key_type;
126 o = (o + kt->__field_align - 1) & ~ (kt->__field_align - 1);
127 md->__key_offset = o;
128 o += kt->__size;
129 vt = t->__val_type;
130 o = (o + vt->__field_align - 1) & ~ (vt->__field_align - 1);
131 md->__val_offset = o;
132 o += vt->__size;
133 o = (o + sizeof (void *) - 1) & ~ (sizeof (void *) - 1);
134 o = (o + kt->__field_align - 1) & ~ (kt->__field_align - 1);
135 o = (o + vt->__field_align - 1) & ~ (vt->__field_align - 1);
136 md->__entry_size = o;
138 return (unsigned char *) __go_new_map (md, 0);