]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: add cgocallback_gofunc that can call Go func value
authorRuss Cox <rsc@golang.org>
Fri, 22 Feb 2013 21:08:56 +0000 (16:08 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 22 Feb 2013 21:08:56 +0000 (16:08 -0500)
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

src/pkg/runtime/asm_386.s
src/pkg/runtime/asm_amd64.s
src/pkg/runtime/asm_arm.s
src/pkg/runtime/callback_windows_386.c
src/pkg/runtime/callback_windows_amd64.c
src/pkg/runtime/cgocall.c
src/pkg/runtime/sys_windows_386.s
src/pkg/runtime/sys_windows_amd64.s

index 1e4727427811df56e3246b421551cadcb3477820..05b929f340cf6ba1d2eeb10cd7541874f848435f 100644 (file)
@@ -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
index ae8470708b457634dbc0085db2ca8fd473df220e..9591437eec747520210b70706da190f0616a8b0d 100644 (file)
@@ -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
index a10c91c654388e1139c55c97bc25ba4d34c69c30..35fb53733177d5a491714d58eb4fd4fb845f95f2 100644 (file)
@@ -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
index 159b8508e2be1500e2152863687b01d30b9056a9..880588da636f048f3663effb6ffecf661534eae9 100644 (file)
@@ -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
index 03a4cef136b347ebe94258055374e5cf3619e5b2..1a4779291520731146f9825e09d03953127bed36 100644 (file)
@@ -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;
index f89ac4684fd7950a0382ca865587683809e3fc23..7848437a2370ab184d8463f84820a7cb9030edd0 100644 (file)
@@ -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);
index dbc4352e2e9abadb8efa593b439f4c33c10e027b..a4ac7463a36a580393573a1af70dff688b84806e 100644 (file)
@@ -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
index 33ec33640bde21151ef12ac3ebf4e03aad97cc8f..fe88f3b7544ac975470b9f0f54cde0276d27384e 100644 (file)
@@ -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