mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/cgo: gccgo fixes
Don't require a full-scale callback for calls to the special prologue functions. Always use a simple wrapper function for C functions, so that we can handle static functions defined in the import "C" comment. Disable a test that relies on gc-specific function names. Fixes #5905. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/11406047
This commit is contained in:
parent
d7c99cdf9f
commit
d9d3debee5
2 changed files with 66 additions and 6 deletions
|
|
@ -143,6 +143,10 @@ func testBlocking(t *testing.T) {
|
||||||
// Test that the stack can be unwound through a call out and call back
|
// Test that the stack can be unwound through a call out and call back
|
||||||
// into Go.
|
// into Go.
|
||||||
func testCallbackCallers(t *testing.T) {
|
func testCallbackCallers(t *testing.T) {
|
||||||
|
if runtime.Compiler != "gc" {
|
||||||
|
// The exact function names are not going to be the same.
|
||||||
|
t.Skip("skipping for non-gc toolchain")
|
||||||
|
}
|
||||||
pc := make([]uintptr, 100)
|
pc := make([]uintptr, 100)
|
||||||
n := 0
|
n := 0
|
||||||
name := []string{
|
name := []string{
|
||||||
|
|
|
||||||
|
|
@ -321,6 +321,9 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
|
||||||
Type: gtype,
|
Type: gtype,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Builtins defined in the C prolog.
|
||||||
|
inProlog := name == "CString" || name == "GoString" || name == "GoStringN" || name == "GoBytes"
|
||||||
|
|
||||||
if *gccgo {
|
if *gccgo {
|
||||||
// Gccgo style hooks.
|
// Gccgo style hooks.
|
||||||
fmt.Fprint(fgo2, "\n")
|
fmt.Fprint(fgo2, "\n")
|
||||||
|
|
@ -334,8 +337,10 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
|
||||||
|
|
||||||
conf.Fprint(fgo2, fset, d)
|
conf.Fprint(fgo2, fset, d)
|
||||||
fmt.Fprint(fgo2, " {\n")
|
fmt.Fprint(fgo2, " {\n")
|
||||||
fmt.Fprint(fgo2, "\tdefer syscall.CgocallDone()\n")
|
if !inProlog {
|
||||||
fmt.Fprint(fgo2, "\tsyscall.Cgocall()\n")
|
fmt.Fprint(fgo2, "\tdefer syscall.CgocallDone()\n")
|
||||||
|
fmt.Fprint(fgo2, "\tsyscall.Cgocall()\n")
|
||||||
|
}
|
||||||
if n.AddError {
|
if n.AddError {
|
||||||
fmt.Fprint(fgo2, "\tsyscall.SetErrno(0)\n")
|
fmt.Fprint(fgo2, "\tsyscall.SetErrno(0)\n")
|
||||||
}
|
}
|
||||||
|
|
@ -366,7 +371,11 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
|
||||||
fmt.Fprint(fgo2, "}\n")
|
fmt.Fprint(fgo2, "}\n")
|
||||||
|
|
||||||
// declare the C function.
|
// declare the C function.
|
||||||
fmt.Fprintf(fgo2, "//extern %s\n", n.C)
|
if inProlog {
|
||||||
|
fmt.Fprintf(fgo2, "//extern %s\n", n.C)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(fgo2, "//extern _cgo%s%s\n", cPrefix, n.Mangle)
|
||||||
|
}
|
||||||
d.Name = ast.NewIdent(cname)
|
d.Name = ast.NewIdent(cname)
|
||||||
if n.AddError {
|
if n.AddError {
|
||||||
l := d.Type.Results.List
|
l := d.Type.Results.List
|
||||||
|
|
@ -380,8 +389,7 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
|
||||||
conf.Fprint(fgo2, fset, d)
|
conf.Fprint(fgo2, fset, d)
|
||||||
fmt.Fprint(fgo2, "\n")
|
fmt.Fprint(fgo2, "\n")
|
||||||
|
|
||||||
if name == "CString" || name == "GoString" || name == "GoStringN" || name == "GoBytes" {
|
if inProlog {
|
||||||
// The builtins are already defined in the C prolog.
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -469,7 +477,7 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
|
||||||
p.Written[name] = true
|
p.Written[name] = true
|
||||||
|
|
||||||
if *gccgo {
|
if *gccgo {
|
||||||
// we don't use wrappers with gccgo.
|
p.writeGccgoOutputFunc(fgcc, n)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -526,6 +534,54 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
|
||||||
fmt.Fprintf(fgcc, "\n")
|
fmt.Fprintf(fgcc, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write out a wrapper for a function when using gccgo. This is a
|
||||||
|
// simple wrapper that just calls the real function. We only need a
|
||||||
|
// wrapper to support static functions in the prologue--without a
|
||||||
|
// wrapper, we can't refer to the function, since the reference is in
|
||||||
|
// a different file.
|
||||||
|
func (p *Package) writeGccgoOutputFunc(fgcc *os.File, n *Name) {
|
||||||
|
if t := n.FuncType.Result; t != nil {
|
||||||
|
fmt.Fprintf(fgcc, "%s\n", t.C.String())
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(fgcc, "void\n")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fgcc, "_cgo%s%s(", cPrefix, n.Mangle)
|
||||||
|
for i, t := range n.FuncType.Params {
|
||||||
|
if i > 0 {
|
||||||
|
fmt.Fprintf(fgcc, ", ")
|
||||||
|
}
|
||||||
|
c := t.Typedef
|
||||||
|
if c == "" {
|
||||||
|
c = t.C.String()
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fgcc, "%s p%d", c, i)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fgcc, ")\n")
|
||||||
|
fmt.Fprintf(fgcc, "{\n")
|
||||||
|
fmt.Fprintf(fgcc, "\t")
|
||||||
|
if t := n.FuncType.Result; t != nil {
|
||||||
|
fmt.Fprintf(fgcc, "return ")
|
||||||
|
// Cast to void* to avoid warnings due to omitted qualifiers.
|
||||||
|
if c := t.C.String(); c[len(c)-1] == '*' {
|
||||||
|
fmt.Fprintf(fgcc, "(void*)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fgcc, "%s(", n.C)
|
||||||
|
for i, t := range n.FuncType.Params {
|
||||||
|
if i > 0 {
|
||||||
|
fmt.Fprintf(fgcc, ", ")
|
||||||
|
}
|
||||||
|
// Cast to void* to avoid warnings due to omitted qualifiers.
|
||||||
|
if c := t.C.String(); c[len(c)-1] == '*' {
|
||||||
|
fmt.Fprintf(fgcc, "(void*)")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fgcc, "p%d", i)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(fgcc, ");\n")
|
||||||
|
fmt.Fprintf(fgcc, "}\n")
|
||||||
|
fmt.Fprintf(fgcc, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
// Write out the various stubs we need to support functions exported
|
// Write out the various stubs we need to support functions exported
|
||||||
// from Go so that they are callable from C.
|
// from Go so that they are callable from C.
|
||||||
func (p *Package) writeExports(fgo2, fc, fm *os.File) {
|
func (p *Package) writeExports(fgo2, fc, fm *os.File) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue