// 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;
	Eface err;

	if(inter->mhdr.len == 0)
		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)
			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
					·newTypeAssertionError(nil, type, inter,
						nil, type->string, inter->string,
						iname, &err);
					if(locked)
						unlock(&ifacelock);
					·panic(err);
					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 = mal(wid);
		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;
	Eface err;

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

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

	if(e.type == nil) {
		·newTypeAssertionError(nil, nil, t,
			nil, nil, t->string,
			nil, &err);
		·panic(err);
	}
	if(e.type != t) {
		·newTypeAssertionError(nil, e.type, t,
			nil, e.type->string, t->string,
			nil, &err);
		·panic(err);
	}
	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;
	Eface err;

	tab = i.tab;
	if(tab == nil) {
		// explicit conversions require non-nil interface value.
		·newTypeAssertionError(nil, nil, inter,
			nil, nil, inter->string,
			nil, &err);
		·panic(err);
	} 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;
	Eface err;

	t = e.type;
	if(t == nil) {
		// explicit conversions require non-nil interface value.
		·newTypeAssertionError(nil, nil, inter,
			nil, nil, inter->string,
			nil, &err);
		·panic(err);
	} 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;
	Eface err;

	if(t == nil)
		return 0;

	alg = t->alg;
	wid = t->size;
	if(algarray[alg].hash == nohash) {
		// calling nohash will panic too,
		// but we can print a better error.
		·newErrorString(catstring(gostringnocopy((byte*)"hash of unhashable type "), *t->string), &err);
		·panic(err);
	}
	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;
	Eface err;

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

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

	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);
	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);
	else
		ret = mal(size);
	FLUSH(&ret);
}
