// 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 <u.h>
#include <libc.h>
#include "go.h"
#include "../ld/textflag.h"
#include "../../runtime/mgc0.h"
#include "../../runtime/typekind.h"

/*
 * runtime interface and reflection data structures
 */

static	NodeList*	signatlist;
static	Sym*	dtypesym(Type*);
static	Sym*	weaktypesym(Type*);
static	Sym*	dalgsym(Type*);
static	int	usegcprog(Type*);
static	void	gengcprog(Type*, Sym**, Sym**);
static	void	gengcmask(Type*, uint8[16]);

static int
sigcmp(Sig *a, Sig *b)
{
	int i;

	i = strcmp(a->name, b->name);
	if(i != 0)
		return i;
	if(a->pkg == b->pkg)
		return 0;
	if(a->pkg == nil)
		return -1;
	if(b->pkg == nil)
		return +1;
	return strcmp(a->pkg->path->s, b->pkg->path->s);
}

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

// Builds a type respresenting a Bucket structure for
// the given map type.  This type is not visible to users -
// we include only enough information to generate a correct GC
// program for it.
// Make sure this stays in sync with ../../runtime/hashmap.c!
enum {
	BUCKETSIZE = 8,
	MAXKEYSIZE = 128,
	MAXVALSIZE = 128,
};

static Type*
mapbucket(Type *t)
{
	Type *keytype, *valtype;
	Type *bucket;
	Type *overflowfield, *keysfield, *valuesfield;
	int32 offset;

	if(t->bucket != T)
		return t->bucket;

	keytype = t->down;
	valtype = t->type;
	dowidth(keytype);
	dowidth(valtype);
	if(keytype->width > MAXKEYSIZE)
		keytype = ptrto(keytype);
	if(valtype->width > MAXVALSIZE)
		valtype = ptrto(valtype);

	bucket = typ(TSTRUCT);
	bucket->noalg = 1;

	// The first field is: uint8 topbits[BUCKETSIZE].
	// We don't need to encode it as GC doesn't care about it.
	offset = BUCKETSIZE * 1;

	overflowfield = typ(TFIELD);
	overflowfield->type = ptrto(bucket);
	overflowfield->width = offset;         // "width" is offset in structure
	overflowfield->sym = mal(sizeof(Sym)); // not important but needs to be set to give this type a name
	overflowfield->sym->name = "overflow";
	offset += widthptr;
	
	// The keys are padded to the native integer alignment.
	// This is usually the same as widthptr; the exception (as usual) is nacl/amd64.
	if(widthreg > widthptr)
		offset += widthreg - widthptr;

	keysfield = typ(TFIELD);
	keysfield->type = typ(TARRAY);
	keysfield->type->type = keytype;
	keysfield->type->bound = BUCKETSIZE;
	keysfield->type->width = BUCKETSIZE * keytype->width;
	keysfield->width = offset;
	keysfield->sym = mal(sizeof(Sym));
	keysfield->sym->name = "keys";
	offset += BUCKETSIZE * keytype->width;

	valuesfield = typ(TFIELD);
	valuesfield->type = typ(TARRAY);
	valuesfield->type->type = valtype;
	valuesfield->type->bound = BUCKETSIZE;
	valuesfield->type->width = BUCKETSIZE * valtype->width;
	valuesfield->width = offset;
	valuesfield->sym = mal(sizeof(Sym));
	valuesfield->sym->name = "values";
	offset += BUCKETSIZE * valtype->width;

	// link up fields
	bucket->type = overflowfield;
	overflowfield->down = keysfield;
	keysfield->down = valuesfield;
	valuesfield->down = T;

	bucket->width = offset;
	bucket->local = t->local;
	t->bucket = bucket;
	bucket->map = t;
	return bucket;
}

// Builds a type respresenting a Hmap structure for
// the given map type.  This type is not visible to users -
// we include only enough information to generate a correct GC
// program for it.
// Make sure this stays in sync with ../../runtime/hashmap.go!
static Type*
hmap(Type *t)
{
	Type *h, *bucket;
	Type *bucketsfield, *oldbucketsfield;
	int32 offset;

	if(t->hmap != T)
		return t->hmap;

	bucket = mapbucket(t);
	h = typ(TSTRUCT);
	h->noalg = 1;

	offset = widthint; // count
	offset += 4;       // flags
	offset += 4;       // hash0
	offset += 1;       // B
	offset = (offset + widthptr - 1) / widthptr * widthptr;
	
	bucketsfield = typ(TFIELD);
	bucketsfield->type = ptrto(bucket);
	bucketsfield->width = offset;
	bucketsfield->sym = mal(sizeof(Sym));
	bucketsfield->sym->name = "buckets";
	offset += widthptr;

	oldbucketsfield = typ(TFIELD);
	oldbucketsfield->type = ptrto(bucket);
	oldbucketsfield->width = offset;
	oldbucketsfield->sym = mal(sizeof(Sym));
	oldbucketsfield->sym->name = "oldbuckets";
	offset += widthptr;

	offset += widthptr; // nevacuate (last field in Hmap)

	// link up fields
	h->type = bucketsfield;
	bucketsfield->down = oldbucketsfield;
	oldbucketsfield->down = T;

	h->width = offset;
	h->local = t->local;
	t->hmap = h;
	h->map = t;
	return h;
}

Type*
hiter(Type *t)
{
	int32 n, off;
	Type *field[7];
	Type *i;

	if(t->hiter != T)
		return t->hiter;

	// build a struct:
	// hash_iter {
	//    key *Key
	//    val *Value
	//    t *MapType
	//    h *Hmap
	//    buckets *Bucket
	//    bptr *Bucket
	//    other [4]uintptr
	// }
	// must match ../../runtime/hashmap.c:hash_iter.
	field[0] = typ(TFIELD);
	field[0]->type = ptrto(t->down);
	field[0]->sym = mal(sizeof(Sym));
	field[0]->sym->name = "key";
	
	field[1] = typ(TFIELD);
	field[1]->type = ptrto(t->type);
	field[1]->sym = mal(sizeof(Sym));
	field[1]->sym->name = "val";
	
	field[2] = typ(TFIELD);
	field[2]->type = ptrto(types[TUINT8]); // TODO: is there a Type type?
	field[2]->sym = mal(sizeof(Sym));
	field[2]->sym->name = "t";
	
	field[3] = typ(TFIELD);
	field[3]->type = ptrto(hmap(t));
	field[3]->sym = mal(sizeof(Sym));
	field[3]->sym->name = "h";
	
	field[4] = typ(TFIELD);
	field[4]->type = ptrto(mapbucket(t));
	field[4]->sym = mal(sizeof(Sym));
	field[4]->sym->name = "buckets";
	
	field[5] = typ(TFIELD);
	field[5]->type = ptrto(mapbucket(t));
	field[5]->sym = mal(sizeof(Sym));
	field[5]->sym->name = "bptr";
	
	// all other non-pointer fields
	field[6] = typ(TFIELD);
	field[6]->type = typ(TARRAY);
	field[6]->type->type = types[TUINTPTR];
	field[6]->type->bound = 4;
	field[6]->type->width = 4 * widthptr;
	field[6]->sym = mal(sizeof(Sym));
	field[6]->sym->name = "other";
	
	// build iterator struct holding the above fields
	i = typ(TSTRUCT);
	i->noalg = 1;
	i->type = field[0];
	off = 0;
	for(n = 0; n < 6; n++) {
		field[n]->down = field[n+1];
		field[n]->width = off;
		off += field[n]->type->width;
	}
	field[6]->down = T;
	off += field[6]->type->width;
	if(off != 10 * widthptr)
		yyerror("hash_iter size not correct %d %d", off, 10 * widthptr);
	t->hiter = i;
	i->map = t;
	return i;
}

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

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

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

	t = functype(N, in, out);
	if(f->nname) {
		// Link to name of original method function.
		t->nname = f->nname;
	}
	return t;
}

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

	// method type
	mt = methtype(t, 0);
	if(mt == T)
		return nil;
	expandmeth(mt);

	// type stored in interface word
	it = t;
	if(!isdirectiface(it))
		it = ptrto(t);

	// make list of methods for t,
	// generating code if necessary.
	a = nil;
	for(f=mt->xmethod; f; f=f->down) {
		if(f->etype != TFIELD)
			fatal("methods: not field %T", f);
		if (f->type->etype != TFUNC || f->type->thistuple == 0)
			fatal("non-method on %T method %S %T\n", mt, f->sym, f);
		if (!getthisx(f->type)->type)
			fatal("receiver with no type on %T method %S %T\n", mt, f->sym, f);
		if(f->nointerface)
			continue;

		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->type))
			continue;

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

		a->name = method->name;
		if(!exportname(method->name)) {
			if(method->pkg == nil)
				fatal("methods: missing package");
			a->pkg = method->pkg;
		}
		a->isym = methodsym(method, it, 1);
		a->tsym = methodsym(method, t, 0);
		a->type = methodfunc(f->type, t);
		a->mtype = methodfunc(f->type, nil);

		if(!(a->isym->flags & SymSiggen)) {
			a->isym->flags |= SymSiggen;
			if(!eqtype(this, it) || this->width < types[tptr]->width) {
				compiling_wrappers = 1;
				genwrapper(it, f, a->isym, 1);
				compiling_wrappers = 0;
			}
		}

		if(!(a->tsym->flags & SymSiggen)) {
			a->tsym->flags |= SymSiggen;
			if(!eqtype(this, t)) {
				compiling_wrappers = 1;
				genwrapper(t, f, a->tsym, 0);
				compiling_wrappers = 0;
			}
		}
	}

	return lsort(a, sigcmp);
}

/*
 * return methods of interface type t, sorted by name.
 */
static Sig*
imethods(Type *t)
{
	Sig *a, *all, *last;
	Type *f;
	Sym *method, *isym;

	all = nil;
	last = nil;
	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;
		method = f->sym;
		a = mal(sizeof(*a));
		a->name = method->name;
		if(!exportname(method->name)) {
			if(method->pkg == nil)
				fatal("imethods: missing package");
			a->pkg = method->pkg;
		}
		a->mtype = f->type;
		a->offset = 0;
		a->type = methodfunc(f->type, nil);

		if(last && sigcmp(last, a) >= 0)
			fatal("sigcmp vs sortinter %s %s", last->name, a->name);
		if(last == nil)
			all = a;
		else
			last->link = a;
		last = a;

		// Compiler can only refer to wrappers for non-blank methods.
		if(isblanksym(method))
			continue;

		// NOTE(rsc): Perhaps an oversight that
		// IfaceType.Method is not in the reflect data.
		// Generate the method body, so that compiled
		// code can refer to it.
		isym = methodsym(method, t, 0);
		if(!(isym->flags & SymSiggen)) {
			isym->flags |= SymSiggen;
			genwrapper(t, f, isym, 0);
		}
	}
	return all;
}

static void
dimportpath(Pkg *p)
{
	static Pkg *gopkg;
	char *nam;
	Node *n;

	if(p->pathsym != S)
		return;

	if(gopkg == nil) {
		gopkg = mkpkg(strlit("go"));
		gopkg->name = "go";
	}
	nam = smprint("importpath.%s.", p->prefix);

	n = nod(ONAME, N, N);
	n->sym = pkglookup(nam, gopkg);
	free(nam);
	n->class = PEXTERN;
	n->xoffset = 0;
	p->pathsym = n->sym;

	gdatastring(n, p->path);
	ggloblsym(n->sym, types[TSTRING]->width, DUPOK|RODATA);
}

static int
dgopkgpath(Sym *s, int ot, Pkg *pkg)
{
	if(pkg == nil)
		return dgostringptr(s, ot, nil);

	// Emit reference to go.importpath.""., which 6l will
	// rewrite using the correct import path.  Every package
	// that imports this one directly defines the symbol.
	if(pkg == localpkg) {
		static Sym *ns;

		if(ns == nil)
			ns = pkglookup("importpath.\"\".", mkpkg(strlit("go")));
		return dsymptr(s, ot, ns, 0);
	}

	dimportpath(pkg);
	return dsymptr(s, ot, pkg->pathsym, 0);
}

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

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

	// fill in *extraType pointer in header
	off = rnd(off, widthptr);
	dsymptr(sym, ptroff, sym, off);

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

	ot = off;
	s = sym;
	if(t->sym) {
		ot = dgostringptr(s, ot, t->sym->name);
		if(t != types[t->etype] && t != errortype)
			ot = dgopkgpath(s, ot, t->sym->pkg);
		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*widthint);
	ot = duintxx(s, ot, n, widthint);
	ot = duintxx(s, ot, n, widthint);

	// methods
	for(a=m; a; a=a->link) {
		// method
		// ../../runtime/type.go:/method
		ot = dgostringptr(s, ot, a->name);
		ot = dgopkgpath(s, ot, a->pkg);
		ot = dsymptr(s, ot, dtypesym(a->mtype), 0);
		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);
	}

	return ot;
}

static int
kinds[] =
{
	[TINT]		= KindInt,
	[TUINT]		= KindUint,
	[TINT8]		= KindInt8,
	[TUINT8]	= KindUint8,
	[TINT16]	= KindInt16,
	[TUINT16]	= KindUint16,
	[TINT32]	= KindInt32,
	[TUINT32]	= KindUint32,
	[TINT64]	= KindInt64,
	[TUINT64]	= KindUint64,
	[TUINTPTR]	= KindUintptr,
	[TFLOAT32]	= KindFloat32,
	[TFLOAT64]	= KindFloat64,
	[TBOOL]		= KindBool,
	[TSTRING]		= KindString,
	[TPTR32]		= KindPtr,
	[TPTR64]		= KindPtr,
	[TSTRUCT]	= KindStruct,
	[TINTER]		= KindInterface,
	[TCHAN]		= KindChan,
	[TMAP]		= KindMap,
	[TARRAY]		= KindArray,
	[TFUNC]		= KindFunc,
	[TCOMPLEX64]	= KindComplex64,
	[TCOMPLEX128]	= KindComplex128,
	[TUNSAFEPTR]	= KindUnsafePointer,
};

int
haspointers(Type *t)
{
	Type *t1;
	int ret;

	if(t->haspointers != 0)
		return t->haspointers - 1;

	switch(t->etype) {
	case TINT:
	case TUINT:
	case TINT8:
	case TUINT8:
	case TINT16:
	case TUINT16:
	case TINT32:
	case TUINT32:
	case TINT64:
	case TUINT64:
	case TUINTPTR:
	case TFLOAT32:
	case TFLOAT64:
	case TCOMPLEX64:
	case TCOMPLEX128:
	case TBOOL:
		ret = 0;
		break;
	case TARRAY:
		if(t->bound < 0) {	// slice
			ret = 1;
			break;
		}
		if(t->bound == 0) {	// empty array
			ret = 0;
			break;
		}
		ret = haspointers(t->type);
		break;
	case TSTRUCT:
		ret = 0;
		for(t1=t->type; t1!=T; t1=t1->down) {
			if(haspointers(t1->type)) {
				ret = 1;
				break;
			}
		}
		break;
	case TSTRING:
	case TPTR32:
	case TPTR64:
	case TUNSAFEPTR:
	case TINTER:
	case TCHAN:
	case TMAP:
	case TFUNC:
	default:
		ret = 1;
		break;
	}
	
	t->haspointers = 1+ret;
	return ret;
}

/*
 * commonType
 * ../../runtime/type.go:/commonType
 */
static int
dcommontype(Sym *s, int ot, Type *t)
{
	int i, alg, sizeofAlg, gcprog;
	Sym *sptr, *algsym, *zero, *gcprog0, *gcprog1, *sbits;
	uint8 gcmask[16];
	static Sym *algarray;
	uint64 x1, x2;
	char *p;
	
	if(ot != 0)
		fatal("dcommontype %d", ot);

	sizeofAlg = 2*widthptr;
	if(algarray == nil)
		algarray = pkglookup("algarray", runtimepkg);
	dowidth(t);
	alg = algtype(t);
	algsym = S;
	if(alg < 0)
		algsym = dalgsym(t);

	if(t->sym != nil && !isptr[t->etype])
		sptr = dtypesym(ptrto(t));
	else
		sptr = weaktypesym(ptrto(t));

	// All (non-reflect-allocated) Types share the same zero object.
	// Each place in the compiler where a pointer to the zero object
	// might be returned by a runtime call (map access return value,
	// 2-arg type cast) declares the size of the zerovalue it needs.
	// The linker magically takes the max of all the sizes.
	zero = pkglookup("zerovalue", runtimepkg);

	// We use size 0 here so we get the pointer to the zero value,
	// but don't allocate space for the zero value unless we need it.
	// TODO: how do we get this symbol into bss?  We really want
	// a read-only bss, but I don't think such a thing exists.

	// ../../pkg/reflect/type.go:/^type.commonType
	// actual type structure
	//	type commonType struct {
	//		size          uintptr
	//		hash          uint32
	//		_             uint8
	//		align         uint8
	//		fieldAlign    uint8
	//		kind          uint8
	//		alg           unsafe.Pointer
	//		gc            unsafe.Pointer
	//		string        *string
	//		*extraType
	//		ptrToThis     *Type
	//		zero          unsafe.Pointer
	//	}
	ot = duintptr(s, ot, t->width);
	ot = duint32(s, ot, typehash(t));
	ot = duint8(s, ot, 0);	// unused

	// runtime (and common sense) expects alignment to be a power of two.
	i = t->align;
	if(i == 0)
		i = 1;
	if((i&(i-1)) != 0)
		fatal("invalid alignment %d for %T", t->align, t);
	ot = duint8(s, ot, t->align);	// align
	ot = duint8(s, ot, t->align);	// fieldAlign

	gcprog = usegcprog(t);
	i = kinds[t->etype];
	if(t->etype == TARRAY && t->bound < 0)
		i = KindSlice;
	if(!haspointers(t))
		i |= KindNoPointers;
	if(isdirectiface(t))
		i |= KindDirectIface;
	if(gcprog)
		i |= KindGCProg;
	ot = duint8(s, ot, i);  // kind
	if(alg >= 0)
		ot = dsymptr(s, ot, algarray, alg*sizeofAlg);
	else
		ot = dsymptr(s, ot, algsym, 0);
	// gc
	if(gcprog) {
		gengcprog(t, &gcprog0, &gcprog1);
		if(gcprog0 != S)
			ot = dsymptr(s, ot, gcprog0, 0);
		else
			ot = duintptr(s, ot, 0);
		ot = dsymptr(s, ot, gcprog1, 0);
	} else {
		gengcmask(t, gcmask);
		x1 = 0;
		for(i=0; i<8; i++)
			x1 = x1<<8 | gcmask[i];
		if(widthptr == 4) {
			p = smprint("gcbits.%#016llux", x1);
		} else {
			x2 = 0;
			for(i=0; i<8; i++)
				x2 = x2<<8 | gcmask[i+8];
			p = smprint("gcbits.%#016llux%016llux", x1, x2);
		}
		sbits = pkglookup(p, runtimepkg);
		if((sbits->flags & SymUniq) == 0) {
			sbits->flags |= SymUniq;
			for(i = 0; i < 2*widthptr; i++)
				duint8(sbits, i, gcmask[i]);
			ggloblsym(sbits, 2*widthptr, DUPOK|RODATA);
		}
		ot = dsymptr(s, ot, sbits, 0);
		ot = duintptr(s, ot, 0);
	}
	p = smprint("%-uT", t);
	//print("dcommontype: %s\n", p);
	ot = dgostringptr(s, ot, p);	// string
	free(p);

	// skip pointer to extraType,
	// which follows the rest of this type structure.
	// caller will fill in if needed.
	// otherwise linker will assume 0.
	ot += widthptr;

	ot = dsymptr(s, ot, sptr, 0);  // ptrto type
	ot = dsymptr(s, ot, zero, 0);  // ptr to zero value
	return ot;
}

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

	p = smprint("%-T", t);
	s = pkglookup(p, typepkg);
	//print("typesym: %s -> %+S\n", p, s);
	free(p);
	return s;
}

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

	p = smprint("%-T.%s", t->outer, t->sym->name);
	s = pkglookup(p, trackpkg);
	free(p);
	return s;
}

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

	// %-uT is what the generated Type's string field says.
	// It uses (ambiguous) package names instead of import paths.
	// %-T is the complete, unambiguous type name.
	// We want the types to end up sorted by string field,
	// so use that first in the name, and then add :%-T to
	// disambiguate. The names are a little long but they are
	// discarded by the linker and do not end up in the symbol
	// table of the final binary.
	p = smprint("%-uT/%-T", t, t);
	s = pkglookup(p, typelinkpkg);
	//print("typelinksym: %s -> %+S\n", p, s);
	free(p);
	return s;
}

Sym*
typesymprefix(char *prefix, Type *t)
{
	char *p;
	Sym *s;

	p = smprint("%s.%-T", prefix, t);
	s = pkglookup(p, typepkg);
	//print("algsym: %s -> %+S\n", p, s);
	free(p);
	return s;
}

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

	if(t == T || (isptr[t->etype] && t->type == T) || isideal(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;
		n->typecheck = 1;
		s->def = n;

		signatlist = list(signatlist, typenod(t));
	}
	return s->def->sym;
}

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

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

static Sym*
weaktypesym(Type *t)
{
	char *p;
	Sym *s;

	p = smprint("%-T", t);
	s = pkglookup(p, weaktypepkg);
	//print("weaktypesym: %s -> %+S\n", p, s);
	free(p);
	return s;
}

static Sym*
dtypesym(Type *t)
{
	int ot, xt, n, isddd, dupok;
	Sym *s, *s1, *s2, *s3, *s4, *slink;
	Sig *a, *m;
	Type *t1, *tbase, *t2;

	// Replace byte, rune aliases with real type.
	// They've been separate internally to make error messages
	// better, but we have to merge them in the reflect tables.
	if(t == bytetype || t == runetype)
		t = types[t->etype];

	if(isideal(t))
		fatal("dtypesym %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.
	tbase = t;
	if(isptr[t->etype] && t->sym == S && t->type->sym != S)
		tbase = t->type;
	dupok = 0;
	if(tbase->sym == S)
		dupok = DUPOK;

	if(compiling_runtime &&
			(tbase == types[tbase->etype] ||
			tbase == bytetype ||
			tbase == runetype ||
			tbase == errortype)) { // int, float, etc
		goto ok;
	}

	// named types from other files are defined only by those files
	if(tbase->sym && !tbase->local)
		return s;
	if(isforw[tbase->etype])
		return s;

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

	case TARRAY:
		if(t->bound >= 0) {
			// ../../runtime/type.go:/ArrayType
			s1 = dtypesym(t->type);
			t2 = typ(TARRAY);
			t2->type = t->type;
			t2->bound = -1;  // slice
			s2 = dtypesym(t2);
			ot = dcommontype(s, ot, t);
			xt = ot - 3*widthptr;
			ot = dsymptr(s, ot, s1, 0);
			ot = dsymptr(s, ot, s2, 0);
			ot = duintptr(s, ot, t->bound);
		} else {
			// ../../runtime/type.go:/SliceType
			s1 = dtypesym(t->type);
			ot = dcommontype(s, ot, t);
			xt = ot - 3*widthptr;
			ot = dsymptr(s, ot, s1, 0);
		}
		break;

	case TCHAN:
		// ../../runtime/type.go:/ChanType
		s1 = dtypesym(t->type);
		ot = dcommontype(s, ot, t);
		xt = ot - 3*widthptr;
		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);
		isddd = 0;
		for(t1=getinargx(t)->type; t1; t1=t1->down) {
			isddd = t1->isddd;
			dtypesym(t1->type);
		}
		for(t1=getoutargx(t)->type; t1; t1=t1->down)
			dtypesym(t1->type);

		ot = dcommontype(s, ot, t);
		xt = ot - 3*widthptr;
		ot = duint8(s, ot, isddd);

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

		// 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++;
		}

		// ../../runtime/type.go:/InterfaceType
		ot = dcommontype(s, ot, t);
		xt = ot - 3*widthptr;
		ot = dsymptr(s, ot, s, ot+widthptr+2*widthint);
		ot = duintxx(s, ot, n, widthint);
		ot = duintxx(s, ot, n, widthint);
		for(a=m; a; a=a->link) {
			// ../../runtime/type.go:/imethod
			ot = dgostringptr(s, ot, a->name);
			ot = dgopkgpath(s, ot, a->pkg);
			ot = dsymptr(s, ot, dtypesym(a->type), 0);
		}
		break;

	case TMAP:
		// ../../runtime/type.go:/MapType
		s1 = dtypesym(t->down);
		s2 = dtypesym(t->type);
		s3 = dtypesym(mapbucket(t));
		s4 = dtypesym(hmap(t));
		ot = dcommontype(s, ot, t);
		xt = ot - 3*widthptr;
		ot = dsymptr(s, ot, s1, 0);
		ot = dsymptr(s, ot, s2, 0);
		ot = dsymptr(s, ot, s3, 0);
		ot = dsymptr(s, ot, s4, 0);
		if(t->down->width > MAXKEYSIZE) {
			ot = duint8(s, ot, widthptr);
			ot = duint8(s, ot, 1); // indirect
		} else {
			ot = duint8(s, ot, t->down->width);
			ot = duint8(s, ot, 0); // not indirect
		}
		if(t->type->width > MAXVALSIZE) {
			ot = duint8(s, ot, widthptr);
			ot = duint8(s, ot, 1); // indirect
		} else {
			ot = duint8(s, ot, t->type->width);
			ot = duint8(s, ot, 0); // not indirect
		}
		ot = duint16(s, ot, mapbucket(t)->width);
		break;

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

	case TSTRUCT:
		// ../../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);
		xt = ot - 3*widthptr;
		ot = dsymptr(s, ot, s, ot+widthptr+2*widthint);
		ot = duintxx(s, ot, n, widthint);
		ot = duintxx(s, ot, n, widthint);
		for(t1=t->type; t1!=T; t1=t1->down) {
			// ../../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 = dgopkgpath(s, ot, t1->sym->pkg);
			} else {
				ot = dgostringptr(s, ot, nil);
				if(t1->type->sym != S && t1->type->sym->pkg == builtinpkg)
					ot = dgopkgpath(s, ot, localpkg);
				else
					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;
	}
	ot = dextratype(s, ot, t, xt);
	ggloblsym(s, ot, dupok|RODATA);

	// generate typelink.foo pointing at s = type.foo.
	// The linker will leave a table of all the typelinks for
	// types in the binary, so reflect can find them.
	// We only need the link for unnamed composites that
	// we want be able to find.
	if(t->sym == S) {
		switch(t->etype) {
		case TARRAY:
		case TCHAN:
		case TMAP:
			slink = typelinksym(t);
			dsymptr(slink, 0, s, 0);
			ggloblsym(slink, widthptr, dupok|RODATA);
		}
	}

	return s;
}

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

	// 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)
			dtypesym(ptrto(t));
	}

	// generate import strings for imported packages
	for(i=0; i<nelem(phash); i++)
		for(p=phash[i]; p; p=p->link)
			if(p->direct)
				dimportpath(p);

	// do basic types if compiling package runtime.
	// they have to be in at least one package,
	// and runtime 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(compiling_runtime) {
		for(i=1; i<=TBOOL; i++)
			dtypesym(ptrto(types[i]));
		dtypesym(ptrto(types[TSTRING]));
		dtypesym(ptrto(types[TUNSAFEPTR]));

		// emit type structs for error and func(error) string.
		// The latter is the type of an auto-generated wrapper.
		dtypesym(ptrto(errortype));
		dtypesym(functype(nil,
			list1(nod(ODCLFIELD, N, typenod(errortype))),
			list1(nod(ODCLFIELD, N, typenod(types[TSTRING])))));

		// add paths for runtime and main, which 6l imports implicitly.
		dimportpath(runtimepkg);
		if(flag_race)
			dimportpath(racepkg);
		dimportpath(mkpkg(strlit("main")));
	}
}

static Sym*
dalgsym(Type *t)
{
	int ot;
	Sym *s, *hash, *hashfunc, *eq, *eqfunc;

	// dalgsym is only called for a type that needs an algorithm table,
	// which implies that the type is comparable (or else it would use ANOEQ).

	s = typesymprefix(".alg", t);
	hash = typesymprefix(".hash", t);
	genhash(hash, t);
	eq = typesymprefix(".eq", t);
	geneq(eq, t);

	// make Go funcs (closures) for calling hash and equal from Go
	hashfunc = typesymprefix(".hashfunc", t);
	dsymptr(hashfunc, 0, hash, 0);
	ggloblsym(hashfunc, widthptr, DUPOK|RODATA);
	eqfunc = typesymprefix(".eqfunc", t);
	dsymptr(eqfunc, 0, eq, 0);
	ggloblsym(eqfunc, widthptr, DUPOK|RODATA);

	// ../../runtime/alg.go:/typeAlg
	ot = 0;
	ot = dsymptr(s, ot, hashfunc, 0);
	ot = dsymptr(s, ot, eqfunc, 0);

	ggloblsym(s, ot, DUPOK|RODATA);
	return s;
}

static int
usegcprog(Type *t)
{
	vlong size, nptr;

	if(!haspointers(t))
		return 0;
	if(t->width == BADWIDTH)
		dowidth(t);
	// Calculate size of the unrolled GC mask.
	nptr = (t->width+widthptr-1)/widthptr;
	size = nptr;
	if(size%2)
		size *= 2;	// repeated
	size = size*gcBits/8;	// 4 bits per word
	// Decide whether to use unrolled GC mask or GC program.
	// We could use a more elaborate condition, but this seems to work well in practice.
	// For small objects GC program can't give significant reduction.
	// While large objects usually contain arrays; and even if it don't
	// the program uses 2-bits per word while mask uses 4-bits per word,
	// so the program is still smaller.
	return size > 2*widthptr;
}

// Generates sparse GC bitmask (4 bits per word).
static void
gengcmask(Type *t, uint8 gcmask[16])
{
	Bvec *vec;
	vlong xoffset, nptr, i, j;
	int  half, mw;
	uint8 bits, *pos;

	memset(gcmask, 0, 16);
	if(!haspointers(t))
		return;

	// Generate compact mask as stacks use.
	xoffset = 0;
	vec = bvalloc(2*widthptr*8);
	twobitwalktype1(t, &xoffset, vec);

	// Unfold the mask for the GC bitmap format:
	// 4 bits per word, 2 high bits encode pointer info.
	pos = (uint8*)gcmask;
	nptr = (t->width+widthptr-1)/widthptr;
	half = 0;
	mw = 0;
	// If number of words is odd, repeat the mask.
	// This makes simpler handling of arrays in runtime.
	for(j=0; j<=(nptr%2); j++) {
		for(i=0; i<nptr; i++) {
			bits = bvget(vec, i*BitsPerPointer) | bvget(vec, i*BitsPerPointer+1)<<1;
			// Some fake types (e.g. Hmap) has missing fileds.
			// twobitwalktype1 generates BitsDead for that holes,
			// replace BitsDead with BitsScalar.
			if(!mw && bits == BitsDead)
				bits = BitsScalar;
			mw = !mw && bits == BitsMultiWord;
			bits <<= 2;
			if(half)
				bits <<= 4;
			*pos |= bits;
			half = !half;
			if(!half)
				pos++;
		}
	}
}

// Helper object for generation of GC programs.
typedef struct ProgGen ProgGen;
struct ProgGen
{
	Sym*	s;
	int32	datasize;
	uint8	data[256/PointersPerByte];
	vlong	ot;
};

static void
proggeninit(ProgGen *g, Sym *s)
{
	g->s = s;
	g->datasize = 0;
	g->ot = 0;
	memset(g->data, 0, sizeof(g->data));
}

static void
proggenemit(ProgGen *g, uint8 v)
{
	g->ot = duint8(g->s, g->ot, v);
}

// Emits insData block from g->data.
static void
proggendataflush(ProgGen *g)
{
	int32 i, s;

	if(g->datasize == 0)
		return;
	proggenemit(g, insData);
	proggenemit(g, g->datasize);
	s = (g->datasize + PointersPerByte - 1)/PointersPerByte;
	for(i = 0; i < s; i++)
		proggenemit(g, g->data[i]);
	g->datasize = 0;
	memset(g->data, 0, sizeof(g->data));
}

static void
proggendata(ProgGen *g, uint8 d)
{
	g->data[g->datasize/PointersPerByte] |= d << ((g->datasize%PointersPerByte)*BitsPerPointer);
	g->datasize++;
	if(g->datasize == 255)
		proggendataflush(g);
}

// Skip v bytes due to alignment, etc.
static void
proggenskip(ProgGen *g, vlong off, vlong v)
{
	vlong i;

	for(i = off; i < off+v; i++) {
		if((i%widthptr) == 0)
			proggendata(g, BitsScalar);
	}
}

// Emit insArray instruction.
static void
proggenarray(ProgGen *g, vlong len)
{
	int32 i;

	proggendataflush(g);
	proggenemit(g, insArray);
	for(i = 0; i < widthptr; i++, len >>= 8)
		proggenemit(g, len);
}

static void
proggenarrayend(ProgGen *g)
{
	proggendataflush(g);
	proggenemit(g, insArrayEnd);
}

static vlong
proggenfini(ProgGen *g)
{
	proggendataflush(g);
	proggenemit(g, insEnd);
	return g->ot;
}

static void gengcprog1(ProgGen *g, Type *t, vlong *xoffset);

// Generates GC program for large types.
static void
gengcprog(Type *t, Sym **pgc0, Sym **pgc1)
{
	Sym *gc0, *gc1;
	vlong nptr, size, ot, xoffset;
	ProgGen g;

	nptr = (t->width+widthptr-1)/widthptr;
	size = nptr;
	if(size%2)
		size *= 2;	// repeated twice
	size = size*PointersPerByte/8;	// 4 bits per word
	size++;	// unroll flag in the beginning, used by runtime (see runtime.markallocated)
	// emity space in BSS for unrolled program
	*pgc0 = S;
	// Don't generate it if it's too large, runtime will unroll directly into GC bitmap.
	if(size <= MaxGCMask) {
		gc0 = typesymprefix(".gc", t);
		ggloblsym(gc0, size, DUPOK|NOPTR);
		*pgc0 = gc0;
	}

	// program in RODATA
	gc1 = typesymprefix(".gcprog", t);
	proggeninit(&g, gc1);
	xoffset = 0;
	gengcprog1(&g, t, &xoffset);
	ot = proggenfini(&g);
	ggloblsym(gc1, ot, DUPOK|RODATA);
	*pgc1 = gc1;
}

// Recursively walks type t and writes GC program into g.
static void
gengcprog1(ProgGen *g, Type *t, vlong *xoffset)
{
	vlong fieldoffset, i, o, n;
	Type *t1;

	switch(t->etype) {
	case TINT8:
	case TUINT8:
	case TINT16:
	case TUINT16:
	case TINT32:
	case TUINT32:
	case TINT64:
	case TUINT64:
	case TINT:
	case TUINT:
	case TUINTPTR:
	case TBOOL:
	case TFLOAT32:
	case TFLOAT64:
	case TCOMPLEX64:
	case TCOMPLEX128:
		proggenskip(g, *xoffset, t->width);
		*xoffset += t->width;
		break;
	case TPTR32:
	case TPTR64:
	case TUNSAFEPTR:
	case TFUNC:
	case TCHAN:
	case TMAP:
		proggendata(g, BitsPointer);
		*xoffset += t->width;
		break;
	case TSTRING:
		proggendata(g, BitsPointer);
		proggendata(g, BitsScalar);
		*xoffset += t->width;
		break;
	case TINTER:
		proggendata(g, BitsMultiWord);
		if(isnilinter(t))
			proggendata(g, BitsEface);
		else
			proggendata(g, BitsIface);
		*xoffset += t->width;
		break;
	case TARRAY:
		if(isslice(t)) {
			proggendata(g, BitsPointer);
			proggendata(g, BitsScalar);
			proggendata(g, BitsScalar);
		} else {
			t1 = t->type;
			if(t1->width == 0) {
				// ignore
			} if(t->bound <= 1 || t->bound*t1->width < 32*widthptr) {
				for(i = 0; i < t->bound; i++)
					gengcprog1(g, t1, xoffset);
			} else if(!haspointers(t1)) {
				n = t->width;
				n -= -*xoffset&(widthptr-1); // skip to next ptr boundary
				proggenarray(g, (n+widthptr-1)/widthptr);
				proggendata(g, BitsScalar);
				proggenarrayend(g);
				*xoffset -= (n+widthptr-1)/widthptr*widthptr - t->width;
			} else {
				proggenarray(g, t->bound);
				gengcprog1(g, t1, xoffset);
				*xoffset += (t->bound-1)*t1->width;
				proggenarrayend(g);
			}
		}
		break;
	case TSTRUCT:
		o = 0;
		for(t1 = t->type; t1 != T; t1 = t1->down) {
			fieldoffset = t1->width;
			proggenskip(g, *xoffset, fieldoffset - o);
			*xoffset += fieldoffset - o;
			gengcprog1(g, t1->type, xoffset);
			o = fieldoffset + t1->type->width;
		}
		proggenskip(g, *xoffset, t->width - o);
		*xoffset += t->width - o;
		break;
	default:
		fatal("gengcprog1: unexpected type, %T", t);
	}
}
