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
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
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
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
// MOVL fn, AX
*p++ = 0xb8;
- *(uint32*)p = (uint32)(*(byte**)fn.data);
+ *(uint32*)p = (uint32)(fn.data);
p += 4;
// MOVL argsize, DX
// MOVQ fn, AX
*p++ = 0x48;
*p++ = 0xb8;
- *(uint64*)p = (uint64)(*(byte**)fn.data);
+ *(uint64*)p = (uint64)(fn.data);
p += 8;
// PUSH AX
*p++ = 0x50;
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;
}
runtime·raceacquire(&cgosync);
// Invoke callback.
- reflect·call(&fv, arg, argsize);
+ reflect·call(fn, arg, argsize);
if(raceenabled)
runtime·racereleasemerge(&cgosync);
CLD
- CALL runtime·cgocallback(SB)
+ CALL runtime·cgocallback_gofunc(SB)
POPL AX
POPL CX
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