// 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 runtime
#include "runtime.h"
#include "arch_GOARCH.h"
#include "type.h"
#include "typekind.h"
#include "malloc.h"
#include "../../cmd/ld/textflag.h"

func printiface(i Iface) {
	runtime·printf("(%p,%p)", i.tab, i.data);
}

func printeface(e Eface) {
	runtime·printf("(%p,%p)", e.type, e.data);
}

static	Itab*	hash[1009];
static	Lock	ifacelock;

static Itab*
itab(InterfaceType *inter, Type *type, int32 canfail)
{
	int32 locked;
	int32 ni;
	Method *t, *et;
	IMethod *i, *ei;
	uint32 h;
	String *iname, *ipkgPath;
	Itab *m;
	UncommonType *x;
	Type *itype;
	Eface err;

	if(inter->mhdr.len == 0)
		runtime·throw("internal error - misuse of itab");

	locked = 0;

	// easy case
	x = type->x;
	if(x == nil) {
		if(canfail)
			return nil;
		iname = inter->m[0].name;
		goto throw;
	}

	// compiler has provided some good hash codes for us.
	h = inter->hash;
	h += 17 * type->hash;
	// TODO(rsc): h += 23 * x->mhash ?
	h %= nelem(hash);

	// look twice - once without lock, once with.
	// common case will be no lock contention.
	for(locked=0; locked<2; locked++) {
		if(locked)
			runtime·lock(&ifacelock);
		for(m=runtime·atomicloadp(&hash[h]); m!=nil; m=m->link) {
			if(m->inter == inter && m->type == type) {
				if(m->bad) {
					m = nil;
					if(!canfail) {
						// this can only happen if the conversion
						// was already done once using the , ok form
						// and we have a cached negative result.
						// the cached result doesn't record which
						// interface function was missing, so jump
						// down to the interface check, which will
						// do more work but give a better error.
						goto search;
					}
				}
				if(locked)
					runtime·unlock(&ifacelock);
				return m;
			}
		}
	}

	ni = inter->mhdr.len;
	m = runtime·persistentalloc(sizeof(*m) + ni*sizeof m->fun[0], 0, &mstats.other_sys);
	m->inter = inter;
	m->type = type;

search:
	// both inter and type have method sorted by name,
	// and interface names are unique,
	// so can iterate over both in lock step;
	// the loop is O(ni+nt) not O(ni*nt).
	i = inter->m;
	ei = i + inter->mhdr.len;
	t = x->m;
	et = t + x->mhdr.len;
	for(; i < ei; i++) {
		itype = i->type;
		iname = i->name;
		ipkgPath = i->pkgPath;
		for(;; t++) {
			if(t >= et) {
				if(!canfail) {
				throw:
					// didn't find method
					runtime·newTypeAssertionError(
						nil, type->string, inter->string,
						iname, &err);
					if(locked)
						runtime·unlock(&ifacelock);
					runtime·panic(err);
					return nil;	// not reached
				}
				m->bad = 1;
				goto out;
			}
			if(t->mtyp == itype && t->name == iname && t->pkgPath == ipkgPath)
				break;
		}
		if(m)
			m->fun[i - inter->m] = t->ifn;
	}

out:
	if(!locked)
		runtime·panicstring("invalid itab locking");
	m->link = hash[h];
	runtime·atomicstorep(&hash[h], m);
	runtime·unlock(&ifacelock);
	if(m->bad)
		return nil;
	return m;
}

// call the callback for every itab that is currently allocated.
void
runtime·iterate_itabs(void (*callback)(Itab*))
{
	int32 i;
	Itab *tab;

	for(i = 0; i < nelem(hash); i++) {
		for(tab = hash[i]; tab != nil; tab = tab->link) {
			callback(tab);
		}
	}
}

static void
copyin(Type *t, void *src, void **dst)
{
	uintptr size;
	void *p;
	Alg *alg;

	size = t->size;
	alg = t->alg;

	if(size <= sizeof(*dst))
		alg->copy(size, dst, src);
	else {
		p = runtime·mal(size);
		alg->copy(size, p, src);
		*dst = p;
	}
}

static void
copyout(Type *t, void **src, void *dst)
{
	uintptr size;
	Alg *alg;

	size = t->size;
	alg = t->alg;

	if(size <= sizeof(*src))
		alg->copy(size, dst, src);
	else
		alg->copy(size, dst, *src);
}

#pragma textflag NOSPLIT
func typ2Itab(t *Type, inter *InterfaceType, cache **Itab) (tab *Itab) {
	tab = itab(inter, t, 0);
	runtime·atomicstorep(cache, tab);
}

#pragma textflag NOSPLIT
func convT2I(t *Type, inter *InterfaceType, cache **Itab, elem *byte) (ret Iface) {
	Itab *tab;

	tab = runtime·atomicloadp(cache);
	if(!tab) {
		tab = itab(inter, t, 0);
		runtime·atomicstorep(cache, tab);
	}
	ret.tab = tab;
	copyin(t, elem, &ret.data);
}

#pragma textflag NOSPLIT
func convT2E(t *Type, elem *byte) (ret Eface) {
	ret.type = t;
	copyin(t, elem, &ret.data);
}

static void assertI2Tret(Type *t, Iface i, byte *ret);

#pragma textflag NOSPLIT
func assertI2T(t *Type, i Iface) (ret byte, ...) {
	assertI2Tret(t, i, &ret);
}

static void
assertI2Tret(Type *t, Iface i, byte *ret)
{
	Itab *tab;
	Eface err;

	tab = i.tab;
	if(tab == nil) {
		runtime·newTypeAssertionError(
			nil, nil, t->string,
			nil, &err);
		runtime·panic(err);
	}
	if(tab->type != t) {
		runtime·newTypeAssertionError(
			tab->inter->string, tab->type->string, t->string,
			nil, &err);
		runtime·panic(err);
	}
	copyout(t, &i.data, ret);
}

#pragma textflag NOSPLIT
func assertI2T2(t *Type, i Iface) (ret byte, ...) {
	bool *ok;
	int32 wid;

	wid = t->size;
	ok = (bool*)(&ret + wid);

	if(i.tab == nil || i.tab->type != t) {
		*ok = false;
		runtime·memclr(&ret, wid);
		return;
	}

	*ok = true;
	copyout(t, &i.data, &ret);
}

func assertI2TOK(t *Type, i Iface) (ok bool) {
	ok = i.tab!=nil && i.tab->type==t;
}

static void assertE2Tret(Type *t, Eface e, byte *ret);

#pragma textflag NOSPLIT
func assertE2T(t *Type, e Eface) (ret byte, ...) {
	assertE2Tret(t, e, &ret);
}

static void
assertE2Tret(Type *t, Eface e, byte *ret)
{
	Eface err;

	if(e.type == nil) {
		runtime·newTypeAssertionError(
			nil, nil, t->string,
			nil, &err);
		runtime·panic(err);
	}
	if(e.type != t) {
		runtime·newTypeAssertionError(
			nil, e.type->string, t->string,
			nil, &err);
		runtime·panic(err);
	}
	copyout(t, &e.data, ret);
}

#pragma textflag NOSPLIT
func assertE2T2(t *Type, e Eface) (ret byte, ...) {
	bool *ok;
	int32 wid;

	wid = t->size;
	ok = (bool*)(&ret + wid);

	if(t != e.type) {
		*ok = false;
		runtime·memclr(&ret, wid);
		return;
	}

	*ok = true;
	copyout(t, &e.data, &ret);
}

func assertE2TOK(t *Type, e Eface) (ok bool) {
	ok = t==e.type;
}

func convI2E(i Iface) (ret Eface) {
	Itab *tab;

	ret.data = i.data;
	if((tab = i.tab) == nil)
		ret.type = nil;
	else
		ret.type = tab->type;
}

func assertI2E(inter *InterfaceType, i Iface) (ret Eface) {
	Itab *tab;
	Eface err;

	tab = i.tab;
	if(tab == nil) {
		// explicit conversions require non-nil interface value.
		runtime·newTypeAssertionError(
			nil, nil, inter->string,
			nil, &err);
		runtime·panic(err);
	}
	ret.data = i.data;
	ret.type = tab->type;
}

func assertI2E2(inter *InterfaceType, i Iface) (ret Eface, ok bool) {
	Itab *tab;

	USED(inter);
	tab = i.tab;
	if(tab == nil) {
		ret.type = nil;
		ok = 0;
	} else {
		ret.type = tab->type;
		ok = 1;
	}
	ret.data = i.data;
}

func convI2I(inter *InterfaceType, i Iface) (ret Iface) {
	Itab *tab;

	ret.data = i.data;
	if((tab = i.tab) == nil)
		ret.tab = nil;
	else if(tab->inter == inter)
		ret.tab = tab;
	else
		ret.tab = itab(inter, tab->type, 0);
}

void
runtime·ifaceI2I(InterfaceType *inter, Iface i, Iface *ret)
{
	Itab *tab;
	Eface err;

	tab = i.tab;
	if(tab == nil) {
		// explicit conversions require non-nil interface value.
		runtime·newTypeAssertionError(
			nil, nil, inter->string,
			nil, &err);
		runtime·panic(err);
	}
	ret->data = i.data;
	ret->tab = itab(inter, tab->type, 0);
}

func assertI2I(inter *InterfaceType, i Iface) (ret Iface) {
	runtime·ifaceI2I(inter, i, &ret);
}

func assertI2I2(inter *InterfaceType, i Iface) (ret Iface, ok bool) {
	Itab *tab;

	tab = i.tab;
	if(tab != nil && (tab->inter == inter || (tab = itab(inter, tab->type, 1)) != nil)) {
		ret.data = i.data;
		ret.tab = tab;
		ok = 1;
	} else {
		ret.data = 0;
		ret.tab = 0;
		ok = 0;
	}
}

void
runtime·ifaceE2I(InterfaceType *inter, Eface e, Iface *ret)
{
	Type *t;
	Eface err;

	t = e.type;
	if(t == nil) {
		// explicit conversions require non-nil interface value.
		runtime·newTypeAssertionError(
			nil, nil, inter->string,
			nil, &err);
		runtime·panic(err);
	}
	ret->data = e.data;
	ret->tab = itab(inter, t, 0);
}

bool
runtime·ifaceE2I2(InterfaceType *inter, Eface e, Iface *ret)
{
	ret->tab = itab(inter, e.type, 1);
	if(ret->tab == nil)
		return false;
	ret->data = e.data;
	return true;
}

func reflect·ifaceE2I(inter *InterfaceType, e Eface, dst *Iface) {
	runtime·ifaceE2I(inter, e, dst);
}

func assertE2I(inter *InterfaceType, e Eface) (ret Iface) {
	runtime·ifaceE2I(inter, e, &ret);
}

func assertE2I2(inter *InterfaceType, e Eface) (ret Iface, ok bool) {
	if(e.type == nil) {
		ok = 0;
		ret.data = nil;
		ret.tab = nil;
	} else if((ret.tab = itab(inter, e.type, 1)) == nil) {
		ok = 0;
		ret.data = nil;
	} else {
		ok = 1;
		ret.data = e.data;
	}
}

func assertE2E(inter *InterfaceType, e Eface) (ret Eface) {
	Type *t;
	Eface err;

	t = e.type;
	if(t == nil) {
		// explicit conversions require non-nil interface value.
		runtime·newTypeAssertionError(
			nil, nil, inter->string,
			nil, &err);
		runtime·panic(err);
	}
	ret = e;
}

func assertE2E2(inter *InterfaceType, e Eface) (ret Eface, ok bool) {
	USED(inter);
	ret = e;
	ok = e.type != nil;
}

static uintptr
ifacehash1(void *data, Type *t, uintptr h)
{
	Alg *alg;
	uintptr size;
	Eface err;

	if(t == nil)
		return 0;

	alg = t->alg;
	size = t->size;
	if(alg->hash == runtime·nohash) {
		// calling nohash will panic too,
		// but we can print a better error.
		runtime·newErrorString(runtime·catstring(runtime·gostringnocopy((byte*)"hash of unhashable type "), *t->string), &err);
		runtime·panic(err);
	}
	if(size <= sizeof(data))
		alg->hash(&h, size, &data);
	else
		alg->hash(&h, size, data);
	return h;
}

uintptr
runtime·ifacehash(Iface a, uintptr h)
{
	if(a.tab == nil)
		return h;
	return ifacehash1(a.data, a.tab->type, h);
}

uintptr
runtime·efacehash(Eface a, uintptr h)
{
	return ifacehash1(a.data, a.type, h);
}

static bool
ifaceeq1(void *data1, void *data2, Type *t)
{
	uintptr size;
	Alg *alg;
	Eface err;
	bool eq;

	alg = t->alg;
	size = t->size;

	if(alg->equal == runtime·noequal) {
		// calling noequal will panic too,
		// but we can print a better error.
		runtime·newErrorString(runtime·catstring(runtime·gostringnocopy((byte*)"comparing uncomparable type "), *t->string), &err);
		runtime·panic(err);
	}

	eq = 0;
	if(size <= sizeof(data1))
		alg->equal(&eq, size, &data1, &data2);
	else
		alg->equal(&eq, size, data1, data2);
	return eq;
}

bool
runtime·ifaceeq_c(Iface i1, Iface i2)
{
	if(i1.tab != i2.tab)
		return false;
	if(i1.tab == nil)
		return true;
	return ifaceeq1(i1.data, i2.data, i1.tab->type);
}

bool
runtime·efaceeq_c(Eface e1, Eface e2)
{
	if(e1.type != e2.type)
		return false;
	if(e1.type == nil)
		return true;
	return ifaceeq1(e1.data, e2.data, e1.type);
}

func ifaceeq(i1 Iface, i2 Iface) (ret bool) {
	ret = runtime·ifaceeq_c(i1, i2);
}

func efaceeq(e1 Eface, e2 Eface) (ret bool) {
	ret = runtime·efaceeq_c(e1, e2);
}

func ifacethash(i1 Iface) (ret uint32) {
	Itab *tab;

	ret = 0;
	tab = i1.tab;
	if(tab != nil)
		ret = tab->type->hash;
}

func efacethash(e1 Eface) (ret uint32) {
	Type *t;

	ret = 0;
	t = e1.type;
	if(t != nil)
		ret = t->hash;
}

func reflect·unsafe_Typeof(e Eface) (ret Eface) {
	if(e.type == nil) {
		ret.type = nil;
		ret.data = nil;
	} else {
		ret = *(Eface*)(e.type);
	}
}

func reflect·unsafe_New(t *Type) (ret *byte) {
	ret = runtime·cnew(t);
}

func reflect·unsafe_NewArray(t *Type, n int) (ret *byte) {
	ret = runtime·cnewarray(t, n);
}

func reflect·typelinks() (ret Slice) {
	extern Type *typelink[], *etypelink[];
	static int32 first = 1;
	ret.array = (byte*)typelink;
	ret.len = etypelink - typelink;
	ret.cap = ret.len;
}
