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

#include "runtime.h"
#include "arch_GOARCH.h"
#include "type.h"
#include "malloc.h"

enum 
{
	// If an empty interface has these bits set in its type
	// pointer, it was copied from a reflect.Value and is
	// not a valid empty interface.
	reflectFlags = 3,
};

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

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

/*
 * layout of Itab known to compilers
 */
struct Itab
{
	InterfaceType*	inter;
	Type*	type;
	Itab*	link;
	int32	bad;
	int32	unused;
	void	(*fun[])(void);
};

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·malloc(sizeof(*m) + ni*sizeof m->fun[0]);
	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, inter,
						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;
}

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);
}

// func convT2I(typ *byte, typ2 *byte, elem any) (ret any)
#pragma textflag 7
void
runtime·convT2I(Type *t, InterfaceType *inter, ...)
{
	byte *elem;
	Iface *ret;
	int32 wid;

	elem = (byte*)(&inter+1);
	wid = t->size;
	ret = (Iface*)(elem + runtime·rnd(wid, Structrnd));
	ret->tab = itab(inter, t, 0);
	copyin(t, elem, &ret->data);
}

// func convT2E(typ *byte, elem any) (ret any)
#pragma textflag 7
void
runtime·convT2E(Type *t, ...)
{
	byte *elem;
	Eface *ret;
	int32 wid;

	elem = (byte*)(&t+1);
	wid = t->size;
	ret = (Eface*)(elem + runtime·rnd(wid, Structrnd));
	ret->type = t;
	copyin(t, elem, &ret->data);
}

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

// func ifaceI2T(typ *byte, iface any) (ret any)
#pragma textflag 7
void
runtime·assertI2T(Type *t, Iface i, ...)
{
	byte *ret;

	ret = (byte*)(&i+1);
	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,
			nil, nil, t->string,
			nil, &err);
		runtime·panic(err);
	}
	if(tab->type != t) {
		runtime·newTypeAssertionError(tab->inter, tab->type, t,
			tab->inter->string, tab->type->string, t->string,
			nil, &err);
		runtime·panic(err);
	}
	copyout(t, &i.data, ret);
}

// func ifaceI2T2(typ *byte, iface any) (ret any, ok bool)
#pragma textflag 7
void
runtime·assertI2T2(Type *t, Iface i, ...)
{
	byte *ret;
	bool *ok;
	int32 wid;

	ret = (byte*)(&i+1);
	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);
}

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

// func ifaceE2T(typ *byte, iface any) (ret any)
#pragma textflag 7
void
runtime·assertE2T(Type *t, Eface e, ...)
{
	byte *ret;

	if(((uintptr)e.type&reflectFlags) != 0)
		runtime·throw("invalid interface value");
	ret = (byte*)(&e+1);
	assertE2Tret(t, e, ret);
}

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

	if(((uintptr)e.type&reflectFlags) != 0)
		runtime·throw("invalid interface value");
	if(e.type == nil) {
		runtime·newTypeAssertionError(nil, nil, t,
			nil, nil, t->string,
			nil, &err);
		runtime·panic(err);
	}
	if(e.type != t) {
		runtime·newTypeAssertionError(nil, e.type, t,
			nil, e.type->string, t->string,
			nil, &err);
		runtime·panic(err);
	}
	copyout(t, &e.data, ret);
}

// func ifaceE2T2(sigt *byte, iface any) (ret any, ok bool);
#pragma textflag 7
void
runtime·assertE2T2(Type *t, Eface e, ...)
{
	byte *ret;
	bool *ok;
	int32 wid;

	if(((uintptr)e.type&reflectFlags) != 0)
		runtime·throw("invalid interface value");
	ret = (byte*)(&e+1);
	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 convI2E(elem any) (ret any)
void
runtime·convI2E(Iface i, Eface ret)
{
	Itab *tab;

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

// func ifaceI2E(typ *byte, iface any) (ret any)
void
runtime·assertI2E(InterfaceType* inter, Iface i, Eface ret)
{
	Itab *tab;
	Eface err;

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

// func ifaceI2E2(typ *byte, iface any) (ret any, ok bool)
void
runtime·assertI2E2(InterfaceType* inter, Iface i, Eface ret, bool ok)
{
	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;
	FLUSH(&ret);
	FLUSH(&ok);
}

// func convI2I(typ *byte, elem any) (ret any)
void
runtime·convI2I(InterfaceType* inter, Iface i, Iface ret)
{
	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);
	FLUSH(&ret);
}

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,
			nil, nil, inter->string,
			nil, &err);
		runtime·panic(err);
	}
	ret->data = i.data;
	ret->tab = itab(inter, tab->type, 0);
}

// func ifaceI2I(sigi *byte, iface any) (ret any)
void
runtime·assertI2I(InterfaceType* inter, Iface i, Iface ret)
{
	runtime·ifaceI2I(inter, i, &ret);
}

// func ifaceI2I2(sigi *byte, iface any) (ret any, ok bool)
void
runtime·assertI2I2(InterfaceType *inter, Iface i, Iface ret, bool ok)
{
	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;
	}
	FLUSH(&ret);
	FLUSH(&ok);
}

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

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

// For reflect
//	func ifaceE2I(t *InterfaceType, e interface{}, dst *Iface)
void
reflect·ifaceE2I(InterfaceType *inter, Eface e, Iface *dst)
{
	runtime·ifaceE2I(inter, e, dst);
}

// func ifaceE2I(sigi *byte, iface any) (ret any)
void
runtime·assertE2I(InterfaceType* inter, Eface e, Iface ret)
{
	runtime·ifaceE2I(inter, e, &ret);
}

// ifaceE2I2(sigi *byte, iface any) (ret any, ok bool)
void
runtime·assertE2I2(InterfaceType *inter, Eface e, Iface ret, bool ok)
{
	if(((uintptr)e.type&reflectFlags) != 0)
		runtime·throw("invalid interface value");
	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;
	}
	FLUSH(&ret);
	FLUSH(&ok);
}

// func ifaceE2E(typ *byte, iface any) (ret any)
void
runtime·assertE2E(InterfaceType* inter, Eface e, Eface ret)
{
	Type *t;
	Eface err;

	if(((uintptr)e.type&reflectFlags) != 0)
		runtime·throw("invalid interface value");
	t = e.type;
	if(t == nil) {
		// explicit conversions require non-nil interface value.
		runtime·newTypeAssertionError(nil, nil, inter,
			nil, nil, inter->string,
			nil, &err);
		runtime·panic(err);
	}
	ret = e;
	FLUSH(&ret);
}

// func ifaceE2E2(iface any) (ret any, ok bool)
void
runtime·assertE2E2(InterfaceType* inter, Eface e, Eface ret, bool ok)
{
	if(((uintptr)e.type&reflectFlags) != 0)
		runtime·throw("invalid interface value");
	USED(inter);
	ret = e;
	ok = e.type != nil;
	FLUSH(&ret);
	FLUSH(&ok);
}

static uintptr
ifacehash1(void *data, Type *t)
{
	Alg *alg;
	uintptr size, h;
	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);
	}
	h = 0;
	if(size <= sizeof(data))
		alg->hash(&h, size, &data);
	else
		alg->hash(&h, size, data);
	return h;
}

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

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

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(((uintptr)e1.type&reflectFlags) != 0)
		runtime·throw("invalid interface value");
	if(((uintptr)e2.type&reflectFlags) != 0)
		runtime·throw("invalid interface value");
	if(e1.type != e2.type)
		return false;
	if(e1.type == nil)
		return true;
	return ifaceeq1(e1.data, e2.data, e1.type);
}

// ifaceeq(i1 any, i2 any) (ret bool);
void
runtime·ifaceeq(Iface i1, Iface i2, bool ret)
{
	ret = runtime·ifaceeq_c(i1, i2);
	FLUSH(&ret);
}

// efaceeq(i1 any, i2 any) (ret bool)
void
runtime·efaceeq(Eface e1, Eface e2, bool ret)
{
	ret = runtime·efaceeq_c(e1, e2);
	FLUSH(&ret);
}

// ifacethash(i1 any) (ret uint32);
void
runtime·ifacethash(Iface i1, uint32 ret)
{
	Itab *tab;

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

// efacethash(e1 any) (ret uint32)
void
runtime·efacethash(Eface e1, uint32 ret)
{
	Type *t;

	if(((uintptr)e1.type&reflectFlags) != 0)
		runtime·throw("invalid interface value");
	ret = 0;
	t = e1.type;
	if(t != nil)
		ret = t->hash;
	FLUSH(&ret);
}

void
unsafe·Typeof(Eface e, Eface ret)
{
	if(((uintptr)e.type&reflectFlags) != 0)
		runtime·throw("invalid interface value");
	if(e.type == nil) {
		ret.type = nil;
		ret.data = nil;
	} else {
		ret = *(Eface*)(e.type);
	}
	FLUSH(&ret);
}

void
unsafe·Reflect(Eface e, Eface rettype, void *retaddr)
{
	uintptr *p;
	uintptr x;

	if(((uintptr)e.type&reflectFlags) != 0)
		runtime·throw("invalid interface value");
	if(e.type == nil) {
		rettype.type = nil;
		rettype.data = nil;
		retaddr = 0;
	} else {
		rettype = *(Eface*)e.type;
		if(e.type->size <= sizeof(uintptr)) {
			// Copy data into x ...
			x = 0;
			e.type->alg->copy(e.type->size, &x, &e.data);

			// but then build pointer to x so that Reflect
			// always returns pointer to data.
			p = runtime·mal(sizeof(uintptr));
			*p = x;
		} else {
			// Already a pointer, but still make a copy,
			// to preserve value semantics for interface data.
			p = runtime·mal(e.type->size);
			e.type->alg->copy(e.type->size, p, e.data);
		}
		retaddr = p;
	}
	FLUSH(&rettype);
	FLUSH(&retaddr);
}

void
unsafe·Unreflect(Eface typ, void *addr, Eface e)
{
	if(((uintptr)typ.type&reflectFlags) != 0)
		runtime·throw("invalid interface value");

	// Reflect library has reinterpreted typ
	// as its own kind of type structure.
	// We know that the pointer to the original
	// type structure sits before the data pointer.
	e.type = (Type*)((Eface*)typ.data-1);

	// Interface holds either pointer to data
	// or copy of original data.
	if(e.type->size <= sizeof(uintptr))
		e.type->alg->copy(e.type->size, &e.data, addr);
	else {
		// Easier: already a pointer to data.
		// TODO(rsc): Should this make a copy?
		e.data = addr;
	}

	FLUSH(&e);
}

void
unsafe·New(Eface typ, void *ret)
{
	Type *t;

	if(((uintptr)typ.type&reflectFlags) != 0)
		runtime·throw("invalid interface value");

	// Reflect library has reinterpreted typ
	// as its own kind of type structure.
	// We know that the pointer to the original
	// type structure sits before the data pointer.
	t = (Type*)((Eface*)typ.data-1);

	if(t->kind&KindNoPointers)
		ret = runtime·mallocgc(t->size, FlagNoPointers, 1, 1);
	else
		ret = runtime·mal(t->size);
	FLUSH(&ret);
}

void
unsafe·NewArray(Eface typ, uint32 n, void *ret)
{
	uint64 size;
	Type *t;

	if(((uintptr)typ.type&reflectFlags) != 0)
		runtime·throw("invalid interface value");

	// Reflect library has reinterpreted typ
	// as its own kind of type structure.
	// We know that the pointer to the original
	// type structure sits before the data pointer.
	t = (Type*)((Eface*)typ.data-1);
	
	size = n*t->size;
	if(t->kind&KindNoPointers)
		ret = runtime·mallocgc(size, FlagNoPointers, 1, 1);
	else
		ret = runtime·mal(size);
	FLUSH(&ret);
}
