github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gofrontend/libgo/runtime/go-reflect-map.c (about) 1 /* go-reflect-map.c -- map reflection support for Go. 2 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. */ 6 7 #include <stdlib.h> 8 #include <stdint.h> 9 10 #include "runtime.h" 11 #include "go-alloc.h" 12 #include "go-assert.h" 13 #include "go-type.h" 14 #include "map.h" 15 16 /* This file implements support for reflection on maps. These 17 functions are called from reflect/value.go. */ 18 19 extern void *mapaccess (struct __go_map_type *, void *, void *) 20 __asm__ (GOSYM_PREFIX "reflect.mapaccess"); 21 22 void * 23 mapaccess (struct __go_map_type *mt, void *m, void *key) 24 { 25 struct __go_map *map = (struct __go_map *) m; 26 27 __go_assert ((mt->__common.__code & GO_CODE_MASK) == GO_MAP); 28 if (map == NULL) 29 return NULL; 30 else 31 return __go_map_index (map, key, 0); 32 } 33 34 extern void mapassign (struct __go_map_type *, void *, void *, void *) 35 __asm__ (GOSYM_PREFIX "reflect.mapassign"); 36 37 void 38 mapassign (struct __go_map_type *mt, void *m, void *key, void *val) 39 { 40 struct __go_map *map = (struct __go_map *) m; 41 void *p; 42 43 __go_assert ((mt->__common.__code & GO_CODE_MASK) == GO_MAP); 44 if (map == NULL) 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); 48 } 49 50 extern void mapdelete (struct __go_map_type *, void *, void *) 51 __asm__ (GOSYM_PREFIX "reflect.mapdelete"); 52 53 void 54 mapdelete (struct __go_map_type *mt, void *m, void *key) 55 { 56 struct __go_map *map = (struct __go_map *) m; 57 58 __go_assert ((mt->__common.__code & GO_CODE_MASK) == GO_MAP); 59 if (map == NULL) 60 return; 61 __go_map_delete (map, key); 62 } 63 64 extern int32_t maplen (void *) __asm__ (GOSYM_PREFIX "reflect.maplen"); 65 66 int32_t 67 maplen (void *m) 68 { 69 struct __go_map *map = (struct __go_map *) m; 70 71 if (map == NULL) 72 return 0; 73 return (int32_t) map->__element_count; 74 } 75 76 extern unsigned char *mapiterinit (struct __go_map_type *, void *) 77 __asm__ (GOSYM_PREFIX "reflect.mapiterinit"); 78 79 unsigned char * 80 mapiterinit (struct __go_map_type *mt, void *m) 81 { 82 struct __go_hash_iter *it; 83 84 __go_assert ((mt->__common.__code & GO_CODE_MASK) == GO_MAP); 85 it = __go_alloc (sizeof (struct __go_hash_iter)); 86 __go_mapiterinit ((struct __go_map *) m, it); 87 return (unsigned char *) it; 88 } 89 90 extern void mapiternext (void *) __asm__ (GOSYM_PREFIX "reflect.mapiternext"); 91 92 void 93 mapiternext (void *it) 94 { 95 __go_mapiternext ((struct __go_hash_iter *) it); 96 } 97 98 extern void *mapiterkey (void *) __asm__ (GOSYM_PREFIX "reflect.mapiterkey"); 99 100 void * 101 mapiterkey (void *ita) 102 { 103 struct __go_hash_iter *it = (struct __go_hash_iter *) ita; 104 const struct __go_type_descriptor *key_descriptor; 105 void *key; 106 107 if (it->entry == NULL) 108 return NULL; 109 110 key_descriptor = it->map->__descriptor->__map_descriptor->__key_type; 111 key = __go_alloc (key_descriptor->__size); 112 __go_mapiter1 (it, key); 113 return key; 114 } 115 116 /* Make a new map. We have to build our own map descriptor. */ 117 118 extern struct __go_map *makemap (const struct __go_map_type *) 119 __asm__ (GOSYM_PREFIX "reflect.makemap"); 120 121 struct __go_map * 122 makemap (const struct __go_map_type *t) 123 { 124 struct __go_map_descriptor *md; 125 unsigned int o; 126 const struct __go_type_descriptor *kt; 127 const struct __go_type_descriptor *vt; 128 129 md = (struct __go_map_descriptor *) __go_alloc (sizeof (*md)); 130 md->__map_descriptor = t; 131 o = sizeof (void *); 132 kt = t->__key_type; 133 o = (o + kt->__field_align - 1) & ~ (kt->__field_align - 1); 134 md->__key_offset = o; 135 o += kt->__size; 136 vt = t->__val_type; 137 o = (o + vt->__field_align - 1) & ~ (vt->__field_align - 1); 138 md->__val_offset = o; 139 o += vt->__size; 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; 144 145 return __go_new_map (md, 0); 146 } 147 148 extern _Bool ismapkey (const struct __go_type_descriptor *) 149 __asm__ (GOSYM_PREFIX "reflect.ismapkey"); 150 151 _Bool 152 ismapkey (const struct __go_type_descriptor *typ) 153 { 154 return (typ != NULL 155 && (void *) typ->__hashfn->fn != (void *) __go_type_hash_error); 156 }