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

enum {
	maxround = sizeof(uintptr),
};

uint32	runtime·panicking;
void	(*runtime·destroylock)(Lock*);

/*
 * We assume that all architectures turn faults and the like
 * into apparent calls to runtime.sigpanic.  If we see a "call"
 * to runtime.sigpanic, we do not back up the PC to find the
 * line number of the CALL instruction, because there is no CALL.
 */
void	runtime·sigpanic(void);

int32
runtime·gotraceback(void)
{
	byte *p;

	p = runtime·getenv("GOTRACEBACK");
	if(p == nil || p[0] == '\0')
		return 1;	// default is on
	return runtime·atoi(p);
}

static Lock paniclk;

void
runtime·startpanic(void)
{
	if(m->dying) {
		runtime·printf("panic during panic\n");
		runtime·exit(3);
	}
	m->dying = 1;
	runtime·xadd(&runtime·panicking, 1);
	runtime·lock(&paniclk);
}

void
runtime·dopanic(int32 unused)
{
	static bool didothers;

	if(g->sig != 0)
		runtime·printf("\n[signal %x code=%p addr=%p pc=%p]\n",
			g->sig, g->sigcode0, g->sigcode1, g->sigpc);

	runtime·printf("\n");
	if(runtime·gotraceback()){
		runtime·traceback(runtime·getcallerpc(&unused), runtime·getcallersp(&unused), 0, g);
		if(!didothers) {
			didothers = true;
			runtime·tracebackothers(g);
		}
	}
	runtime·unlock(&paniclk);
	if(runtime·xadd(&runtime·panicking, -1) != 0) {
		// Some other m is panicking too.
		// Let it print what it needs to print.
		// Wait forever without chewing up cpu.
		// It will exit when it's done.
		static Lock deadlock;
		runtime·lock(&deadlock);
		runtime·lock(&deadlock);
	}

	runtime·exit(2);
}

void
runtime·panicindex(void)
{
	runtime·panicstring("index out of range");
}

void
runtime·panicslice(void)
{
	runtime·panicstring("slice bounds out of range");
}

void
runtime·throwreturn(void)
{
	// can only happen if compiler is broken
	runtime·throw("no return at end of a typed function - compiler is broken");
}

void
runtime·throwinit(void)
{
	// can only happen with linker skew
	runtime·throw("recursive call during initialization - linker skew");
}

void
runtime·throw(int8 *s)
{
	runtime·startpanic();
	runtime·printf("throw: %s\n", s);
	runtime·dopanic(0);
	*(int32*)0 = 0;	// not reached
	runtime·exit(1);	// even more not reached
}

void
runtime·panicstring(int8 *s)
{
	Eface err;
	
	if(m->gcing) {
		runtime·printf("panic: %s\n", s);
		runtime·throw("panic during gc");
	}
	runtime·newErrorString(runtime·gostringnocopy((byte*)s), &err);
	runtime·panic(err);
}

int32
runtime·mcmp(byte *s1, byte *s2, uint32 n)
{
	uint32 i;
	byte c1, c2;

	for(i=0; i<n; i++) {
		c1 = s1[i];
		c2 = s2[i];
		if(c1 < c2)
			return -1;
		if(c1 > c2)
			return +1;
	}
	return 0;
}


byte*
runtime·mchr(byte *p, byte c, byte *ep)
{
	for(; p < ep; p++)
		if(*p == c)
			return p;
	return nil;
}

uint32
runtime·rnd(uint32 n, uint32 m)
{
	uint32 r;

	if(m > maxround)
		m = maxround;
	r = n % m;
	if(r)
		n += m-r;
	return n;
}

static int32	argc;
static uint8**	argv;

Slice os·Args;
Slice os·Envs;

void
runtime·args(int32 c, uint8 **v)
{
	argc = c;
	argv = v;
}

int32 runtime·isplan9;
int32 runtime·iswindows;

void
runtime·goargs(void)
{
	String *s;
	int32 i;
	
	// for windows implementation see "os" package
	if(Windows)
		return;

	s = runtime·malloc(argc*sizeof s[0]);
	for(i=0; i<argc; i++)
		s[i] = runtime·gostringnocopy(argv[i]);
	os·Args.array = (byte*)s;
	os·Args.len = argc;
	os·Args.cap = argc;
}

void
runtime·goenvs_unix(void)
{
	String *s;
	int32 i, n;
	
	for(n=0; argv[argc+1+n] != 0; n++)
		;

	s = runtime·malloc(n*sizeof s[0]);
	for(i=0; i<n; i++)
		s[i] = runtime·gostringnocopy(argv[argc+1+i]);
	os·Envs.array = (byte*)s;
	os·Envs.len = n;
	os·Envs.cap = n;
}

byte*
runtime·getenv(int8 *s)
{
	int32 i, j, len;
	byte *v, *bs;
	String* envv;
	int32 envc;

	bs = (byte*)s;
	len = runtime·findnull(bs);
	envv = (String*)os·Envs.array;
	envc = os·Envs.len;
	for(i=0; i<envc; i++){
		if(envv[i].len <= len)
			continue;
		v = envv[i].str;
		for(j=0; j<len; j++)
			if(bs[j] != v[j])
				goto nomatch;
		if(v[len] != '=')
			goto nomatch;
		return v+len+1;
	nomatch:;
	}
	return nil;
}

void
runtime·getgoroot(String out)
{
	byte *p;

	p = runtime·getenv("GOROOT");
	out = runtime·gostringnocopy(p);
	FLUSH(&out);
}

int32
runtime·atoi(byte *p)
{
	int32 n;

	n = 0;
	while('0' <= *p && *p <= '9')
		n = n*10 + *p++ - '0';
	return n;
}

void
runtime·check(void)
{
	int8 a;
	uint8 b;
	int16 c;
	uint16 d;
	int32 e;
	uint32 f;
	int64 g;
	uint64 h;
	float32 i;
	float64 j;
	void* k;
	uint16* l;
	struct x1 {
		byte x;
	};
	struct y1 {
		struct x1 x1;
		byte y;
	};

	if(sizeof(a) != 1) runtime·throw("bad a");
	if(sizeof(b) != 1) runtime·throw("bad b");
	if(sizeof(c) != 2) runtime·throw("bad c");
	if(sizeof(d) != 2) runtime·throw("bad d");
	if(sizeof(e) != 4) runtime·throw("bad e");
	if(sizeof(f) != 4) runtime·throw("bad f");
	if(sizeof(g) != 8) runtime·throw("bad g");
	if(sizeof(h) != 8) runtime·throw("bad h");
	if(sizeof(i) != 4) runtime·throw("bad i");
	if(sizeof(j) != 8) runtime·throw("bad j");
	if(sizeof(k) != sizeof(uintptr)) runtime·throw("bad k");
	if(sizeof(l) != sizeof(uintptr)) runtime·throw("bad l");
	if(sizeof(struct x1) != 1) runtime·throw("bad sizeof x1");
	if(offsetof(struct y1, y) != 1) runtime·throw("bad offsetof y1.y");
	if(sizeof(struct y1) != 2) runtime·throw("bad sizeof y1");

	uint32 z;
	z = 1;
	if(!runtime·cas(&z, 1, 2))
		runtime·throw("cas1");
	if(z != 2)
		runtime·throw("cas2");

	z = 4;
	if(runtime·cas(&z, 5, 6))
		runtime·throw("cas3");
	if(z != 4)
		runtime·throw("cas4");

	runtime·initsig(0);
}

/*
 * map and chan helpers for
 * dealing with unknown types
 */
static uintptr
memhash(uint32 s, void *a)
{
	byte *b;
	uintptr hash;

	b = a;
	if(sizeof(hash) == 4)
		hash = 2860486313U;
	else
		hash = 33054211828000289ULL;
	while(s > 0) {
		if(sizeof(hash) == 4)
			hash = (hash ^ *b) * 3267000013UL;
		else
			hash = (hash ^ *b) * 23344194077549503ULL;
		b++;
		s--;
	}
	return hash;
}

static uint32
memequal(uint32 s, void *a, void *b)
{
	byte *ba, *bb, *aend;

	if(a == b)
	  return 1;
	ba = a;
	bb = b;
	aend = ba+s;
	while(ba != aend) {
		if(*ba != *bb)
			return 0;
		ba++;
		bb++;
	}
	return 1;
}

static void
memprint(uint32 s, void *a)
{
	uint64 v;

	v = 0xbadb00b;
	switch(s) {
	case 1:
		v = *(uint8*)a;
		break;
	case 2:
		v = *(uint16*)a;
		break;
	case 4:
		v = *(uint32*)a;
		break;
	case 8:
		v = *(uint64*)a;
		break;
	}
	runtime·printint(v);
}

static void
memcopy(uint32 s, void *a, void *b)
{
	if(b == nil) {
		runtime·memclr(a,s);
		return;
	}
	runtime·memmove(a,b,s);
}

static uint32
memequal8(uint32 s, uint8 *a, uint8 *b)
{
	USED(s);
	return *a == *b;
}

static void
memcopy8(uint32 s, uint8 *a, uint8 *b)
{
	USED(s);
	if(b == nil) {
		*a = 0;
		return;
	}
	*a = *b;
}

static uint32
memequal16(uint32 s, uint16 *a, uint16 *b)
{
	USED(s);
	return *a == *b;
}

static void
memcopy16(uint32 s, uint16 *a, uint16 *b)
{
	USED(s);
	if(b == nil) {
		*a = 0;
		return;
	}
	*a = *b;
}

static uint32
memequal32(uint32 s, uint32 *a, uint32 *b)
{
	USED(s);
	return *a == *b;
}

static void
memcopy32(uint32 s, uint32 *a, uint32 *b)
{
	USED(s);
	if(b == nil) {
		*a = 0;
		return;
	}
	*a = *b;
}

static uint32
memequal64(uint32 s, uint64 *a, uint64 *b)
{
	USED(s);
	return *a == *b;
}

static void
memcopy64(uint32 s, uint64 *a, uint64 *b)
{
	USED(s);
	if(b == nil) {
		*a = 0;
		return;
	}
	*a = *b;
}

static uint32
memequal128(uint32 s, uint64 *a, uint64 *b)
{
	USED(s);
	return a[0] == b[0] && a[1] == b[1];
}

static void
memcopy128(uint32 s, uint64 *a, uint64 *b)
{
	USED(s);
	if(b == nil) {
		a[0] = 0;
		a[1] = 0;
		return;
	}
	a[0] = b[0];
	a[1] = b[1];
}

static void
slicecopy(uint32 s, Slice *a, Slice *b)
{
	USED(s);
	if(b == nil) {
		a->array = 0;
		a->len = 0;
		a->cap = 0;
		return;
	}
	a->array = b->array;
	a->len = b->len;
	a->cap = b->cap;
}

static uintptr
strhash(uint32 s, String *a)
{
	USED(s);
	return memhash((*a).len, (*a).str);
}

static uint32
strequal(uint32 s, String *a, String *b)
{
	int32 alen;

	USED(s);
	alen = a->len;
	if(alen != b->len)
		return false;
	return memequal(alen, a->str, b->str);
}

static void
strprint(uint32 s, String *a)
{
	USED(s);
	runtime·printstring(*a);
}

static void
strcopy(uint32 s, String *a, String *b)
{
	USED(s);
	if(b == nil) {
		a->str = 0;
		a->len = 0;
		return;
	}
	a->str = b->str;
	a->len = b->len;
}

static uintptr
interhash(uint32 s, Iface *a)
{
	USED(s);
	return runtime·ifacehash(*a);
}

static void
interprint(uint32 s, Iface *a)
{
	USED(s);
	runtime·printiface(*a);
}

static uint32
interequal(uint32 s, Iface *a, Iface *b)
{
	USED(s);
	return runtime·ifaceeq_c(*a, *b);
}

static void
intercopy(uint32 s, Iface *a, Iface *b)
{
	USED(s);
	if(b == nil) {
		a->tab = 0;
		a->data = 0;
		return;
	}
	a->tab = b->tab;
	a->data = b->data;
}

static uintptr
nilinterhash(uint32 s, Eface *a)
{
	USED(s);
	return runtime·efacehash(*a);
}

static void
nilinterprint(uint32 s, Eface *a)
{
	USED(s);
	runtime·printeface(*a);
}

static uint32
nilinterequal(uint32 s, Eface *a, Eface *b)
{
	USED(s);
	return runtime·efaceeq_c(*a, *b);
}

static void
nilintercopy(uint32 s, Eface *a, Eface *b)
{
	USED(s);
	if(b == nil) {
		a->type = 0;
		a->data = 0;
		return;
	}
	a->type = b->type;
	a->data = b->data;
}

uintptr
runtime·nohash(uint32 s, void *a)
{
	USED(s);
	USED(a);
	runtime·panicstring("hash of unhashable type");
	return 0;
}

uint32
runtime·noequal(uint32 s, void *a, void *b)
{
	USED(s);
	USED(a);
	USED(b);
	runtime·panicstring("comparing uncomparable types");
	return 0;
}

Alg
runtime·algarray[] =
{
[AMEM]	{ memhash, memequal, memprint, memcopy },
[ANOEQ]	{ runtime·nohash, runtime·noequal, memprint, memcopy },
[ASTRING]	{ strhash, strequal, strprint, strcopy },
[AINTER]		{ interhash, interequal, interprint, intercopy },
[ANILINTER]	{ nilinterhash, nilinterequal, nilinterprint, nilintercopy },
[ASLICE]	{ runtime·nohash, runtime·noequal, memprint, slicecopy },
[AMEM8]		{ memhash, memequal8, memprint, memcopy8 },
[AMEM16]	{ memhash, memequal16, memprint, memcopy16 },
[AMEM32]	{ memhash, memequal32, memprint, memcopy32 },
[AMEM64]	{ memhash, memequal64, memprint, memcopy64 },
[AMEM128]	{ memhash, memequal128, memprint, memcopy128 },
[ANOEQ8]	{ runtime·nohash, runtime·noequal, memprint, memcopy8 },
[ANOEQ16]	{ runtime·nohash, runtime·noequal, memprint, memcopy16 },
[ANOEQ32]	{ runtime·nohash, runtime·noequal, memprint, memcopy32 },
[ANOEQ64]	{ runtime·nohash, runtime·noequal, memprint, memcopy64 },
[ANOEQ128]	{ runtime·nohash, runtime·noequal, memprint, memcopy128 },
};

int64
runtime·nanotime(void)
{
	int64 sec;
	int32 usec;

	sec = 0;
	usec = 0;
	runtime·gettime(&sec, &usec);
	return sec*1000000000 + (int64)usec*1000;
}

void
runtime·Caller(int32 skip, uintptr retpc, String retfile, int32 retline, bool retbool)
{
	Func *f, *g;
	uintptr pc;
	uintptr rpc[2];

	/*
	 * Ask for two PCs: the one we were asked for
	 * and what it called, so that we can see if it
	 * "called" sigpanic.
	 */
	retpc = 0;
	if(runtime·callers(1+skip-1, rpc, 2) < 2) {
		retfile = runtime·emptystring;
		retline = 0;
		retbool = false;
	} else if((f = runtime·findfunc(rpc[1])) == nil) {
		retfile = runtime·emptystring;
		retline = 0;
		retbool = true;  // have retpc at least
	} else {
		retpc = rpc[1];
		retfile = f->src;
		pc = retpc;
		g = runtime·findfunc(rpc[0]);
		if(pc > f->entry && (g == nil || g->entry != (uintptr)runtime·sigpanic))
			pc--;
		retline = runtime·funcline(f, pc);
		retbool = true;
	}
	FLUSH(&retpc);
	FLUSH(&retfile);
	FLUSH(&retline);
	FLUSH(&retbool);
}

void
runtime·Callers(int32 skip, Slice pc, int32 retn)
{
	retn = runtime·callers(skip, (uintptr*)pc.array, pc.len);
	FLUSH(&retn);
}

void
runtime·FuncForPC(uintptr pc, void *retf)
{
	retf = runtime·findfunc(pc);
	FLUSH(&retf);
}

uint32
runtime·fastrand1(void)
{
	uint32 x;

	x = m->fastrand;
	x += x;
	if(x & 0x80000000L)
		x ^= 0x88888eefUL;
	m->fastrand = x;
	return x;
}
