mirror of
https://github.com/golang/go
synced 2024-11-26 16:16:57 -07:00
runtime: add cgocallback_gofunc that can call Go func value
For now, all the callbacks from C use top-level Go functions, so they use the equivalent C function pointer, and will continue to do so. But perhaps some day this will be useful for calling a Go func value (at least if the type is already known). More importantly, the Windows callback code needs to be able to use cgocallback_gofunc to call a Go func value. Should fix the Windows build. R=ken2 CC=golang-dev https://golang.org/cl/7388049
This commit is contained in:
parent
96f57186ba
commit
3d2dfc5a7b
@ -498,8 +498,22 @@ TEXT runtime·asmcgocall(SB),7,$0
|
||||
RET
|
||||
|
||||
// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
|
||||
// See cgocall.c for more details.
|
||||
// Turn the fn into a Go func (by taking its address) and call
|
||||
// cgocallback_gofunc.
|
||||
TEXT runtime·cgocallback(SB),7,$12
|
||||
LEAL fn+0(FP), AX
|
||||
MOVL AX, 0(SP)
|
||||
MOVL frame+4(FP), AX
|
||||
MOVL AX, 4(SP)
|
||||
MOVL framesize+8(FP), AX
|
||||
MOVL AX, 8(SP)
|
||||
MOVL $runtime·cgocallback_gofunc(SB), AX
|
||||
CALL AX
|
||||
RET
|
||||
|
||||
// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
|
||||
// See cgocall.c for more details.
|
||||
TEXT runtime·cgocallback_gofunc(SB),7,$12
|
||||
// If m is nil, Go did not create the current thread.
|
||||
// Call needm to obtain one for temporary use.
|
||||
// In this case, we're running on the thread stack, so there's
|
||||
|
@ -531,8 +531,22 @@ TEXT runtime·asmcgocall(SB),7,$0
|
||||
RET
|
||||
|
||||
// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
|
||||
// See cgocall.c for more details.
|
||||
// Turn the fn into a Go func (by taking its address) and call
|
||||
// cgocallback_gofunc.
|
||||
TEXT runtime·cgocallback(SB),7,$24
|
||||
LEAQ fn+0(FP), AX
|
||||
MOVQ AX, 0(SP)
|
||||
MOVQ frame+8(FP), AX
|
||||
MOVQ AX, 8(SP)
|
||||
MOVQ framesize+16(FP), AX
|
||||
MOVQ AX, 16(SP)
|
||||
MOVQ $runtime·cgocallback_gofunc(SB), AX
|
||||
CALL AX
|
||||
RET
|
||||
|
||||
// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
|
||||
// See cgocall.c for more details.
|
||||
TEXT runtime·cgocallback_gofunc(SB),7,$24
|
||||
// If m is nil, Go did not create the current thread.
|
||||
// Call needm to obtain one for temporary use.
|
||||
// In this case, we're running on the thread stack, so there's
|
||||
|
@ -310,8 +310,22 @@ TEXT runtime·asmcgocall(SB),7,$0
|
||||
RET
|
||||
|
||||
// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
|
||||
// Turn the fn into a Go func (by taking its address) and call
|
||||
// cgocallback_gofunc.
|
||||
TEXT runtime·cgocallback(SB),7,$12
|
||||
MOVW $fn+0(FP), R0
|
||||
MOVW R0, 4(R13)
|
||||
MOVW frame+4(FP), R0
|
||||
MOVW R0, 8(R13)
|
||||
MOVW framesize+8(FP), R0
|
||||
MOVW R0, 12(R13)
|
||||
MOVL $runtime·cgocallback_gofunc(SB), R0
|
||||
BL (R0)
|
||||
RET
|
||||
|
||||
// cgocallback_gofunc(void (*fn)(void*), void *frame, uintptr framesize)
|
||||
// See cgocall.c for more details.
|
||||
TEXT runtime·cgocallback(SB),7,$16
|
||||
TEXT runtime·cgocallback_gofunc(SB),7,$16
|
||||
// Load m and g from thread-local storage.
|
||||
MOVW cgo_load_gm(SB), R0
|
||||
CMP $0, R0
|
||||
|
@ -80,7 +80,7 @@ runtime·compilecallback(Eface fn, bool cleanstack)
|
||||
|
||||
// MOVL fn, AX
|
||||
*p++ = 0xb8;
|
||||
*(uint32*)p = (uint32)(*(byte**)fn.data);
|
||||
*(uint32*)p = (uint32)(fn.data);
|
||||
p += 4;
|
||||
|
||||
// MOVL argsize, DX
|
||||
|
@ -78,7 +78,7 @@ runtime·compilecallback(Eface fn, bool /*cleanstack*/)
|
||||
// MOVQ fn, AX
|
||||
*p++ = 0x48;
|
||||
*p++ = 0xb8;
|
||||
*(uint64*)p = (uint64)(*(byte**)fn.data);
|
||||
*(uint64*)p = (uint64)(fn.data);
|
||||
p += 8;
|
||||
// PUSH AX
|
||||
*p++ = 0x50;
|
||||
|
@ -206,14 +206,12 @@ runtime·cfree(void *p)
|
||||
static FuncVal unwindmf = {unwindm};
|
||||
|
||||
void
|
||||
runtime·cgocallbackg(void (*fn)(void), void *arg, uintptr argsize)
|
||||
runtime·cgocallbackg(FuncVal *fn, void *arg, uintptr argsize)
|
||||
{
|
||||
Defer d;
|
||||
FuncVal fv;
|
||||
|
||||
fv.fn = fn;
|
||||
if(m->racecall) {
|
||||
reflect·call(&fv, arg, argsize);
|
||||
reflect·call(fn, arg, argsize);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -240,7 +238,7 @@ runtime·cgocallbackg(void (*fn)(void), void *arg, uintptr argsize)
|
||||
runtime·raceacquire(&cgosync);
|
||||
|
||||
// Invoke callback.
|
||||
reflect·call(&fv, arg, argsize);
|
||||
reflect·call(fn, arg, argsize);
|
||||
|
||||
if(raceenabled)
|
||||
runtime·racereleasemerge(&cgosync);
|
||||
|
@ -216,7 +216,7 @@ TEXT runtime·callbackasm+0(SB),7,$0
|
||||
|
||||
CLD
|
||||
|
||||
CALL runtime·cgocallback(SB)
|
||||
CALL runtime·cgocallback_gofunc(SB)
|
||||
|
||||
POPL AX
|
||||
POPL CX
|
||||
|
@ -272,13 +272,13 @@ TEXT runtime·callbackasm(SB),7,$0
|
||||
MOVQ R15, 0(SP)
|
||||
|
||||
// prepare call stack. use SUBQ to hide from stack frame checks
|
||||
// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
|
||||
// cgocallback(Go func, void *frame, uintptr framesize)
|
||||
SUBQ $24, SP
|
||||
MOVQ DX, 16(SP) // uintptr framesize
|
||||
MOVQ CX, 8(SP) // void *frame
|
||||
MOVQ AX, 0(SP) // void (*fn)(void*)
|
||||
MOVQ AX, 0(SP) // Go func
|
||||
CLD
|
||||
CALL runtime·cgocallback(SB)
|
||||
CALL runtime·cgocallback_gofunc(SB)
|
||||
MOVQ 0(SP), AX
|
||||
MOVQ 8(SP), CX
|
||||
MOVQ 16(SP), DX
|
||||
|
Loading…
Reference in New Issue
Block a user