// 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 "arch_GOARCH.h"
#include "stack.h"
#include "cgocall.h"

// Cgo call and callback support.
//
// To call into the C function f from Go, the cgo-generated code calls
// runtime.cgocall(_cgo_Cfunc_f, frame), where _cgo_Cfunc_f is a
// gcc-compiled function written by cgo.
//
// runtime.cgocall (below) locks g to m, calls entersyscall
// so as not to block other goroutines or the garbage collector,
// and then calls runtime.asmcgocall(_cgo_Cfunc_f, frame). 
//
// runtime.asmcgocall (in asm_$GOARCH.s) switches to the m->g0 stack
// (assumed to be an operating system-allocated stack, so safe to run
// gcc-compiled code on) and calls _cgo_Cfunc_f(frame).
//
// _cgo_Cfunc_f invokes the actual C function f with arguments
// taken from the frame structure, records the results in the frame,
// and returns to runtime.asmcgocall.
//
// After it regains control, runtime.asmcgocall switches back to the
// original g (m->curg)'s stack and returns to runtime.cgocall.
//
// After it regains control, runtime.cgocall calls exitsyscall, which blocks
// until this m can run Go code without violating the $GOMAXPROCS limit,
// and then unlocks g from m.
//
// The above description skipped over the possibility of the gcc-compiled
// function f calling back into Go.  If that happens, we continue down
// the rabbit hole during the execution of f.
//
// To make it possible for gcc-compiled C code to call a Go function p.GoF,
// cgo writes a gcc-compiled function named GoF (not p.GoF, since gcc doesn't
// know about packages).  The gcc-compiled C function f calls GoF.
//
// GoF calls crosscall2(_cgoexp_GoF, frame, framesize).  Crosscall2
// (in cgo/$GOOS.S, a gcc-compiled assembly file) is a two-argument
// adapter from the gcc function call ABI to the 6c function call ABI.
// It is called from gcc to call 6c functions.  In this case it calls
// _cgoexp_GoF(frame, framesize), still running on m->g0's stack
// and outside the $GOMAXPROCS limit.  Thus, this code cannot yet
// call arbitrary Go code directly and must be careful not to allocate
// memory or use up m->g0's stack.
//
// _cgoexp_GoF calls runtime.cgocallback(p.GoF, frame, framesize).
// (The reason for having _cgoexp_GoF instead of writing a crosscall3
// to make this call directly is that _cgoexp_GoF, because it is compiled
// with 6c instead of gcc, can refer to dotted names like
// runtime.cgocallback and p.GoF.)
//
// runtime.cgocallback (in asm_$GOARCH.s) switches from m->g0's
// stack to the original g (m->curg)'s stack, on which it calls
// runtime.cgocallbackg(p.GoF, frame, framesize).
// As part of the stack switch, runtime.cgocallback saves the current
// SP as m->g0->sched.sp, so that any use of m->g0's stack during the
// execution of the callback will be done below the existing stack frames.
// Before overwriting m->g0->sched.sp, it pushes the old value on the
// m->g0 stack, so that it can be restored later.
//
// runtime.cgocallbackg (below) is now running on a real goroutine
// stack (not an m->g0 stack).  First it calls runtime.exitsyscall, which will
// block until the $GOMAXPROCS limit allows running this goroutine.
// Once exitsyscall has returned, it is safe to do things like call the memory
// allocator or invoke the Go callback function p.GoF.  runtime.cgocallbackg
// first defers a function to unwind m->g0.sched.sp, so that if p.GoF
// panics, m->g0.sched.sp will be restored to its old value: the m->g0 stack
// and the m->curg stack will be unwound in lock step.
// Then it calls p.GoF.  Finally it pops but does not execute the deferred
// function, calls runtime.entersyscall, and returns to runtime.cgocallback.
//
// After it regains control, runtime.cgocallback switches back to
// m->g0's stack (the pointer is still in m->g0.sched.sp), restores the old
// m->g0.sched.sp value from the stack, and returns to _cgoexp_GoF.
//
// _cgoexp_GoF immediately returns to crosscall2, which restores the
// callee-save registers for gcc and returns to GoF, which returns to f.

void *initcgo;	/* filled in by dynamic linker when Cgo is available */

static void unlockm(void);
static void unwindm(void);

// Call from Go to C.

void
runtime·cgocall(void (*fn)(void*), void *arg)
{
	Defer d;

	if(!runtime·iscgo && !Windows)
		runtime·throw("cgocall unavailable");

	if(fn == 0)
		runtime·throw("cgocall nil");

	m->ncgocall++;

	/*
	 * Lock g to m to ensure we stay on the same stack if we do a
	 * cgo callback.
	 */
	d.nofree = false;
	if(m->lockedg == nil) {
		m->lockedg = g;
		g->lockedm = m;

		// Add entry to defer stack in case of panic.
		d.fn = (byte*)unlockm;
		d.siz = 0;
		d.link = g->defer;
		d.argp = (void*)-1;  // unused because unlockm never recovers
		d.nofree = true;
		g->defer = &d;
	}

	/*
	 * Announce we are entering a system call
	 * so that the scheduler knows to create another
	 * M to run goroutines while we are in the
	 * foreign code.
	 *
	 * The call to asmcgocall is guaranteed not to
	 * split the stack and does not allocate memory,
	 * so it is safe to call while "in a system call", outside
	 * the $GOMAXPROCS accounting.
	 */
	runtime·entersyscall();
	runtime·asmcgocall(fn, arg);
	runtime·exitsyscall();

	if(d.nofree) {
		if(g->defer != &d || d.fn != (byte*)unlockm)
			runtime·throw("runtime: bad defer entry in cgocallback");
		g->defer = d.link;
		unlockm();
	}
}

static void
unlockm(void)
{
	m->lockedg = nil;
	g->lockedm = nil;
}

void
runtime·NumCgoCall(int64 ret)
{
	M *m;

	ret = 0;
	for(m=runtime·atomicloadp(&runtime·allm); m; m=m->alllink)
		ret += m->ncgocall;
	FLUSH(&ret);
}

// Helper functions for cgo code.

void (*_cgo_malloc)(void*);
void (*_cgo_free)(void*);

void*
runtime·cmalloc(uintptr n)
{
	struct {
		uint64 n;
		void *ret;
	} a;

	a.n = n;
	a.ret = nil;
	runtime·cgocall(_cgo_malloc, &a);
	return a.ret;
}

void
runtime·cfree(void *p)
{
	runtime·cgocall(_cgo_free, p);
}

// Call from C back to Go.

void
runtime·cgocallbackg(void (*fn)(void), void *arg, uintptr argsize)
{
	Defer d;

	if(g != m->curg)
		runtime·throw("runtime: bad g in cgocallback");

	runtime·exitsyscall();	// coming out of cgo call

	// Add entry to defer stack in case of panic.
	d.fn = (byte*)unwindm;
	d.siz = 0;
	d.link = g->defer;
	d.argp = (void*)-1;  // unused because unwindm never recovers
	d.nofree = true;
	g->defer = &d;

	// Invoke callback.
	reflect·call((byte*)fn, arg, argsize);

	// Pop defer.
	// Do not unwind m->g0->sched.sp.
	// Our caller, cgocallback, will do that.
	if(g->defer != &d || d.fn != (byte*)unwindm)
		runtime·throw("runtime: bad defer entry in cgocallback");
	g->defer = d.link;

	runtime·entersyscall();	// going back to cgo call
}

static void
unwindm(void)
{
	// Restore sp saved by cgocallback during
	// unwind of g's stack (see comment at top of file).
	switch(thechar){
	default:
		runtime·throw("runtime: unwindm not implemented");
	case '8':
	case '6':
		m->g0->sched.sp = *(void**)m->g0->sched.sp;
		break;
	}
}

void
runtime·badcgocallback(void)	// called from assembly
{
	runtime·throw("runtime: misaligned stack in cgocallback");
}

void
runtime·cgounimpl(void)	// called from (incomplete) assembly
{
	runtime·throw("runtime: cgo not implemented");
}
