// 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) {
	mapaccess((Hmap*)map, key, val, &pres);
}

func mapassign(map *byte, key *byte, val *byte) {
	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*)mapiterinit((Hmap*)map);
}

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

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

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

	t = (MapType*)gettype(typ);
	map = (byte*)makemap(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*)makechan(t->elem, size);
}

func chansend(ch *byte, val *byte, pres *bool) {
	chansend((Hchan*)ch, val, pres);
}

func chanrecv(ch *byte, val *byte, pres *bool) {
	chanrecv((Hchan*)ch, val, pres);
}

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

func chanclosed(ch *byte) (r bool) {
	r = chanclosed((Hchan*)ch);
}

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

func chancap(ch *byte) (r int32) {
	r = 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;
	}
	ifaceE2I((InterfaceType*)gettype(typ), *(Eface*)x, (Iface*)ret);
}
