diff options
Diffstat (limited to 'misc/cgo')
-rw-r--r-- | misc/cgo/gmp/gmp.go | 2 | ||||
-rw-r--r-- | misc/cgo/test/callback.go | 43 | ||||
-rw-r--r-- | misc/cgo/test/cflags.go | 32 | ||||
-rw-r--r-- | misc/cgo/test/cgo_test.go | 3 | ||||
-rw-r--r-- | misc/cgo/test/cthread.go | 6 | ||||
-rw-r--r-- | misc/cgo/test/issue4029.go | 9 | ||||
-rw-r--r-- | misc/cgo/test/issue5227.go | 38 | ||||
-rw-r--r-- | misc/cgo/testso/cgoso.c | 14 | ||||
-rw-r--r-- | misc/cgo/testso/cgoso.go | 2 | ||||
-rw-r--r-- | misc/cgo/testso/cgoso_c.c | 16 | ||||
-rw-r--r-- | misc/cgo/testso/test.bat | 18 | ||||
-rw-r--r-- | misc/cgo/testtls/tls.go | 28 | ||||
-rw-r--r-- | misc/cgo/testtls/tls_test.go | 13 | ||||
-rw-r--r-- | misc/cgo/testtls/tls_unix.c | 19 |
14 files changed, 232 insertions, 11 deletions
diff --git a/misc/cgo/gmp/gmp.go b/misc/cgo/gmp/gmp.go index 3bcf99151..7b7a9b3c9 100644 --- a/misc/cgo/gmp/gmp.go +++ b/misc/cgo/gmp/gmp.go @@ -33,7 +33,7 @@ field; unrepresentable fields are replaced with opaque byte arrays. A C union translates into a struct containing the first union member and perhaps additional padding. C arrays become Go arrays. C pointers become Go pointers. C function pointers become Go's uintptr. -C void pointer's become Go's unsafe.Pointer. +C void pointers become Go's unsafe.Pointer. For example, mpz_t is defined in <gmp.h> as: diff --git a/misc/cgo/test/callback.go b/misc/cgo/test/callback.go index 4f5d3f855..b6e2e3c1c 100644 --- a/misc/cgo/test/callback.go +++ b/misc/cgo/test/callback.go @@ -12,7 +12,9 @@ import "C" import ( "./backdoor" + "path" "runtime" + "strings" "testing" "unsafe" ) @@ -136,3 +138,44 @@ func testBlocking(t *testing.T) { } }) } + +// Test that the stack can be unwound through a call out and call back +// into Go. +func testCallbackCallers(t *testing.T) { + pc := make([]uintptr, 100) + n := 0 + name := []string{ + "test.goCallback", + "runtime.cgocallbackg", + "runtime.cgocallback_gofunc", + "return", + "runtime.cgocall", + "test._Cfunc_callback", + "test.nestedCall", + "test.testCallbackCallers", + "test.TestCallbackCallers", + "testing.tRunner", + "runtime.goexit", + } + nestedCall(func() { + n = runtime.Callers(2, pc) + }) + if n != len(name) { + t.Errorf("expected %d frames, got %d", len(name), n) + } + for i := 0; i < n; i++ { + f := runtime.FuncForPC(pc[i]) + if f == nil { + t.Fatalf("expected non-nil Func for pc %p", pc[i]) + } + fname := f.Name() + // Remove the prepended pathname from automatically + // generated cgo function names. + if strings.HasPrefix(fname, "_") { + fname = path.Base(f.Name()[1:]) + } + if fname != name[i] { + t.Errorf("expected function name %s, got %s", name[i], fname) + } + } +} diff --git a/misc/cgo/test/cflags.go b/misc/cgo/test/cflags.go new file mode 100644 index 000000000..24caab471 --- /dev/null +++ b/misc/cgo/test/cflags.go @@ -0,0 +1,32 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test that the #cgo CFLAGS directive works, +// with and without platform filters. +// See http://code.google.com/p/go/issues/detail?id=5224 for details. +package cgotest + +/* +#cgo CFLAGS: -DCOMMON_VALUE=123 +#cgo windows CFLAGS: -DIS_WINDOWS=1 +#cgo !windows CFLAGS: -DIS_WINDOWS=0 +int common = COMMON_VALUE; +int is_windows = IS_WINDOWS; +*/ +import "C" + +import ( + "runtime" + "testing" +) + +func testCflags(t *testing.T) { + is_windows := C.is_windows == 1 + if is_windows != (runtime.GOOS == "windows") { + t.Errorf("is_windows: %v, runtime.GOOS: %s", is_windows, runtime.GOOS) + } + if C.common != 123 { + t.Errorf("common: %v (expected 123)", C.common) + } +} diff --git a/misc/cgo/test/cgo_test.go b/misc/cgo/test/cgo_test.go index 536fa507a..56e1a0625 100644 --- a/misc/cgo/test/cgo_test.go +++ b/misc/cgo/test/cgo_test.go @@ -36,5 +36,8 @@ 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 BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) } diff --git a/misc/cgo/test/cthread.go b/misc/cgo/test/cthread.go index d918d033f..68d4a03ea 100644 --- a/misc/cgo/test/cthread.go +++ b/misc/cgo/test/cthread.go @@ -8,7 +8,6 @@ package cgotest import "C" import ( - "runtime" "sync" "testing" ) @@ -31,10 +30,7 @@ func Add(x int) { } func testCthread(t *testing.T) { - if runtime.GOARCH == "arm" { - t.Skip("testCthread disabled on arm") - } - + sum.i = 0 C.doAdd(10, 6) want := 10 * (10 - 1) / 2 * 6 diff --git a/misc/cgo/test/issue4029.go b/misc/cgo/test/issue4029.go index 7495d38fe..b0385eb85 100644 --- a/misc/cgo/test/issue4029.go +++ b/misc/cgo/test/issue4029.go @@ -47,14 +47,15 @@ func test4029(t *testing.T) { func loadThySelf(t *testing.T, symbol string) { this_process := C.dlopen(nil, C.RTLD_NOW) if this_process == nil { - t.Fatal("dlopen:", C.GoString(C.dlerror())) + t.Error("dlopen:", C.GoString(C.dlerror())) + return } defer C.dlclose(this_process) symbol_address := C.dlsym(this_process, C.CString(symbol)) if symbol_address == nil { - t.Fatal("dlsym:", C.GoString(C.dlerror())) - } else { - t.Log(symbol, symbol_address) + t.Error("dlsym:", C.GoString(C.dlerror())) + return } + t.Log(symbol, symbol_address) } diff --git a/misc/cgo/test/issue5227.go b/misc/cgo/test/issue5227.go new file mode 100644 index 000000000..336c4c609 --- /dev/null +++ b/misc/cgo/test/issue5227.go @@ -0,0 +1,38 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Issue 5227: linker incorrectly treats common symbols and +// leaves them undefined. + +package cgotest + +/* +typedef struct { + int Count; +} Fontinfo; + +Fontinfo SansTypeface; + +extern void init(); + +Fontinfo loadfont() { + Fontinfo f = {0}; + return f; +} + +void init() { + SansTypeface = loadfont(); +} +*/ +import "C" + +import "testing" + +func test5227(t *testing.T) { + C.init() +} + +func selectfont() C.Fontinfo { + return C.SansTypeface +} diff --git a/misc/cgo/testso/cgoso.c b/misc/cgo/testso/cgoso.c new file mode 100644 index 000000000..917f472d3 --- /dev/null +++ b/misc/cgo/testso/cgoso.c @@ -0,0 +1,14 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "_cgo_export.h" + +#ifdef WIN32 +extern void setCallback(void *); +void init() { + setCallback(goCallback); +} +#else +void init() {} +#endif diff --git a/misc/cgo/testso/cgoso.go b/misc/cgo/testso/cgoso.go index 44fb616c1..216cb1f05 100644 --- a/misc/cgo/testso/cgoso.go +++ b/misc/cgo/testso/cgoso.go @@ -6,11 +6,13 @@ package cgosotest /* #cgo LDFLAGS: -L. -lcgosotest +void init(void); void sofunc(void); */ import "C" func Test() { + C.init() C.sofunc() } diff --git a/misc/cgo/testso/cgoso_c.c b/misc/cgo/testso/cgoso_c.c index 8c15a6b9f..27155c27f 100644 --- a/misc/cgo/testso/cgoso_c.c +++ b/misc/cgo/testso/cgoso_c.c @@ -4,8 +4,22 @@ // +build ignore +#ifdef WIN32 +// A Windows DLL is unable to call an arbitrary function in +// the main executable. Work around that by making the main +// executable pass the callback function pointer to us. +void (*goCallback)(void); +__declspec(dllexport) void setCallback(void *f) +{ + goCallback = (void (*)())f; +} +__declspec(dllexport) void sofunc(void); +#else +extern void goCallback(void); +void setCallback(void *f) { (void)f; } +#endif + void sofunc(void) { - extern void goCallback(void); goCallback(); } diff --git a/misc/cgo/testso/test.bat b/misc/cgo/testso/test.bat new file mode 100644 index 000000000..b8cc3842b --- /dev/null +++ b/misc/cgo/testso/test.bat @@ -0,0 +1,18 @@ +:: Copyright 2013 The Go Authors. All rights reserved. +:: Use of this source code is governed by a BSD-style +:: license that can be found in the LICENSE file. + +@echo off + +gcc -c cgoso_c.c +gcc -shared -o libcgosotest.dll cgoso_c.o +if not exist libcgosotest.dll goto fail +go build main.go +if not exist main.exe goto fail +main.exe +goto :end + +:fail +set FAIL=1 +:end +del /F cgoso_c.o libcgosotest.dll main.exe 2>NUL diff --git a/misc/cgo/testtls/tls.go b/misc/cgo/testtls/tls.go new file mode 100644 index 000000000..a9546a61c --- /dev/null +++ b/misc/cgo/testtls/tls.go @@ -0,0 +1,28 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cgotlstest + +// #include <pthread.h> +// extern void setTLS(int); +// extern int getTLS(); +import "C" + +import ( + "runtime" + "testing" +) + +func testTLS(t *testing.T) { + var keyVal C.int = 1234 + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + C.setTLS(C.int(keyVal)) + storedVal := C.getTLS() + + if storedVal != keyVal { + t.Fatalf("stored %d want %d", storedVal, keyVal) + } +} diff --git a/misc/cgo/testtls/tls_test.go b/misc/cgo/testtls/tls_test.go new file mode 100644 index 000000000..3076c2d59 --- /dev/null +++ b/misc/cgo/testtls/tls_test.go @@ -0,0 +1,13 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !windows + +package cgotlstest + +import "testing" + +func TestTLS(t *testing.T) { + testTLS(t) +} diff --git a/misc/cgo/testtls/tls_unix.c b/misc/cgo/testtls/tls_unix.c new file mode 100644 index 000000000..545951631 --- /dev/null +++ b/misc/cgo/testtls/tls_unix.c @@ -0,0 +1,19 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include <pthread.h> + +static __thread int tls; + +void +setTLS(int v) +{ + tls = v; +} + +int +getTLS() +{ + return tls; +} |