/* go-reflect-map.c -- map reflection support for Go.

   Copyright 2009, 2010 The Go Authors. All rights reserved.
   Use of this source code is governed by a BSD-style
   license that can be found in the LICENSE file.  */

#include <stdlib.h>
#include <stdint.h>

#include "runtime.h"
#include "go-alloc.h"
#include "go-assert.h"
#include "go-type.h"
#include "map.h"

/* This file implements support for reflection on maps.  These
   functions are called from reflect/value.go.  */

extern void *mapaccess (struct __go_map_type *, void *, void *)
  __asm__ (GOSYM_PREFIX "reflect.mapaccess");

void *
mapaccess (struct __go_map_type *mt, void *m, void *key)
{
  struct __go_map *map = (struct __go_map *) m;

  __go_assert (mt->__common.__code == GO_MAP);
  if (map == NULL)
    return NULL;
  else
    return __go_map_index (map, key, 0);
}

extern void mapassign (struct __go_map_type *, void *, void *, void *)
  __asm__ (GOSYM_PREFIX "reflect.mapassign");

void
mapassign (struct __go_map_type *mt, void *m, void *key, void *val)
{
  struct __go_map *map = (struct __go_map *) m;
  void *p;

  __go_assert (mt->__common.__code == GO_MAP);
  if (map == NULL)
    runtime_panicstring ("assignment to entry in nil map");
  p = __go_map_index (map, key, 1);
  __builtin_memcpy (p, val, mt->__val_type->__size);
}

extern void mapdelete (struct __go_map_type *, void *, void *)
  __asm__ (GOSYM_PREFIX "reflect.mapdelete");

void
mapdelete (struct __go_map_type *mt, void *m, void *key)
{
  struct __go_map *map = (struct __go_map *) m;

  __go_assert (mt->__common.__code == GO_MAP);
  if (map == NULL)
    return;
  __go_map_delete (map, key);
}

extern int32_t maplen (void *) __asm__ (GOSYM_PREFIX "reflect.maplen");

int32_t
maplen (void *m)
{
  struct __go_map *map = (struct __go_map *) m;

  if (map == NULL)
    return 0;
  return (int32_t) map->__element_count;
}

extern unsigned char *mapiterinit (struct __go_map_type *, void *)
  __asm__ (GOSYM_PREFIX "reflect.mapiterinit");

unsigned char *
mapiterinit (struct __go_map_type *mt, void *m)
{
  struct __go_hash_iter *it;

  __go_assert (mt->__common.__code == GO_MAP);
  it = __go_alloc (sizeof (struct __go_hash_iter));
  __go_mapiterinit ((struct __go_map *) m, it);
  return (unsigned char *) it;
}

extern void mapiternext (void *) __asm__ (GOSYM_PREFIX "reflect.mapiternext");

void
mapiternext (void *it)
{
  __go_mapiternext ((struct __go_hash_iter *) it);
}

extern void *mapiterkey (void *) __asm__ (GOSYM_PREFIX "reflect.mapiterkey");

void *
mapiterkey (void *ita)
{
  struct __go_hash_iter *it = (struct __go_hash_iter *) ita;
  const struct __go_type_descriptor *key_descriptor;
  void *key;

  if (it->entry == NULL)
    return NULL;

  key_descriptor = it->map->__descriptor->__map_descriptor->__key_type;
  key = __go_alloc (key_descriptor->__size);
  __go_mapiter1 (it, key);
  return key;
}

/* Make a new map.  We have to build our own map descriptor.  */

extern struct __go_map *makemap (const struct __go_map_type *)
  __asm__ (GOSYM_PREFIX "reflect.makemap");

struct __go_map *
makemap (const struct __go_map_type *t)
{
  struct __go_map_descriptor *md;
  unsigned int o;
  const struct __go_type_descriptor *kt;
  const struct __go_type_descriptor *vt;

  md = (struct __go_map_descriptor *) __go_alloc (sizeof (*md));
  md->__map_descriptor = t;
  o = sizeof (void *);
  kt = t->__key_type;
  o = (o + kt->__field_align - 1) & ~ (kt->__field_align - 1);
  md->__key_offset = o;
  o += kt->__size;
  vt = t->__val_type;
  o = (o + vt->__field_align - 1) & ~ (vt->__field_align - 1);
  md->__val_offset = o;
  o += vt->__size;
  o = (o + sizeof (void *) - 1) & ~ (sizeof (void *) - 1);
  o = (o + kt->__field_align - 1) & ~ (kt->__field_align - 1);
  o = (o + vt->__field_align - 1) & ~ (vt->__field_align - 1);
  md->__entry_size = o;

  return __go_new_map (md, 0);
}

extern _Bool ismapkey (const struct __go_type_descriptor *)
  __asm__ (GOSYM_PREFIX "reflect.ismapkey");

_Bool
ismapkey (const struct __go_type_descriptor *typ)
{
  return typ != NULL && typ->__hashfn != __go_type_hash_error;
}
