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

// Code related to defer, panic and recover.

// TODO: remove once code is moved to Go
extern Defer* runtime·newdefer(int32 siz);
extern runtime·freedefer(Defer *d);

uint32 runtime·panicking;
static Mutex paniclk;

void
runtime·deferproc_m(void)
{
	int32 siz;
	FuncVal *fn;
	uintptr argp;
	uintptr callerpc;
	Defer *d;

	siz = g->m->scalararg[0];
	fn = g->m->ptrarg[0];
	argp = g->m->scalararg[1];
	callerpc = g->m->scalararg[2];
	g->m->ptrarg[0] = nil;
	g->m->scalararg[1] = 0;

	d = runtime·newdefer(siz);
	if(d->panic != nil)
		runtime·throw("deferproc: d->panic != nil after newdefer");
	d->fn = fn;
	d->pc = callerpc;
	d->argp = argp;
	runtime·memmove(d+1, (void*)argp, siz);
}

// 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.
void
runtime·recovery_m(G *gp)
{
	void *argp;
	uintptr pc;
	
	// Info about defer passed in G struct.
	argp = (void*)gp->sigcode0;
	pc = (uintptr)gp->sigcode1;

	// d's arguments need to be in the stack.
	if(argp != nil && ((uintptr)argp < gp->stack.lo || gp->stack.hi < (uintptr)argp)) {
		runtime·printf("recover: %p not in [%p, %p]\n", argp, gp->stack.lo, gp->stack.hi);
		runtime·throw("bad recovery");
	}

	// 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 and power there are 2 saved LRs mixed in too.
	if(thechar == '5' || thechar == '9')
		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);
}

void
runtime·startpanic_m(void)
{
	if(runtime·mheap.cachealloc.size == 0) { // very early
		runtime·printf("runtime: panic before malloc heap initialized\n");
		g->m->mallocing = 1; // tell rest of panic not to try to malloc
	} else if(g->m->mcache == nil) // can happen if called from signal handler or throw
		g->m->mcache = runtime·allocmcache();
	switch(g->m->dying) {
	case 0:
		g->m->dying = 1;
		if(g != nil) {
			g->writebuf.array = nil;
			g->writebuf.len = 0;
			g->writebuf.cap = 0;
		}
		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.
		g->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.
		g->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_m(void)
{
	G *gp;
	uintptr sp, pc;
	static bool didothers;
	bool crash;
	int32 t;

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

	if((t = runtime·gotraceback(&crash)) > 0){
		if(gp != gp->m->g0) {
			runtime·printf("\n");
			runtime·goroutineheader(gp);
			runtime·traceback(pc, sp, 0, gp);
		} else if(t >= 2 || g->m->throwing > 0) {
			runtime·printf("\nruntime stack:\n");
			runtime·traceback(pc, sp, 0, gp);
		}
		if(!didothers) {
			didothers = true;
			runtime·tracebackothers(gp);
		}
	}
	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 Mutex deadlock;
		runtime·lock(&deadlock);
		runtime·lock(&deadlock);
	}
	
	if(crash)
		runtime·crash();

	runtime·exit(2);
}

#pragma textflag NOSPLIT
bool
runtime·canpanic(G *gp)
{
	M *m;
	uint32 status;

	// Note that g is m->gsignal, different from gp.
	// Note also that g->m can change at preemption, so m can go stale
	// if this function ever makes a function call.
	m = g->m;

	// Is it okay for gp to panic instead of crashing the program?
	// Yes, as long as it is running Go code, not runtime code,
	// and not stuck in a system call.
	if(gp == nil || gp != m->curg)
		return false;
	if(m->locks-m->softfloat != 0 || m->mallocing != 0 || m->throwing != 0 || m->gcing != 0 || m->dying != 0)
		return false;
	status = runtime·readgstatus(gp);
	if((status&~Gscan) != Grunning || gp->syscallsp != 0)
		return false;
#ifdef GOOS_windows
	if(m->libcallsp != 0)
		return false;
#endif
	return true;
}
