// Copyright 2009 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.

package reflect
#include "runtime.h"
#include "type.h"

static Type*
gettype(void *typ)
{
	// typ is a *runtime.Type (or *runtime.MapType, etc), but the Type
	// defined in type.h includes an interface value header
	// in front of the raw structure.  the -2 below backs up
	// to the interface value header.
	return (Type*)((void**)typ - 2);
}

/*
 * Go wrappers around the C functions near the bottom of hashmap.c
 * There's no recursion here even though it looks like there is:
 * the names after func are in the reflect package name space
 * but the names in the C bodies are in the standard C name space.
 */

func mapaccess(map *byte, key *byte, val *byte) (pres bool) {
	runtime·mapaccess((Hmap*)map, key, val, &pres);
}

func mapassign(map *byte, key *byte, val *byte) {
	runtime·mapassign((Hmap*)map, key, val);
}

func maplen(map *byte) (len int32) {
	// length is first word of map
	len = *(uint32*)map;
}

func mapiterinit(map *byte) (it *byte) {
	it = (byte*)runtime·newmapiterinit((Hmap*)map);
}

func mapiternext(it *byte) {
	runtime·mapiternext((struct hash_iter*)it);
}

func mapiterkey(it *byte, key *byte) (ok bool) {
	ok = runtime·mapiterkey((struct hash_iter*)it, key);
}

func makemap(typ *byte) (map *byte) {
	MapType *t;

	t = (MapType*)gettype(typ);
	map = (byte*)runtime·makemap_c(t->key, t->elem, 0);
}

/*
 * Go wrappers around the C functions in chan.c
 */

func makechan(typ *byte, size uint32) (ch *byte) {
	ChanType *t;

	// typ is a *runtime.ChanType, but the ChanType
	// defined in type.h includes an interface value header
	// in front of the raw ChanType.  the -2 below backs up
	// to the interface value header.
	t = (ChanType*)gettype(typ);
	ch = (byte*)runtime·makechan_c(t->elem, size);
}

func chansend(ch *byte, val *byte, selected *bool) {
	runtime·chansend((Hchan*)ch, val, selected);
}

func chanrecv(ch *byte, val *byte, selected *bool, received *bool) {
	runtime·chanrecv((Hchan*)ch, val, selected, received);
}

func chanclose(ch *byte) {
	runtime·chanclose((Hchan*)ch);
}

func chanlen(ch *byte) (r int32) {
	r = runtime·chanlen((Hchan*)ch);
}

func chancap(ch *byte) (r int32) {
	r = runtime·chancap((Hchan*)ch);
}


/*
 * Go wrappers around the functions in iface.c
 */

func setiface(typ *byte, x *byte, ret *byte) {
	InterfaceType *t;

	t = (InterfaceType*)gettype(typ);
	if(t->mhdr.len == 0) {
		// already an empty interface
		*(Eface*)ret = *(Eface*)x;
		return;
	}
	if(((Eface*)x)->type == nil) {
		// can assign nil to any interface
		((Iface*)ret)->tab = nil;
		((Iface*)ret)->data = nil;
		return;
	}
	runtime·ifaceE2I((InterfaceType*)gettype(typ), *(Eface*)x, (Iface*)ret);
}
