diff options
Diffstat (limited to 'misc')
-rw-r--r-- | misc/cgo/test/callback.go | 45 | ||||
-rw-r--r-- | misc/cgo/test/callback_c.c | 16 | ||||
-rw-r--r-- | misc/cgo/test/cgo_test.go | 98 |
3 files changed, 111 insertions, 48 deletions
diff --git a/misc/cgo/test/callback.go b/misc/cgo/test/callback.go index a7f1a3ecd..44167e6e9 100644 --- a/misc/cgo/test/callback.go +++ b/misc/cgo/test/callback.go @@ -10,6 +10,9 @@ void callGoFoo(void); void callGoStackCheck(void); void callPanic(void); void callCgoAllocate(void); +int callGoReturnVal(void); +int returnAfterGrow(void); +int returnAfterGrowFromGo(void); */ import "C" @@ -212,6 +215,48 @@ func testAllocateFromC(t *testing.T) { C.callCgoAllocate() // crashes or exits on failure } +// Test that C code can return a value if it calls a Go function that +// causes a stack copy. +func testReturnAfterGrow(t *testing.T) { + // Use a new goroutine so that we get a small stack. + c := make(chan int) + go func() { + c <- int(C.returnAfterGrow()) + }() + if got, want := <-c, 123456; got != want { + t.Errorf("got %d want %d", got, want) + } +} + +// Test that we can return a value from Go->C->Go if the Go code +// causes a stack copy. +func testReturnAfterGrowFromGo(t *testing.T) { + // Use a new goroutine so that we get a small stack. + c := make(chan int) + go func() { + c <- int(C.returnAfterGrowFromGo()) + }() + if got, want := <-c, 129*128/2; got != want { + t.Errorf("got %d want %d", got, want) + } +} + +//export goReturnVal +func goReturnVal() (r C.int) { + // Force a stack copy. + var f func(int) int + f = func(i int) int { + var buf [256]byte + use(buf[:]) + if i == 0 { + return 0 + } + return i + f(i-1) + } + r = C.int(f(128)) + return +} + func testCallbackStack(t *testing.T) { // Make cgo call and callback with different amount of stack stack available. // We do not do any explicit checks, just ensure that it does not crash. diff --git a/misc/cgo/test/callback_c.c b/misc/cgo/test/callback_c.c index dcd4ddd4e..5bb642534 100644 --- a/misc/cgo/test/callback_c.c +++ b/misc/cgo/test/callback_c.c @@ -64,3 +64,19 @@ callGoStackCheck(void) extern void goStackCheck(void); goStackCheck(); } + +int +returnAfterGrow(void) +{ + extern int goReturnVal(void); + goReturnVal(); + return 123456; +} + +int +returnAfterGrowFromGo(void) +{ + extern int goReturnVal(void); + return goReturnVal(); +} + diff --git a/misc/cgo/test/cgo_test.go b/misc/cgo/test/cgo_test.go index 1d1abf729..fcfad8304 100644 --- a/misc/cgo/test/cgo_test.go +++ b/misc/cgo/test/cgo_test.go @@ -10,53 +10,55 @@ import "testing" // so that they can use cgo (import "C"). // These wrappers are here for gotest to find. -func TestAlign(t *testing.T) { testAlign(t) } -func TestConst(t *testing.T) { testConst(t) } -func TestEnum(t *testing.T) { testEnum(t) } -func TestAtol(t *testing.T) { testAtol(t) } -func TestErrno(t *testing.T) { testErrno(t) } -func TestMultipleAssign(t *testing.T) { testMultipleAssign(t) } -func TestUnsignedInt(t *testing.T) { testUnsignedInt(t) } -func TestCallback(t *testing.T) { testCallback(t) } -func TestCallbackGC(t *testing.T) { testCallbackGC(t) } -func TestCallbackPanic(t *testing.T) { testCallbackPanic(t) } -func TestCallbackPanicLoop(t *testing.T) { testCallbackPanicLoop(t) } -func TestCallbackPanicLocked(t *testing.T) { testCallbackPanicLocked(t) } -func TestPanicFromC(t *testing.T) { testPanicFromC(t) } -func TestAllocateFromC(t *testing.T) { testAllocateFromC(t) } -func TestZeroArgCallback(t *testing.T) { testZeroArgCallback(t) } -func TestBlocking(t *testing.T) { testBlocking(t) } -func Test1328(t *testing.T) { test1328(t) } -func TestParallelSleep(t *testing.T) { testParallelSleep(t) } -func TestSetEnv(t *testing.T) { testSetEnv(t) } -func TestHelpers(t *testing.T) { testHelpers(t) } -func TestLibgcc(t *testing.T) { testLibgcc(t) } -func Test1635(t *testing.T) { test1635(t) } -func TestPrintf(t *testing.T) { testPrintf(t) } -func Test4029(t *testing.T) { test4029(t) } -func TestBoolAlign(t *testing.T) { testBoolAlign(t) } -func Test3729(t *testing.T) { test3729(t) } -func Test3775(t *testing.T) { test3775(t) } -func TestCthread(t *testing.T) { testCthread(t) } -func TestCallbackCallers(t *testing.T) { testCallbackCallers(t) } -func Test5227(t *testing.T) { test5227(t) } -func TestCflags(t *testing.T) { testCflags(t) } -func Test5337(t *testing.T) { test5337(t) } -func Test5548(t *testing.T) { test5548(t) } -func Test5603(t *testing.T) { test5603(t) } -func Test6833(t *testing.T) { test6833(t) } -func Test3250(t *testing.T) { test3250(t) } -func TestCallbackStack(t *testing.T) { testCallbackStack(t) } -func TestFpVar(t *testing.T) { testFpVar(t) } -func Test4339(t *testing.T) { test4339(t) } -func Test6390(t *testing.T) { test6390(t) } -func Test5986(t *testing.T) { test5986(t) } -func Test7665(t *testing.T) { test7665(t) } -func TestNaming(t *testing.T) { testNaming(t) } -func Test7560(t *testing.T) { test7560(t) } -func Test5242(t *testing.T) { test5242(t) } -func Test8092(t *testing.T) { test8092(t) } -func Test7978(t *testing.T) { test7978(t) } -func Test8694(t *testing.T) { test8694(t) } +func TestAlign(t *testing.T) { testAlign(t) } +func TestConst(t *testing.T) { testConst(t) } +func TestEnum(t *testing.T) { testEnum(t) } +func TestAtol(t *testing.T) { testAtol(t) } +func TestErrno(t *testing.T) { testErrno(t) } +func TestMultipleAssign(t *testing.T) { testMultipleAssign(t) } +func TestUnsignedInt(t *testing.T) { testUnsignedInt(t) } +func TestCallback(t *testing.T) { testCallback(t) } +func TestCallbackGC(t *testing.T) { testCallbackGC(t) } +func TestCallbackPanic(t *testing.T) { testCallbackPanic(t) } +func TestCallbackPanicLoop(t *testing.T) { testCallbackPanicLoop(t) } +func TestCallbackPanicLocked(t *testing.T) { testCallbackPanicLocked(t) } +func TestPanicFromC(t *testing.T) { testPanicFromC(t) } +func TestAllocateFromC(t *testing.T) { testAllocateFromC(t) } +func TestZeroArgCallback(t *testing.T) { testZeroArgCallback(t) } +func TestBlocking(t *testing.T) { testBlocking(t) } +func Test1328(t *testing.T) { test1328(t) } +func TestParallelSleep(t *testing.T) { testParallelSleep(t) } +func TestSetEnv(t *testing.T) { testSetEnv(t) } +func TestHelpers(t *testing.T) { testHelpers(t) } +func TestLibgcc(t *testing.T) { testLibgcc(t) } +func Test1635(t *testing.T) { test1635(t) } +func TestPrintf(t *testing.T) { testPrintf(t) } +func Test4029(t *testing.T) { test4029(t) } +func TestBoolAlign(t *testing.T) { testBoolAlign(t) } +func Test3729(t *testing.T) { test3729(t) } +func Test3775(t *testing.T) { test3775(t) } +func TestCthread(t *testing.T) { testCthread(t) } +func TestCallbackCallers(t *testing.T) { testCallbackCallers(t) } +func Test5227(t *testing.T) { test5227(t) } +func TestCflags(t *testing.T) { testCflags(t) } +func Test5337(t *testing.T) { test5337(t) } +func Test5548(t *testing.T) { test5548(t) } +func Test5603(t *testing.T) { test5603(t) } +func Test6833(t *testing.T) { test6833(t) } +func Test3250(t *testing.T) { test3250(t) } +func TestCallbackStack(t *testing.T) { testCallbackStack(t) } +func TestFpVar(t *testing.T) { testFpVar(t) } +func Test4339(t *testing.T) { test4339(t) } +func Test6390(t *testing.T) { test6390(t) } +func Test5986(t *testing.T) { test5986(t) } +func Test7665(t *testing.T) { test7665(t) } +func TestNaming(t *testing.T) { testNaming(t) } +func Test7560(t *testing.T) { test7560(t) } +func Test5242(t *testing.T) { test5242(t) } +func Test8092(t *testing.T) { test8092(t) } +func Test7978(t *testing.T) { test7978(t) } +func Test8694(t *testing.T) { test8694(t) } +func TestReturnAfterGrow(t *testing.T) { testReturnAfterGrow(t) } +func TestReturnAfterGrowFromGo(t *testing.T) { testReturnAfterGrowFromGo(t) } func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) } |