// 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 "go.h"

/*
 * runtime interface and reflection data structures
 */

static	NodeList*	signatlist;
static	Sym*	dtypesym(Type*);

static int
sigcmp(Sig *a, Sig *b)
{
	return strcmp(a->name, b->name);
}

static Sig*
lsort(Sig *l, int(*f)(Sig*, Sig*))
{
	Sig *l1, *l2, *le;

	if(l == 0 || l->link == 0)
		return l;

	l1 = l;
	l2 = l;
	for(;;) {
		l2 = l2->link;
		if(l2 == 0)
			break;
		l2 = l2->link;
		if(l2 == 0)
			break;
		l1 = l1->link;
	}

	l2 = l1->link;
	l1->link = 0;
	l1 = lsort(l, f);
	l2 = lsort(l2, f);

	/* set up lead element */
	if((*f)(l1, l2) < 0) {
		l = l1;
		l1 = l1->link;
	} else {
		l = l2;
		l2 = l2->link;
	}
	le = l;

	for(;;) {
		if(l1 == 0) {
			while(l2) {
				le->link = l2;
				le = l2;
				l2 = l2->link;
			}
			le->link = 0;
			break;
		}
		if(l2 == 0) {
			while(l1) {
				le->link = l1;
				le = l1;
				l1 = l1->link;
			}
			break;
		}
		if((*f)(l1, l2) < 0) {
			le->link = l1;
			le = l1;
			l1 = l1->link;
		} else {
			le->link = l2;
			le = l2;
			l2 = l2->link;
		}
	}
	le->link = 0;
	return l;
}

/*
 * f is method type, with receiver.
 * return function type, receiver as first argument.
 */
static Type*
methodfunc(Type *f)
{
	NodeList *in, *out;
	Node *d;
	Type *t;

	in = nil;
	if(!isifacemethod(f)) {
		d = nod(ODCLFIELD, N, N);
		d->type = getthisx(f->type)->type->type;
		in = list(in, d);
	}
	for(t=getinargx(f->type)->type; t; t=t->down) {
		d = nod(ODCLFIELD, N, N);
		d->type = t->type;
		in = list(in, d);
	}

	out = nil;
	for(t=getoutargx(f->type)->type; t; t=t->down) {
		d = nod(ODCLFIELD, N, N);
		d->type = t->type;
		out = list(out, d);
	}

	return functype(N, in, out);
}

/*
 * return methods of non-interface type t,
 * sorted by hash.
 * generates stub functions as needed.
 */
static Sig*
methods(Type *t)
{
	int o;
	Type *f, *mt, *it, *this;
	Sig *a, *b;
	Sym *method;
	Prog *oldlist;

	// named method type
	mt = methtype(t);
	if(mt == T)
		return nil;
	expandmeth(mt->sym, mt);

	// type stored in interface word
	it = t;
	if(it->width > widthptr)
		it = ptrto(t);

	// make list of methods for t,
	// generating code if necessary.
	a = nil;
	o = 0;
	oldlist = nil;
	for(f=mt->xmethod; f; f=f->down) {
		if(f->type->etype != TFUNC)
			continue;
		if(f->etype != TFIELD)
			fatal("methods: not field");
		method = f->sym;
		if(method == nil)
			continue;

		// get receiver type for this particular method.
		// if pointer receiver but non-pointer t and
		// this is not an embedded pointer inside a struct,
		// method does not apply.
		this = getthisx(f->type)->type->type;
		if(isptr[this->etype] && this->type == t)
			continue;
		if(isptr[this->etype] && !isptr[t->etype]
		&& f->embedded != 2 && !isifacemethod(f))
			continue;

		b = mal(sizeof(*b));
		b->link = a;
		a = b;

		a->name = method->name;
		a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type);
		if(!exportname(a->name)) {
			a->package = method->package;
			a->hash += PRIME10*stringhash(a->package);
		}
		a->perm = o++;
		a->isym = methodsym(method, it);
		a->tsym = methodsym(method, t);
		a->type = methodfunc(f);

		if(!(a->isym->flags & SymSiggen)) {
			a->isym->flags |= SymSiggen;
			if(!eqtype(this, it)) {
				if(oldlist == nil)
					oldlist = pc;
				// Is okay to call genwrapper here always,
				// but we can generate more efficient code
				// using genembedtramp if all that is necessary
				// is a pointer adjustment and a JMP.
				if(isptr[it->etype] && isptr[this->etype]
				&& f->embedded && !isifacemethod(f))
					genembedtramp(it, f, a->isym);
				else
					genwrapper(it, f, a->isym);
			}
		}

		if(!(a->tsym->flags & SymSiggen)) {
			a->tsym->flags |= SymSiggen;
			if(!eqtype(this, t)) {
				if(oldlist == nil)
					oldlist = pc;
				if(isptr[t->etype] && isptr[this->etype]
				&& f->embedded && !isifacemethod(f))
					genembedtramp(t, f, a->tsym);
				else
					genwrapper(t, f, a->tsym);
			}
		}
	}

	// restore data output
	if(oldlist) {
		// old list ended with AEND; change to ANOP
		// so that the trampolines that follow can be found.
		nopout(oldlist);

		// start new data list
		newplist();
	}

	return lsort(a, sigcmp);
}

/*
 * return methods of interface type t, sorted by hash.
 */
Sig*
imethods(Type *t)
{
	Sig *a, *b;
	int o;
	Type *f;

	a = nil;
	o = 0;
	for(f=t->type; f; f=f->down) {
		if(f->etype != TFIELD)
			fatal("imethods: not field");
		if(f->type->etype != TFUNC || f->sym == nil)
			continue;
		b = mal(sizeof(*b));
		b->link = a;
		a = b;

		a->name = f->sym->name;
		a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type);
		if(!exportname(a->name)) {
			a->package = f->sym->package;
			a->hash += PRIME10*stringhash(a->package);
		}
		a->perm = o++;
		a->offset = 0;
		a->type = methodfunc(f);
	}

	return lsort(a, sigcmp);
}

/*
 * uncommonType
 * ../../pkg/runtime/type.go:/uncommonType
 */
static Sym*
dextratype(Type *t)
{
	int ot, n;
	char *p;
	Sym *s;
	Sig *a, *m;

	m = methods(t);
	if(t->sym == nil && m == nil)
		return nil;

	n = 0;
	for(a=m; a; a=a->link) {
		dtypesym(a->type);
		n++;
	}

	p = smprint("%#-T", t);
	s = pkglookup(p, "extratype");
	ot = 0;
	if(t->sym) {
		ot = dgostringptr(s, ot, t->sym->name);
		if(t != types[t->etype])
			ot = dgostringptr(s, ot, t->sym->package);
		else
			ot = dgostringptr(s, ot, nil);
	} else {
		ot = dgostringptr(s, ot, nil);
		ot = dgostringptr(s, ot, nil);
	}

	// slice header
	ot = dsymptr(s, ot, s, ot + widthptr + 2*4);
	ot = duint32(s, ot, n);
	ot = duint32(s, ot, n);

	// methods
	for(a=m; a; a=a->link) {
		// method
		// ../../pkg/runtime/type.go:/method
		ot = duint32(s, ot, a->hash);
		ot = rnd(ot, widthptr);
		ot = dgostringptr(s, ot, a->name);
		ot = dgostringptr(s, ot, a->package);
		ot = dsymptr(s, ot, dtypesym(a->type), 0);
		if(a->isym)
			ot = dsymptr(s, ot, a->isym, 0);
		else
			ot = duintptr(s, ot, 0);
		if(a->tsym)
			ot = dsymptr(s, ot, a->tsym, 0);
		else
			ot = duintptr(s, ot, 0);
	}
	ggloblsym(s, ot, 0);

	return s;
}

static char*
structnames[] =
{
	[TINT]		= "*runtime.IntType",
	[TUINT]		= "*runtime.UintType",
	[TINT8]		= "*runtime.Int8Type",
	[TUINT8]	= "*runtime.Uint8Type",
	[TINT16]	= "*runtime.Int16Type",
	[TUINT16]	= "*runtime.Uint16Type",
	[TINT32]	= "*runtime.Int32Type",
	[TUINT32]	= "*runtime.Uint32Type",
	[TINT64]	= "*runtime.Int64Type",
	[TUINT64]	= "*runtime.Uint64Type",
	[TUINTPTR]	= "*runtime.UintptrType",
	[TFLOAT]	= "*runtime.FloatType",
	[TFLOAT32]	= "*runtime.Float32Type",
	[TFLOAT64]	= "*runtime.Float64Type",
	[TBOOL]		= "*runtime.BoolType",
	[TSTRING]		= "*runtime.StringType",
	[TDDD]		= "*runtime.DotDotDotType",

	[TPTR32]		= "*runtime.PtrType",
	[TPTR64]		= "*runtime.PtrType",
	[TSTRUCT]	= "*runtime.StructType",
	[TINTER]		= "*runtime.InterfaceType",
	[TCHAN]		= "*runtime.ChanType",
	[TMAP]		= "*runtime.MapType",
	[TARRAY]		= "*runtime.ArrayType",
	[TFUNC]		= "*runtime.FuncType",
};

static Sym*
typestruct(Type *t)
{
	char *name;
	int et;

	et = t->etype;
	if(et < 0 || et >= nelem(structnames) || (name = structnames[et]) == nil) {
		fatal("typestruct %lT", t);
		return nil;	// silence gcc
	}

	if(isslice(t))
		name = "*runtime.SliceType";

	if(isptr[et] && t->type->etype == TANY)
		name = "*runtime.UnsafePointerType";

	return pkglookup(name, "type");
}

/*
 * commonType
 * ../../pkg/runtime/type.go:/commonType
 */
static int
dcommontype(Sym *s, int ot, Type *t)
{
	int i;
	Sym *s1;
	Type *elem;
	char *p;

	dowidth(t);
	s1 = dextratype(t);

	// empty interface pointing at this type.
	// all the references that we emit are *interface{};
	// they point here.
	ot = rnd(ot, widthptr);
	ot = dsymptr(s, ot, typestruct(t), 0);
	ot = dsymptr(s, ot, s, 2*widthptr);

	// ../../pkg/runtime/type.go:/commonType
	// actual type structure
	//	type commonType struct {
	//		size uintptr;
	//		hash uint32;
	//		alg uint8;
	//		align uint8;
	//		fieldAlign uint8;
	//		string *string;
	//		*nameInfo;
	//	}
	ot = duintptr(s, ot, t->width);
	ot = duint32(s, ot, typehash(t));
	ot = duint8(s, ot, algtype(t));
	elem = t;
	while(elem->etype == TARRAY && elem->bound >= 0)
		elem = elem->type;
	i = elem->width;
	if(i > maxround)
		i = maxround;
	ot = duint8(s, ot, i);	// align
	ot = duint8(s, ot, i);	// fieldAlign
	p = smprint("%#-T", t);
	ot = dgostringptr(s, ot, p);	// string
	free(p);
	if(s1)
		ot = dsymptr(s, ot, s1, 0);	// extraType
	else
		ot = duintptr(s, ot, 0);

	return ot;
}

Sym*
typesym(Type *t)
{
	char *p;
	Sym *s;

	p = smprint("%#-T", t);
	s = pkglookup(p, "type");
	free(p);
	return s;
}

Node*
typename(Type *t)
{
	Sym *s;
	Node *n;

	if(isptr[t->etype] && t->type == T)
		fatal("typename %T", t);
	s = typesym(t);
	if(s->def == N) {
		n = nod(ONAME, N, N);
		n->sym = s;
		n->type = types[TUINT8];
		n->addable = 1;
		n->ullman = 1;
		n->class = PEXTERN;
		n->xoffset = 0;
		s->def = n;

		signatlist = list(signatlist, typenod(t));
	}

	n = nod(OADDR, s->def, N);
	n->type = ptrto(s->def->type);
	n->addable = 1;
	n->ullman = 2;
	return n;
}

Sym*
dtypesym(Type *t)
{
	int ot, n;
	Sym *s, *s1, *s2;
	Sig *a, *m;
	Type *t1;
	Sym *tsym;

	if(t->etype == TNIL || t->etype == TIDEAL || t == idealstring)
		fatal("dtypesym ideal %T", t);

	s = typesym(t);
	if(s->flags & SymSiggen)
		return s;
	s->flags |= SymSiggen;

	// special case (look for runtime below):
	// when compiling package runtime,
	// emit the type structures for int, float, etc.
	t1 = T;
	if(isptr[t->etype])
		t1 = t->type;
	tsym = S;
	if(t1)
		tsym = t1->sym;
	else
		tsym = t->sym;

	if(strcmp(package, "runtime") == 0) {
		if(t == types[t->etype])
			goto ok;
		if(t1 && t1 == types[t1->etype])
			goto ok;
		if(t1 && t1->etype == tptr && t1->type->etype == TANY)
			goto ok;
	}

	// named types from other files are defined in those files
	if(t->sym && !t->local)
		return s;
	if(!t->sym && t1 && t1->sym && !t1->local)
		return s;
	if(isforw[t->etype] || (t1 && isforw[t1->etype]))
		return s;

ok:
	ot = 0;
	switch(t->etype) {
	default:
		ot = dcommontype(s, ot, t);
		break;

	case TARRAY:
		// ../../pkg/runtime/type.go:/ArrayType
		s1 = dtypesym(t->type);
		ot = dcommontype(s, ot, t);
		ot = dsymptr(s, ot, s1, 0);
		if(t->bound < 0)
			ot = duintptr(s, ot, -1);
		else
			ot = duintptr(s, ot, t->bound);
		break;

	case TCHAN:
		// ../../pkg/runtime/type.go:/ChanType
		s1 = dtypesym(t->type);
		ot = dcommontype(s, ot, t);
		ot = dsymptr(s, ot, s1, 0);
		ot = duintptr(s, ot, t->chan);
		break;

	case TFUNC:
		for(t1=getthisx(t)->type; t1; t1=t1->down)
			dtypesym(t1->type);
		for(t1=getinargx(t)->type; t1; t1=t1->down)
			dtypesym(t1->type);
		for(t1=getoutargx(t)->type; t1; t1=t1->down)
			dtypesym(t1->type);

		ot = dcommontype(s, ot, t);

		// two slice headers: in and out.
		ot = dsymptr(s, ot, s, ot+2*(widthptr+2*4));
		n = t->thistuple + t->intuple;
		ot = duint32(s, ot, n);
		ot = duint32(s, ot, n);
		ot = dsymptr(s, ot, s, ot+1*(widthptr+2*4)+n*widthptr);
		ot = duint32(s, ot, t->outtuple);
		ot = duint32(s, ot, t->outtuple);

		// slice data
		for(t1=getthisx(t)->type; t1; t1=t1->down, n++)
			ot = dsymptr(s, ot, dtypesym(t1->type), 0);
		for(t1=getinargx(t)->type; t1; t1=t1->down, n++)
			ot = dsymptr(s, ot, dtypesym(t1->type), 0);
		for(t1=getoutargx(t)->type; t1; t1=t1->down, n++)
			ot = dsymptr(s, ot, dtypesym(t1->type), 0);
		break;

	case TINTER:
		m = imethods(t);
		n = 0;
		for(a=m; a; a=a->link) {
			dtypesym(a->type);
			n++;
		}

		// ../../pkg/runtime/type.go:/InterfaceType
		ot = dcommontype(s, ot, t);
		ot = dsymptr(s, ot, s, ot+widthptr+2*4);
		ot = duint32(s, ot, n);
		ot = duint32(s, ot, n);
		for(a=m; a; a=a->link) {
			// ../../pkg/runtime/type.go:/imethod
			ot = duint32(s, ot, a->hash);
			ot = duint32(s, ot, a->perm);
			ot = dgostringptr(s, ot, a->name);
			ot = dgostringptr(s, ot, a->package);
			ot = dsymptr(s, ot, dtypesym(a->type), 0);
		}
		break;

	case TMAP:
		// ../../pkg/runtime/type.go:/MapType
		s1 = dtypesym(t->down);
		s2 = dtypesym(t->type);
		ot = dcommontype(s, ot, t);
		ot = dsymptr(s, ot, s1, 0);
		ot = dsymptr(s, ot, s2, 0);
		break;

	case TPTR32:
	case TPTR64:
		if(t->type->etype == TANY) {
			ot = dcommontype(s, ot, t);
			break;
		}
		// ../../pkg/runtime/type.go:/PtrType
		s1 = dtypesym(t->type);
		ot = dcommontype(s, ot, t);
		ot = dsymptr(s, ot, s1, 0);
		break;

	case TSTRUCT:
		// ../../pkg/runtime/type.go:/StructType
		// for security, only the exported fields.
		n = 0;
		for(t1=t->type; t1!=T; t1=t1->down) {
			dtypesym(t1->type);
			n++;
		}
		ot = dcommontype(s, ot, t);
		ot = dsymptr(s, ot, s, ot+widthptr+2*4);
		ot = duint32(s, ot, n);
		ot = duint32(s, ot, n);
		for(t1=t->type; t1!=T; t1=t1->down) {
			// ../../pkg/runtime/type.go:/structField
			if(t1->sym && !t1->embedded) {
				ot = dgostringptr(s, ot, t1->sym->name);
				if(exportname(t1->sym->name))
					ot = dgostringptr(s, ot, nil);
				else
					ot = dgostringptr(s, ot, t1->sym->package);
			} else {
				ot = dgostringptr(s, ot, nil);
				ot = dgostringptr(s, ot, nil);
			}
			ot = dsymptr(s, ot, dtypesym(t1->type), 0);
			ot = dgostrlitptr(s, ot, t1->note);
			ot = duintptr(s, ot, t1->width);	// field offset
		}
		break;
	}

	ggloblsym(s, ot, tsym == nil);
	return s;
}

void
dumptypestructs(void)
{
	int i;
	NodeList *l;
	Node *n;
	Type *t;

	// copy types from externdcl list to signatlist
	for(l=externdcl; l; l=l->next) {
		n = l->n;
		if(n->op != OTYPE)
			continue;
		signatlist = list(signatlist, n);
	}

	// process signatlist
	for(l=signatlist; l; l=l->next) {
		n = l->n;
		if(n->op != OTYPE)
			continue;
		t = n->type;
		dtypesym(t);
		if(t->sym && !isptr[t->etype])
			dtypesym(ptrto(t));
	}

	// do basic types if compiling package runtime.
	// they have to be in at least one package,
	// and reflect is always loaded implicitly,
	// so this is as good as any.
	// another possible choice would be package main,
	// but using runtime means fewer copies in .6 files.
	if(strcmp(package, "runtime") == 0) {
		for(i=1; i<=TBOOL; i++)
			if(i != TFLOAT80)
				dtypesym(ptrto(types[i]));
		dtypesym(ptrto(types[TSTRING]));
		dtypesym(typ(TDDD));
		dtypesym(ptrto(pkglookup("Pointer", "unsafe")->def->type));
	}
}
