// Copyright 2012 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	"l.h"
#include	"lib.h"
#include	"../../pkg/runtime/typekind.h"

// Decoding the type.* symbols.	 This has to be in sync with
// ../../pkg/runtime/type.go, or more specificaly, with what
// ../gc/reflect.c stuffs in these.

static Reloc*
decode_reloc(LSym *s, int32 off)
{
	int i;

	for (i = 0; i < s->nr; i++)
		if (s->r[i].off == off)
			return s->r + i;
	return nil;
}

static LSym*
decode_reloc_sym(LSym *s, int32 off)
{
	Reloc *r;

	r = decode_reloc(s,off);
	if (r == nil)
		return nil;
	return r->sym;
}

static uvlong
decode_inuxi(uchar* p, int sz)
{
	uint64 v;
	uint32 l;
	uchar *cast, *inuxi;
	int i;

	v = l = 0;
	cast = nil;
	inuxi = nil;
	switch (sz) {
	case 2:
		cast = (uchar*)&l;
		inuxi = inuxi2;
		break;
	case 4:
		cast = (uchar*)&l;
		inuxi = inuxi4;
		break;
	case 8:
		cast = (uchar*)&v;
		inuxi = inuxi8;
		break;
	default:
		diag("dwarf: decode inuxi %d", sz);
		errorexit();
	}
	for (i = 0; i < sz; i++)
		cast[inuxi[i]] = p[i];
	if (sz == 8)
		return v;
	return l;
}

static int
commonsize(void)
{
	return 7*PtrSize + 8;
}

// Type.commonType.kind
uint8
decodetype_kind(LSym *s)
{
	return s->p[1*PtrSize + 7] & ~KindNoPointers;	//  0x13 / 0x1f
}

// Type.commonType.size
vlong
decodetype_size(LSym *s)
{
	return decode_inuxi(s->p, PtrSize);	 // 0x8 / 0x10
}

// Type.commonType.gc
LSym*
decodetype_gc(LSym *s)
{
	return decode_reloc_sym(s, 1*PtrSize + 8 + 1*PtrSize);
}

// Type.ArrayType.elem and Type.SliceType.Elem
LSym*
decodetype_arrayelem(LSym *s)
{
	return decode_reloc_sym(s, commonsize());	// 0x1c / 0x30
}

vlong
decodetype_arraylen(LSym *s)
{
	return decode_inuxi(s->p + commonsize()+PtrSize, PtrSize);
}

// Type.PtrType.elem
LSym*
decodetype_ptrelem(LSym *s)
{
	return decode_reloc_sym(s, commonsize());	// 0x1c / 0x30
}

// Type.MapType.key, elem
LSym*
decodetype_mapkey(LSym *s)
{
	return decode_reloc_sym(s, commonsize());	// 0x1c / 0x30
}
LSym*
decodetype_mapvalue(LSym *s)
{
	return decode_reloc_sym(s, commonsize()+PtrSize);	// 0x20 / 0x38
}

// Type.ChanType.elem
LSym*
decodetype_chanelem(LSym *s)
{
	return decode_reloc_sym(s, commonsize());	// 0x1c / 0x30
}

// Type.FuncType.dotdotdot
int
decodetype_funcdotdotdot(LSym *s)
{
	return s->p[commonsize()];
}

// Type.FuncType.in.len
int
decodetype_funcincount(LSym *s)
{
	return decode_inuxi(s->p + commonsize()+2*PtrSize, IntSize);
}

int
decodetype_funcoutcount(LSym *s)
{
	return decode_inuxi(s->p + commonsize()+3*PtrSize + 2*IntSize, IntSize);
}

LSym*
decodetype_funcintype(LSym *s, int i)
{
	Reloc *r;

	r = decode_reloc(s, commonsize() + PtrSize);
	if (r == nil)
		return nil;
	return decode_reloc_sym(r->sym, r->add + i * PtrSize);
}

LSym*
decodetype_funcouttype(LSym *s, int i)
{
	Reloc *r;

	r = decode_reloc(s, commonsize() + 2*PtrSize + 2*IntSize);
	if (r == nil)
		return nil;
	return decode_reloc_sym(r->sym, r->add + i * PtrSize);
}

// Type.StructType.fields.Slice::len
int
decodetype_structfieldcount(LSym *s)
{
	return decode_inuxi(s->p + commonsize() + PtrSize, IntSize);
}

static int
structfieldsize(void)
{
	return 5*PtrSize;
}

// Type.StructType.fields[]-> name, typ and offset.
char*
decodetype_structfieldname(LSym *s, int i)
{
	Reloc *r;

	// go.string."foo"  0x28 / 0x40
	s = decode_reloc_sym(s, commonsize() + PtrSize + 2*IntSize + i*structfieldsize());
	if (s == nil)			// embedded structs have a nil name.
		return nil;
	r = decode_reloc(s, 0);		// s has a pointer to the string data at offset 0
	if (r == nil)			// shouldn't happen.
		return nil;
	return (char*) r->sym->p + r->add;	// the c-string
}

LSym*
decodetype_structfieldtype(LSym *s, int i)
{
	return decode_reloc_sym(s, commonsize() + PtrSize + 2*IntSize + i*structfieldsize() + 2*PtrSize);
}

vlong
decodetype_structfieldoffs(LSym *s, int i)
{
	return decode_inuxi(s->p + commonsize() + PtrSize + 2*IntSize + i*structfieldsize() + 4*PtrSize, IntSize);
}

// InterfaceTYpe.methods.len
vlong
decodetype_ifacemethodcount(LSym *s)
{
	return decode_inuxi(s->p + commonsize() + PtrSize, IntSize);
}
