go-reflect-map.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /* go-reflect-map.c -- map reflection support for Go.
  2. Copyright 2009, 2010 The Go Authors. All rights reserved.
  3. Use of this source code is governed by a BSD-style
  4. license that can be found in the LICENSE file. */
  5. #include <stdlib.h>
  6. #include <stdint.h>
  7. #include "runtime.h"
  8. #include "go-alloc.h"
  9. #include "go-assert.h"
  10. #include "go-type.h"
  11. #include "map.h"
  12. /* This file implements support for reflection on maps. These
  13. functions are called from reflect/value.go. */
  14. extern void *mapaccess (struct __go_map_type *, void *, void *)
  15. __asm__ (GOSYM_PREFIX "reflect.mapaccess");
  16. void *
  17. mapaccess (struct __go_map_type *mt, void *m, void *key)
  18. {
  19. struct __go_map *map = (struct __go_map *) m;
  20. __go_assert ((mt->__common.__code & GO_CODE_MASK) == GO_MAP);
  21. if (map == NULL)
  22. return NULL;
  23. else
  24. return __go_map_index (map, key, 0);
  25. }
  26. extern void mapassign (struct __go_map_type *, void *, void *, void *)
  27. __asm__ (GOSYM_PREFIX "reflect.mapassign");
  28. void
  29. mapassign (struct __go_map_type *mt, void *m, void *key, void *val)
  30. {
  31. struct __go_map *map = (struct __go_map *) m;
  32. void *p;
  33. __go_assert ((mt->__common.__code & GO_CODE_MASK) == GO_MAP);
  34. if (map == NULL)
  35. runtime_panicstring ("assignment to entry in nil map");
  36. p = __go_map_index (map, key, 1);
  37. __builtin_memcpy (p, val, mt->__val_type->__size);
  38. }
  39. extern void mapdelete (struct __go_map_type *, void *, void *)
  40. __asm__ (GOSYM_PREFIX "reflect.mapdelete");
  41. void
  42. mapdelete (struct __go_map_type *mt, void *m, void *key)
  43. {
  44. struct __go_map *map = (struct __go_map *) m;
  45. __go_assert ((mt->__common.__code & GO_CODE_MASK) == GO_MAP);
  46. if (map == NULL)
  47. return;
  48. __go_map_delete (map, key);
  49. }
  50. extern int32_t maplen (void *) __asm__ (GOSYM_PREFIX "reflect.maplen");
  51. int32_t
  52. maplen (void *m)
  53. {
  54. struct __go_map *map = (struct __go_map *) m;
  55. if (map == NULL)
  56. return 0;
  57. return (int32_t) map->__element_count;
  58. }
  59. extern unsigned char *mapiterinit (struct __go_map_type *, void *)
  60. __asm__ (GOSYM_PREFIX "reflect.mapiterinit");
  61. unsigned char *
  62. mapiterinit (struct __go_map_type *mt, void *m)
  63. {
  64. struct __go_hash_iter *it;
  65. __go_assert ((mt->__common.__code & GO_CODE_MASK) == GO_MAP);
  66. it = __go_alloc (sizeof (struct __go_hash_iter));
  67. __go_mapiterinit ((struct __go_map *) m, it);
  68. return (unsigned char *) it;
  69. }
  70. extern void mapiternext (void *) __asm__ (GOSYM_PREFIX "reflect.mapiternext");
  71. void
  72. mapiternext (void *it)
  73. {
  74. __go_mapiternext ((struct __go_hash_iter *) it);
  75. }
  76. extern void *mapiterkey (void *) __asm__ (GOSYM_PREFIX "reflect.mapiterkey");
  77. void *
  78. mapiterkey (void *ita)
  79. {
  80. struct __go_hash_iter *it = (struct __go_hash_iter *) ita;
  81. const struct __go_type_descriptor *key_descriptor;
  82. void *key;
  83. if (it->entry == NULL)
  84. return NULL;
  85. key_descriptor = it->map->__descriptor->__map_descriptor->__key_type;
  86. key = __go_alloc (key_descriptor->__size);
  87. __go_mapiter1 (it, key);
  88. return key;
  89. }
  90. /* Make a new map. We have to build our own map descriptor. */
  91. extern struct __go_map *makemap (const struct __go_map_type *)
  92. __asm__ (GOSYM_PREFIX "reflect.makemap");
  93. struct __go_map *
  94. makemap (const struct __go_map_type *t)
  95. {
  96. struct __go_map_descriptor *md;
  97. unsigned int o;
  98. const struct __go_type_descriptor *kt;
  99. const struct __go_type_descriptor *vt;
  100. md = (struct __go_map_descriptor *) __go_alloc (sizeof (*md));
  101. md->__map_descriptor = t;
  102. o = sizeof (void *);
  103. kt = t->__key_type;
  104. o = (o + kt->__field_align - 1) & ~ (kt->__field_align - 1);
  105. md->__key_offset = o;
  106. o += kt->__size;
  107. vt = t->__val_type;
  108. o = (o + vt->__field_align - 1) & ~ (vt->__field_align - 1);
  109. md->__val_offset = o;
  110. o += vt->__size;
  111. o = (o + sizeof (void *) - 1) & ~ (sizeof (void *) - 1);
  112. o = (o + kt->__field_align - 1) & ~ (kt->__field_align - 1);
  113. o = (o + vt->__field_align - 1) & ~ (vt->__field_align - 1);
  114. md->__entry_size = o;
  115. return __go_new_map (md, 0);
  116. }
  117. extern _Bool ismapkey (const struct __go_type_descriptor *)
  118. __asm__ (GOSYM_PREFIX "reflect.ismapkey");
  119. _Bool
  120. ismapkey (const struct __go_type_descriptor *typ)
  121. {
  122. return typ != NULL && typ->__hashfn != __go_type_hash_error;
  123. }