// 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 "type.h"
#include "malloc.h"

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

static void
printeface(Eface e)
{
	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;
	Itab *m;
	UncommonType *x;
	Type *itype;

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

	// 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)
			lock(&ifacelock);
		for(m=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)
					unlock(&ifacelock);
				return m;
			}
		}
	}

	ni = inter->mhdr.len;
	m = 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;
		for(;; t++) {
			if(t >= et) {
				if(!canfail) {
				throw:
					// didn't find method
					printf("%S is not %S: missing method %S\n",
						*type->string, *inter->string, *iname);
					throw("interface conversion");
					return nil;	// not reached
				}
				m->bad = 1;
				goto out;
			}
			if(t->mtyp == itype && t->name == iname)
				break;
		}
		if(m)
			m->fun[i - inter->m] = t->ifn;
	}

out:
	m->link = hash[h];
	hash[h] = m;
	if(locked)
		unlock(&ifacelock);
	if(m->bad)
		return nil;
	return m;
}

static void
copyin(Type *t, void *src, void **dst)
{
	int32 wid, alg;
	void *p;

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

	if(wid <= sizeof(*dst))
		algarray[alg].copy(wid, dst, src);
	else {
		p = malx(wid, 1);
		algarray[alg].copy(wid, p, src);
		*dst = p;
	}
}

static void
copyout(Type *t, void **src, void *dst)
{
	int32 wid, alg;

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

	if(wid <= sizeof(*src))
		algarray[alg].copy(wid, dst, src);
	else
		algarray[alg].copy(wid, dst, *src);
}

// ifaceT2I(sigi *byte, sigt *byte, elem any) (ret Iface);
#pragma textflag 7
void
·ifaceT2I(InterfaceType *inter, Type *t, ...)
{
	byte *elem;
	Iface *ret;
	int32 wid;

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

// ifaceT2E(sigt *byte, elem any) (ret Eface);
#pragma textflag 7
void
·ifaceT2E(Type *t, ...)
{
	byte *elem;
	Eface *ret;
	int32 wid;

	elem = (byte*)(&t+1);
	wid = t->size;
	ret = (Eface*)(elem + rnd(wid, Structrnd));

	ret->type = t;
	copyin(t, elem, &ret->data);
}

// ifaceI2T(sigt *byte, iface any) (ret any);
#pragma textflag 7
void
·ifaceI2T(Type *t, Iface i, ...)
{
	Itab *tab;
	byte *ret;

	ret = (byte*)(&i+1);
	tab = i.tab;
	if(tab == nil) {
		printf("interface is nil, not %S\n", *t->string);
		throw("interface conversion");
	}
	if(tab->type != t) {
		printf("%S is %S, not %S\n", *tab->inter->string, *tab->type->string, *t->string);
		throw("interface conversion");
	}
	copyout(t, &i.data, ret);
}

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

	ret = (byte*)(&i+1);
	wid = t->size;
	ok = (bool*)(ret+rnd(wid, 1));

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

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

// ifaceE2T(sigt *byte, e Eface) (ret any);
#pragma textflag 7
void
·ifaceE2T(Type *t, Eface e, ...)
{
	byte *ret;

	ret = (byte*)(&e+1);

	if(e.type != t) {
		if(e.type == nil)
			printf("interface is nil, not %S\n", *t->string);
		else
			printf("interface is %S, not %S\n", *e.type->string, *t->string);
		throw("interface conversion");
	}
	copyout(t, &e.data, ret);
}

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

	ret = (byte*)(&e+1);
	wid = t->size;
	ok = (bool*)(ret+rnd(wid, 1));

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

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

// ifaceI2E(sigi *byte, iface any) (ret any);
// TODO(rsc): Move to back end, throw away function.
void
·ifaceI2E(Iface i, Eface ret)
{
	Itab *tab;

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

// ifaceI2I(sigi *byte, iface any) (ret any);
// called only for implicit (no type assertion) conversions.
// converting nil is okay.
void
·ifaceI2I(InterfaceType *inter, Iface i, Iface ret)
{
	Itab *tab;

	tab = i.tab;
	if(tab == nil) {
		// If incoming interface is uninitialized (zeroed)
		// make the outgoing interface zeroed as well.
		ret.tab = nil;
		ret.data = nil;
	} else {
		ret = i;
		if(tab->inter != inter)
			ret.tab = itab(inter, tab->type, 0);
	}

	FLUSH(&ret);
}

// ifaceI2Ix(sigi *byte, iface any) (ret any);
// called only for explicit conversions (with type assertion).
// converting nil is not okay.
void
·ifaceI2Ix(InterfaceType *inter, Iface i, Iface ret)
{
	Itab *tab;

	tab = i.tab;
	if(tab == nil) {
		// explicit conversions require non-nil interface value.
		printf("interface is nil, not %S\n", *inter->string);
		throw("interface conversion");
	} else {
		ret = i;
		if(tab->inter != inter)
			ret.tab = itab(inter, tab->type, 0);
	}

	FLUSH(&ret);
}

// ifaceI2I2(sigi *byte, iface any) (ret any, ok bool);
void
·ifaceI2I2(InterfaceType *inter, Iface i, Iface ret, bool ok)
{
	Itab *tab;

	tab = i.tab;
	if(tab == nil) {
		// If incoming interface is nil, the conversion fails.
		ret.tab = nil;
		ret.data = nil;
		ok = false;
	} else {
		ret = i;
		ok = true;
		if(tab->inter != inter) {
			ret.tab = itab(inter, tab->type, 1);
			if(ret.tab == nil) {
				ret.data = nil;
				ok = false;
			}
		}
	}

	FLUSH(&ret);
	FLUSH(&ok);
}

// ifaceE2I(sigi *byte, iface any) (ret any);
// Called only for explicit conversions (with type assertion).
void
ifaceE2I(InterfaceType *inter, Eface e, Iface *ret)
{
	Type *t;

	t = e.type;
	if(t == nil) {
		// explicit conversions require non-nil interface value.
		printf("interface is nil, not %S\n", *inter->string);
		throw("interface conversion");
	} else {
		ret->data = e.data;
		ret->tab = itab(inter, t, 0);
	}
}

// ifaceE2I(sigi *byte, iface any) (ret any);
// Called only for explicit conversions (with type assertion).
void
·ifaceE2I(InterfaceType *inter, Eface e, Iface ret)
{
	ifaceE2I(inter, e, &ret);
}

// ifaceE2I2(sigi *byte, iface any) (ret any, ok bool);
void
·ifaceE2I2(InterfaceType *inter, Eface e, Iface ret, bool ok)
{
	Type *t;

	t = e.type;
	ok = true;
	if(t == nil) {
		// If incoming interface is nil, the conversion fails.
		ret.data = nil;
		ret.tab = nil;
		ok = false;
	} else {
		ret.data = e.data;
		ret.tab = itab(inter, t, 1);
		if(ret.tab == nil) {
			ret.data = nil;
			ok = false;
		}
	}
	FLUSH(&ret);
	FLUSH(&ok);
}

static uintptr
ifacehash1(void *data, Type *t)
{
	int32 alg, wid;

	if(t == nil)
		return 0;

	alg = t->alg;
	wid = t->size;
	if(algarray[alg].hash == nohash) {
		// calling nohash will throw too,
		// but we can print a better error.
		printf("hash of unhashable type %S\n", *t->string);
		if(alg == AFAKE)
			throw("fake interface hash");
		throw("interface hash");
	}
	if(wid <= sizeof(data))
		return algarray[alg].hash(wid, &data);
	return algarray[alg].hash(wid, data);
}

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

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

static bool
ifaceeq1(void *data1, void *data2, Type *t)
{
	int32 alg, wid;

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

	if(algarray[alg].equal == noequal) {
		// calling noequal will throw too,
		// but we can print a better error.
		printf("comparing uncomparable type %S\n", *t->string);
		if(alg == AFAKE)
			throw("fake interface compare");
		throw("interface compare");
	}

	if(wid <= sizeof(data1))
		return algarray[alg].equal(wid, &data1, &data2);
	return algarray[alg].equal(wid, data1, data2);
}

bool
ifaceeq(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
efaceeq(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);
}

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

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

// ifacethash(i1 any) (ret uint32);
void
·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
·efacethash(Eface e1, uint32 ret)
{
	Type *t;

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

void
·printiface(Iface i)
{
	printiface(i);
}

void
·printeface(Eface e)
{
	printeface(e);
}

void
unsafe·Typeof(Eface e, Eface ret)
{
	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(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;
			algarray[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 = mal(sizeof(uintptr));
			*p = x;
		} else {
			// Already a pointer, but still make a copy,
			// to preserve value semantics for interface data.
			p = mal(e.type->size);
			algarray[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)
{
	// 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))
		algarray[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;

	// 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 = mallocgc(t->size, RefNoPointers, 1, 1, 1);
	else
		ret = mal(t->size);
	FLUSH(&ret);
}

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

	// 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 = mallocgc(size, RefNoPointers, 1, 1, 1);
	else
		ret = mal(size);
	FLUSH(&ret);
}
