diff --git a/src/pkg/runtime/asm_386.s b/src/pkg/runtime/asm_386.s index 1e47274278..05b929f340 100644 --- a/src/pkg/runtime/asm_386.s +++ b/src/pkg/runtime/asm_386.s @@ -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 diff --git a/src/pkg/runtime/asm_amd64.s b/src/pkg/runtime/asm_amd64.s index ae8470708b..9591437eec 100644 --- a/src/pkg/runtime/asm_amd64.s +++ b/src/pkg/runtime/asm_amd64.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 diff --git a/src/pkg/runtime/asm_arm.s b/src/pkg/runtime/asm_arm.s index a10c91c654..35fb537331 100644 --- a/src/pkg/runtime/asm_arm.s +++ b/src/pkg/runtime/asm_arm.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 diff --git a/src/pkg/runtime/callback_windows_386.c b/src/pkg/runtime/callback_windows_386.c index 159b8508e2..880588da63 100644 --- a/src/pkg/runtime/callback_windows_386.c +++ b/src/pkg/runtime/callback_windows_386.c @@ -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 diff --git a/src/pkg/runtime/callback_windows_amd64.c b/src/pkg/runtime/callback_windows_amd64.c index 03a4cef136..1a47792915 100644 --- a/src/pkg/runtime/callback_windows_amd64.c +++ b/src/pkg/runtime/callback_windows_amd64.c @@ -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; diff --git a/src/pkg/runtime/cgocall.c b/src/pkg/runtime/cgocall.c index f89ac4684f..7848437a23 100644 --- a/src/pkg/runtime/cgocall.c +++ b/src/pkg/runtime/cgocall.c @@ -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); diff --git a/src/pkg/runtime/sys_windows_386.s b/src/pkg/runtime/sys_windows_386.s index dbc4352e2e..a4ac7463a3 100644 --- a/src/pkg/runtime/sys_windows_386.s +++ b/src/pkg/runtime/sys_windows_386.s @@ -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 diff --git a/src/pkg/runtime/sys_windows_amd64.s b/src/pkg/runtime/sys_windows_amd64.s index 33ec33640b..fe88f3b754 100644 --- a/src/pkg/runtime/sys_windows_amd64.s +++ b/src/pkg/runtime/sys_windows_amd64.s @@ -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