Commit 3d2dfc5a authored by Russ Cox's avatar Russ Cox

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
parent 96f57186
...@@ -498,8 +498,22 @@ TEXT runtime·asmcgocall(SB),7,$0 ...@@ -498,8 +498,22 @@ TEXT runtime·asmcgocall(SB),7,$0
RET RET
// cgocallback(void (*fn)(void*), void *frame, uintptr framesize) // 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 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. // If m is nil, Go did not create the current thread.
// Call needm to obtain one for temporary use. // Call needm to obtain one for temporary use.
// In this case, we're running on the thread stack, so there's // In this case, we're running on the thread stack, so there's
......
...@@ -531,8 +531,22 @@ TEXT runtime·asmcgocall(SB),7,$0 ...@@ -531,8 +531,22 @@ TEXT runtime·asmcgocall(SB),7,$0
RET RET
// cgocallback(void (*fn)(void*), void *frame, uintptr framesize) // 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 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. // If m is nil, Go did not create the current thread.
// Call needm to obtain one for temporary use. // Call needm to obtain one for temporary use.
// In this case, we're running on the thread stack, so there's // In this case, we're running on the thread stack, so there's
......
...@@ -310,8 +310,22 @@ TEXT runtime·asmcgocall(SB),7,$0 ...@@ -310,8 +310,22 @@ TEXT runtime·asmcgocall(SB),7,$0
RET RET
// cgocallback(void (*fn)(void*), void *frame, uintptr framesize) // 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. // 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. // Load m and g from thread-local storage.
MOVW cgo_load_gm(SB), R0 MOVW cgo_load_gm(SB), R0
CMP $0, R0 CMP $0, R0
......
...@@ -80,7 +80,7 @@ runtime·compilecallback(Eface fn, bool cleanstack) ...@@ -80,7 +80,7 @@ runtime·compilecallback(Eface fn, bool cleanstack)
// MOVL fn, AX // MOVL fn, AX
*p++ = 0xb8; *p++ = 0xb8;
*(uint32*)p = (uint32)(*(byte**)fn.data); *(uint32*)p = (uint32)(fn.data);
p += 4; p += 4;
// MOVL argsize, DX // MOVL argsize, DX
......
...@@ -78,7 +78,7 @@ runtime·compilecallback(Eface fn, bool /*cleanstack*/) ...@@ -78,7 +78,7 @@ runtime·compilecallback(Eface fn, bool /*cleanstack*/)
// MOVQ fn, AX // MOVQ fn, AX
*p++ = 0x48; *p++ = 0x48;
*p++ = 0xb8; *p++ = 0xb8;
*(uint64*)p = (uint64)(*(byte**)fn.data); *(uint64*)p = (uint64)(fn.data);
p += 8; p += 8;
// PUSH AX // PUSH AX
*p++ = 0x50; *p++ = 0x50;
......
...@@ -206,14 +206,12 @@ runtime·cfree(void *p) ...@@ -206,14 +206,12 @@ runtime·cfree(void *p)
static FuncVal unwindmf = {unwindm}; static FuncVal unwindmf = {unwindm};
void void
runtime·cgocallbackg(void (*fn)(void), void *arg, uintptr argsize) runtime·cgocallbackg(FuncVal *fn, void *arg, uintptr argsize)
{ {
Defer d; Defer d;
FuncVal fv;
fv.fn = fn;
if(m->racecall) { if(m->racecall) {
reflect·call(&fv, arg, argsize); reflect·call(fn, arg, argsize);
return; return;
} }
...@@ -240,7 +238,7 @@ runtime·cgocallbackg(void (*fn)(void), void *arg, uintptr argsize) ...@@ -240,7 +238,7 @@ runtime·cgocallbackg(void (*fn)(void), void *arg, uintptr argsize)
runtime·raceacquire(&cgosync); runtime·raceacquire(&cgosync);
// Invoke callback. // Invoke callback.
reflect·call(&fv, arg, argsize); reflect·call(fn, arg, argsize);
if(raceenabled) if(raceenabled)
runtime·racereleasemerge(&cgosync); runtime·racereleasemerge(&cgosync);
......
...@@ -216,7 +216,7 @@ TEXT runtime·callbackasm+0(SB),7,$0 ...@@ -216,7 +216,7 @@ TEXT runtime·callbackasm+0(SB),7,$0
CLD CLD
CALL runtime·cgocallback(SB) CALL runtime·cgocallback_gofunc(SB)
POPL AX POPL AX
POPL CX POPL CX
......
...@@ -272,13 +272,13 @@ TEXT runtime·callbackasm(SB),7,$0 ...@@ -272,13 +272,13 @@ TEXT runtime·callbackasm(SB),7,$0
MOVQ R15, 0(SP) MOVQ R15, 0(SP)
// prepare call stack. use SUBQ to hide from stack frame checks // 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 SUBQ $24, SP
MOVQ DX, 16(SP) // uintptr framesize MOVQ DX, 16(SP) // uintptr framesize
MOVQ CX, 8(SP) // void *frame MOVQ CX, 8(SP) // void *frame
MOVQ AX, 0(SP) // void (*fn)(void*) MOVQ AX, 0(SP) // Go func
CLD CLD
CALL runtime·cgocallback(SB) CALL runtime·cgocallback_gofunc(SB)
MOVQ 0(SP), AX MOVQ 0(SP), AX
MOVQ 8(SP), CX MOVQ 8(SP), CX
MOVQ 16(SP), DX MOVQ 16(SP), DX
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment