// 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 "runtime.h"
#include "arch_GOARCH.h"
#include "stack.h"
#include "malloc.h"
#include "../../cmd/ld/textflag.h"

// Code related to defer, panic and recover.

uint32 runtime·panicking;
static Lock paniclk;

// Each P holds pool for defers with arg sizes 8, 24, 40, 56 and 72 bytes.
// Memory block is 40 (24 for 32 bits) bytes larger due to Defer header.
// This maps exactly to malloc size classes.

// defer size class for arg size sz
#define DEFERCLASS(sz) (((sz)+7)>>4)
// total size of memory block for defer with arg size sz
#define TOTALSIZE(sz) (sizeof(Defer) - sizeof(((Defer*)nil)->args) + ROUND(sz, sizeof(uintptr)))

// Allocate a Defer, usually using per-P pool.
// Each defer must be released with freedefer.
static Defer*
newdefer(int32 siz)
{
	int32 total, sc;
	Defer *d;
	P *p;

	d = nil;
	sc = DEFERCLASS(siz);
	if(sc < nelem(p->deferpool)) {
		p = m->p;
		d = p->deferpool[sc];
		if(d)
			p->deferpool[sc] = d->link;
	}
	if(d == nil) {
		// deferpool is empty or just a big defer
		total = TOTALSIZE(siz);
		d = runtime·malloc(total);
	}
	d->siz = siz;
	d->special = 0;
	d->link = g->defer;
	g->defer = d;
	return d;
}

// Free the given defer.
// The defer cannot be used after this call.
static void
freedefer(Defer *d)
{
	int32 sc;
	P *p;

	if(d->special)
		return;
	sc = DEFERCLASS(d->siz);
	if(sc < nelem(p->deferpool)) {
		p = m->p;
		d->link = p->deferpool[sc];
		p->deferpool[sc] = d;
		// No need to wipe out pointers in argp/pc/fn/args,
		// because we empty the pool before GC.
	} else
		runtime·free(d);
}

// Create a new deferred function fn with siz bytes of arguments.
// The compiler turns a defer statement into a call to this.
// Cannot split the stack because it assumes that the arguments
// are available sequentially after &fn; they would not be
// copied if a stack split occurred.  It's OK for this to call
// functions that split the stack.
#pragma textflag NOSPLIT
uintptr
runtime·deferproc(int32 siz, FuncVal *fn, ...)
{
	Defer *d;

	d = newdefer(siz);
	d->fn = fn;
	d->pc = runtime·getcallerpc(&siz);
	if(thechar == '5')
		d->argp = (byte*)(&fn+2);  // skip caller's saved link register
	else
		d->argp = (byte*)(&fn+1);
	runtime·memmove(d->args, d->argp, d->siz);

	// deferproc returns 0 normally.
	// a deferred func that stops a panic
	// makes the deferproc return 1.
	// the code the compiler generates always
	// checks the return value and jumps to the
	// end of the function if deferproc returns != 0.
	return 0;
}

// Run a deferred function if there is one.
// The compiler inserts a call to this at the end of any
// function which calls defer.
// If there is a deferred function, this will call runtime·jmpdefer,
// which will jump to the deferred function such that it appears
// to have been called by the caller of deferreturn at the point
// just before deferreturn was called.  The effect is that deferreturn
// is called again and again until there are no more deferred functions.
// Cannot split the stack because we reuse the caller's frame to
// call the deferred function.

// The single argument isn't actually used - it just has its address
// taken so it can be matched against pending defers.
#pragma textflag NOSPLIT
void
runtime·deferreturn(uintptr arg0)
{
	Defer *d;
	byte *argp;
	FuncVal *fn;

	d = g->defer;
	if(d == nil)
		return;
	argp = (byte*)&arg0;
	if(d->argp != argp)
		return;

	// Moving arguments around.
	// Do not allow preemption here, because the garbage collector
	// won't know the form of the arguments until the jmpdefer can
	// flip the PC over to fn.
	m->locks++;
	runtime·memmove(argp, d->args, d->siz);
	fn = d->fn;
	g->defer = d->link;
	freedefer(d);
	m->locks--;
	if(m->locks == 0 && g->preempt)
		g->stackguard0 = StackPreempt;
	runtime·jmpdefer(fn, argp);
}

// Ensure that defer arg sizes that map to the same defer size class
// also map to the same malloc size class.
void
runtime·testdefersizes(void)
{
	P *p;
	int32 i, siz, defersc, mallocsc;
	int32 map[nelem(p->deferpool)];

	for(i=0; i<nelem(p->deferpool); i++)
		map[i] = -1;
	for(i=0;; i++) {
		defersc = DEFERCLASS(i);
		if(defersc >= nelem(p->deferpool))
			break;
		siz = TOTALSIZE(i);
		mallocsc = runtime·SizeToClass(siz);
		siz = runtime·class_to_size[mallocsc];
		// runtime·printf("defer class %d: arg size %d, block size %d(%d)\n", defersc, i, siz, mallocsc);
		if(map[defersc] < 0) {
			map[defersc] = mallocsc;
			continue;
		}
		if(map[defersc] != mallocsc) {
			runtime·printf("bad defer size class: i=%d siz=%d mallocsc=%d/%d\n",
				i, siz, map[defersc], mallocsc);
			runtime·throw("bad defer size class");
		}
	}
}

// Run all deferred functions for the current goroutine.
static void
rundefer(void)
{
	Defer *d;

	while((d = g->defer) != nil) {
		g->defer = d->link;
		reflect·call(d->fn, (byte*)d->args, d->siz);
		freedefer(d);
	}
}

// Print all currently active panics.  Used when crashing.
static void
printpanics(Panic *p)
{
	if(p->link) {
		printpanics(p->link);
		runtime·printf("\t");
	}
	runtime·printf("panic: ");
	runtime·printany(p->arg);
	if(p->recovered)
		runtime·printf(" [recovered]");
	runtime·printf("\n");
}

static void recovery(G*);

// The implementation of the predeclared function panic.
void
runtime·panic(Eface e)
{
	Defer *d;
	Panic p;
	void *pc, *argp;

	runtime·memclr((byte*)&p, sizeof p);
	p.arg = e;
	p.link = g->panic;
	p.stackbase = g->stackbase;
	g->panic = &p;

	for(;;) {
		d = g->defer;
		if(d == nil)
			break;
		// take defer off list in case of recursive panic
		g->defer = d->link;
		g->ispanic = true;	// rock for runtime·newstack, where runtime·newstackcall ends up
		argp = d->argp;
		pc = d->pc;
		runtime·newstackcall(d->fn, (byte*)d->args, d->siz);
		freedefer(d);
		if(p.recovered) {
			g->panic = p.link;
			if(g->panic == nil)	// must be done with signal
				g->sig = 0;
			// Pass information about recovering frame to recovery.
			g->sigcode0 = (uintptr)argp;
			g->sigcode1 = (uintptr)pc;
			runtime·mcall(recovery);
			runtime·throw("recovery failed"); // mcall should not return
		}
	}

	// ran out of deferred calls - old-school panic now
	runtime·startpanic();
	printpanics(g->panic);
	runtime·dopanic(0);	// should not return
	runtime·exit(1);	// not reached
}

// Unwind the stack after a deferred function calls recover
// after a panic.  Then arrange to continue running as though
// the caller of the deferred function returned normally.
static void
recovery(G *gp)
{
	void *argp;
	uintptr pc;
	
	// Info about defer passed in G struct.
	argp = (void*)gp->sigcode0;
	pc = (uintptr)gp->sigcode1;

	// Unwind to the stack frame with d's arguments in it.
	runtime·unwindstack(gp, argp);

	// Make the deferproc for this d return again,
	// this time returning 1.  The calling function will
	// jump to the standard return epilogue.
	// The -2*sizeof(uintptr) makes up for the
	// two extra words that are on the stack at
	// each call to deferproc.
	// (The pc we're returning to does pop pop
	// before it tests the return value.)
	// On the arm there are 2 saved LRs mixed in too.
	if(thechar == '5')
		gp->sched.sp = (uintptr)argp - 4*sizeof(uintptr);
	else
		gp->sched.sp = (uintptr)argp - 2*sizeof(uintptr);
	gp->sched.pc = pc;
	gp->sched.lr = 0;
	gp->sched.ret = 1;
	runtime·gogo(&gp->sched);
}

// Free stack frames until we hit the last one
// or until we find the one that contains the sp.
void
runtime·unwindstack(G *gp, byte *sp)
{
	Stktop *top;
	byte *stk;

	// Must be called from a different goroutine, usually m->g0.
	if(g == gp)
		runtime·throw("unwindstack on self");

	while((top = (Stktop*)gp->stackbase) != 0 && top->stackbase != 0) {
		stk = (byte*)gp->stackguard - StackGuard;
		if(stk <= sp && sp < (byte*)gp->stackbase)
			break;
		gp->stackbase = top->stackbase;
		gp->stackguard = top->stackguard;
		gp->stackguard0 = gp->stackguard;
		if(top->free != 0) {
			gp->stacksize -= top->free;
			runtime·stackfree(stk, top->free);
		}
	}

	if(sp != nil && (sp < (byte*)gp->stackguard - StackGuard || (byte*)gp->stackbase < sp)) {
		runtime·printf("recover: %p not in [%p, %p]\n", sp, gp->stackguard - StackGuard, gp->stackbase);
		runtime·throw("bad unwindstack");
	}
}

// The implementation of the predeclared function recover.
// Cannot split the stack because it needs to reliably
// find the stack segment of its caller.
#pragma textflag NOSPLIT
void
runtime·recover(byte *argp, Eface ret)
{
	Panic *p;
	Stktop *top;

	// Must be an unrecovered panic in progress.
	// Must be on a stack segment created for a deferred call during a panic.
	// Must be at the top of that segment, meaning the deferred call itself
	// and not something it called. The top frame in the segment will have
	// argument pointer argp == top - top->argsize.
	// The subtraction of g->panicwrap allows wrapper functions that
	// do not count as official calls to adjust what we consider the top frame
	// while they are active on the stack. The linker emits adjustments of
	// g->panicwrap in the prologue and epilogue of functions marked as wrappers.
	top = (Stktop*)g->stackbase;
	p = g->panic;
	if(p != nil && !p->recovered && top->panic && argp == (byte*)top - top->argsize - g->panicwrap) {
		p->recovered = 1;
		ret = p->arg;
	} else {
		ret.type = nil;
		ret.data = nil;
	}
	FLUSH(&ret);
}

void
runtime·startpanic(void)
{
	if(runtime·mheap.cachealloc.size == 0) { // very early
		runtime·printf("runtime: panic before malloc heap initialized\n");
		m->mallocing = 1; // tell rest of panic not to try to malloc
	} else if(m->mcache == nil) // can happen if called from signal handler or throw
		m->mcache = runtime·allocmcache();
	switch(m->dying) {
	case 0:
		m->dying = 1;
		if(g != nil)
			g->writebuf = nil;
		runtime·xadd(&runtime·panicking, 1);
		runtime·lock(&paniclk);
		if(runtime·debug.schedtrace > 0 || runtime·debug.scheddetail > 0)
			runtime·schedtrace(true);
		runtime·freezetheworld();
		return;
	case 1:
		// Something failed while panicing, probably the print of the
		// argument to panic().  Just print a stack trace and exit.
		m->dying = 2;
		runtime·printf("panic during panic\n");
		runtime·dopanic(0);
		runtime·exit(3);
	case 2:
		// This is a genuine bug in the runtime, we couldn't even
		// print the stack trace successfully.
		m->dying = 3;
		runtime·printf("stack trace unavailable\n");
		runtime·exit(4);
	default:
		// Can't even print!  Just exit.
		runtime·exit(5);
	}
}

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

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

	if((t = runtime·gotraceback(&crash)) > 0){
		if(g != m->g0) {
			runtime·printf("\n");
			runtime·goroutineheader(g);
			runtime·traceback((uintptr)runtime·getcallerpc(&unused), (uintptr)runtime·getcallersp(&unused), 0, g);
		} else if(t >= 2 || m->throwing > 0) {
			runtime·printf("\nruntime stack:\n");
			runtime·traceback((uintptr)runtime·getcallerpc(&unused), (uintptr)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);
	}
	
	if(crash)
		runtime·crash();

	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)
{
	if(m->throwing == 0)
		m->throwing = 1;
	runtime·startpanic();
	runtime·printf("fatal error: %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->mallocing) {
		runtime·printf("panic: %s\n", s);
		runtime·throw("panic during malloc");
	}
	if(m->gcing) {
		runtime·printf("panic: %s\n", s);
		runtime·throw("panic during gc");
	}
	runtime·newErrorCString(s, &err);
	runtime·panic(err);
}

void
runtime·Goexit(void)
{
	rundefer();
	runtime·goexit();
}

void
runtime·panicdivide(void)
{
	runtime·panicstring("integer divide by zero");
}
