mirror of https://github.com/go-python/gopy.git
all: first stab at no-cgo-ptr
This commit is contained in:
parent
7cb9dcd10f
commit
9240dfc24a
|
@ -122,9 +122,8 @@ class _cffi_helper(object):
|
|||
|
||||
@staticmethod
|
||||
def cffi_cgopy_cnv_c2py_string(c):
|
||||
s = _cffi_helper.lib._cgopy_CString(c)
|
||||
pystr = ffi.string(s)
|
||||
_cffi_helper.lib._cgopy_FreeCString(s)
|
||||
pystr = ffi.string(c)
|
||||
_cffi_helper.lib._cgopy_FreeCString(c)
|
||||
if _PY3:
|
||||
pystr = pystr.decode('utf8')
|
||||
return pystr
|
||||
|
|
|
@ -239,10 +239,10 @@ func (g *cffiGen) genCdefStructMemberSetter(s Struct, i int, f types.Object) {
|
|||
|
||||
// genCdefStructTPStr generates C definitions of str method for a Go struct.
|
||||
func (g *cffiGen) genCdefStructTPStr(s Struct) {
|
||||
g.wrapper.Printf("extern GoString cgo_func_%[1]s_str(void* p0);\n", s.sym.id)
|
||||
g.wrapper.Printf("extern const char* cgo_func_%[1]s_str(void* p0);\n", s.sym.id)
|
||||
}
|
||||
|
||||
// genCdefTypeTPStr generates C definitions of str method for a Go type.
|
||||
func (g *cffiGen) genCdefTypeTPStr(sym *symbol) {
|
||||
g.wrapper.Printf("extern GoString cgo_func_%[1]s_str(%[2]s p0);\n", sym.id, sym.cgoname)
|
||||
g.wrapper.Printf("extern const char* cgo_func_%[1]s_str(%[2]s p0);\n", sym.id, sym.cgoname)
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ func (g *cffiGen) genStructConversion(s Struct) {
|
|||
g.wrapper.Printf("def cffi_cgopy_cnv_c2py_%[1]s_%[2]s(c):\n", s.Package().Name(), s.GoName())
|
||||
g.wrapper.Indent()
|
||||
g.wrapper.Printf("o = %[1]s()\n", s.GoName())
|
||||
g.wrapper.Printf("o.cgopy = ffi.gc(c, _cffi_helper.lib.cgopy_decref)\n")
|
||||
//g.wrapper.Printf("o.cgopy = ffi.gc(c, _cffi_helper.lib.cgopy_decref)\n")
|
||||
g.wrapper.Printf("return o\n\n")
|
||||
g.wrapper.Outdent()
|
||||
}
|
||||
|
|
142
bind/gengo.go
142
bind/gengo.go
|
@ -20,26 +20,27 @@ const (
|
|||
checkGoVersion = "_cgopy_CheckGoVersion()"
|
||||
checkGoVersionDef = `
|
||||
func _cgopy_CheckGoVersion() {
|
||||
godebug := os.Getenv("GODEBUG")
|
||||
cgocheck := -1
|
||||
var err error
|
||||
if godebug != "" {
|
||||
const prefix = "cgocheck="
|
||||
for _, option := range strings.Split(godebug, ",") {
|
||||
if !strings.HasPrefix(option, prefix) {
|
||||
continue
|
||||
}
|
||||
cgocheck, err = strconv.Atoi(option[len(prefix):])
|
||||
if err != nil {
|
||||
cgocheck = -1
|
||||
fmt.Fprintf(os.Stderr, "gopy: invalid cgocheck value %q (expected an integer)\n", option)
|
||||
}
|
||||
}
|
||||
}
|
||||
godebug := os.Getenv("GODEBUG")
|
||||
cgocheck := -1
|
||||
var err error
|
||||
|
||||
if cgocheck != 0 {
|
||||
fmt.Fprintf(os.Stderr, "gopy: GODEBUG=cgocheck=0 should be set for Go>=1.6\n")
|
||||
}
|
||||
if godebug != "" {
|
||||
const prefix = "cgocheck="
|
||||
for _, option := range strings.Split(godebug, ",") {
|
||||
if !strings.HasPrefix(option, prefix) {
|
||||
continue
|
||||
}
|
||||
cgocheck, err = strconv.Atoi(option[len(prefix):])
|
||||
if err != nil {
|
||||
cgocheck = -1
|
||||
fmt.Fprintf(os.Stderr, "gopy: invalid cgocheck value %q (expected an integer)\n", option)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if cgocheck != 0 {
|
||||
fmt.Fprintf(os.Stderr, "gopy: GODEBUG=cgocheck=0 should be set for Go>=1.6\n")
|
||||
}
|
||||
}
|
||||
`
|
||||
goPreamble = `// Package main is an autogenerated binder stub for package %[1]s.
|
||||
|
@ -158,6 +159,28 @@ func cgopy_decref(ptr unsafe.Pointer) {
|
|||
refs.Unlock()
|
||||
}
|
||||
|
||||
//export cgopy_get_ptr
|
||||
func cgopy_get_ptr(id int32) unsafe.Pointer {
|
||||
refs.Lock()
|
||||
cobj, ok := refs.ptrs[id]
|
||||
refs.Unlock()
|
||||
if !ok {
|
||||
panic(fmt.Errorf("cgopy: unknown id %%d", id))
|
||||
}
|
||||
return cobj.ptr
|
||||
}
|
||||
|
||||
//export cgopy_get_id
|
||||
func cgopy_get_id(ptr unsafe.Pointer) int32 {
|
||||
refs.Lock()
|
||||
id, ok := refs.refs[ptr]
|
||||
refs.Unlock()
|
||||
if !ok {
|
||||
panic(fmt.Errorf("cgopy: unknown ptr %%+x", ptr))
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
%[5]s
|
||||
|
||||
func init() {
|
||||
|
@ -287,7 +310,7 @@ func (g *goGen) genFuncBody(f Func) {
|
|||
head := arg.Name()
|
||||
if arg.needWrap() {
|
||||
head = fmt.Sprintf(
|
||||
"*(*%s)(unsafe.Pointer(%s))",
|
||||
"*(*%s)(cgopy_get_ptr(int32(%s)))",
|
||||
types.TypeString(
|
||||
arg.GoType(),
|
||||
func(*types.Package) string { return g.pkg.Name() },
|
||||
|
@ -319,11 +342,11 @@ func (g *goGen) genFuncBody(f Func) {
|
|||
// g.Printf("")
|
||||
// }
|
||||
if res.needWrap() {
|
||||
g.Printf("%s(unsafe.Pointer(&", res.sym.cgoname)
|
||||
g.Printf("%s(cgopy_get_id(unsafe.Pointer(&", res.sym.cgoname)
|
||||
}
|
||||
g.Printf("_gopy_%03d", i)
|
||||
if res.needWrap() {
|
||||
g.Printf("))")
|
||||
g.Printf(")))")
|
||||
}
|
||||
}
|
||||
g.Printf("\n")
|
||||
|
@ -335,7 +358,7 @@ func (g *goGen) genStruct(s Struct) {
|
|||
g.Printf("\n// --- wrapping %s ---\n\n", s.sym.gofmt())
|
||||
g.Printf("//export %[1]s\n", s.sym.cgoname)
|
||||
g.Printf("// %[1]s wraps %[2]s\n", s.sym.cgoname, s.sym.gofmt())
|
||||
g.Printf("type %[1]s unsafe.Pointer\n\n", s.sym.cgoname)
|
||||
g.Printf("type %[1]s int32\n\n", s.sym.cgoname)
|
||||
|
||||
for i := 0; i < typ.NumFields(); i++ {
|
||||
f := typ.Field(i)
|
||||
|
@ -349,7 +372,7 @@ func (g *goGen) genStruct(s Struct) {
|
|||
if needWrapType(ft) {
|
||||
ftname = fmt.Sprintf("cgo_type_%[1]s_field_%d", s.ID(), i+1)
|
||||
g.Printf("//export %s\n", ftname)
|
||||
g.Printf("type %s unsafe.Pointer\n\n", ftname)
|
||||
g.Printf("type %s int32\n\n", ftname)
|
||||
}
|
||||
|
||||
// -- getter --
|
||||
|
@ -361,13 +384,14 @@ func (g *goGen) genStruct(s Struct) {
|
|||
)
|
||||
g.Indent()
|
||||
g.Printf(
|
||||
"ret := (*%[1]s)(unsafe.Pointer(self))\n",
|
||||
"ret := (*%[1]s)(cgopy_get_ptr(self))\n",
|
||||
s.sym.gofmt(),
|
||||
)
|
||||
|
||||
if !fsym.isBasic() {
|
||||
g.Printf("cgopy_incref(unsafe.Pointer(&ret.%s))\n", f.Name())
|
||||
g.Printf("return %s(unsafe.Pointer(&ret.%s))\n", ftname, f.Name())
|
||||
g.Printf("ptr := unsafe.Pointer(&ret.%s)\n", f.Name())
|
||||
g.Printf("cgopy_incref(ptr)\n")
|
||||
g.Printf("return %s(cgopy_get_id(ptr))\n", ftname)
|
||||
} else {
|
||||
g.Printf("return ret.%s\n", f.Name())
|
||||
}
|
||||
|
@ -382,10 +406,10 @@ func (g *goGen) genStruct(s Struct) {
|
|||
g.Indent()
|
||||
fset := "v"
|
||||
if !fsym.isBasic() {
|
||||
fset = fmt.Sprintf("*(*%s)(unsafe.Pointer(v))", fsym.gofmt())
|
||||
fset = fmt.Sprintf("*(*%s)(cgopy_get_ptr(v))", fsym.gofmt())
|
||||
}
|
||||
g.Printf(
|
||||
"(*%[1]s)(unsafe.Pointer(self)).%[2]s = %[3]s\n",
|
||||
"(*%[1]s)(cgopy_get_ptr(int32(self))).%[2]s = %[3]s\n",
|
||||
s.sym.gofmt(),
|
||||
f.Name(),
|
||||
fset,
|
||||
|
@ -402,8 +426,9 @@ func (g *goGen) genStruct(s Struct) {
|
|||
g.Printf("func cgo_func_%[1]s_new() cgo_type_%[1]s {\n", s.ID())
|
||||
g.Indent()
|
||||
g.Printf("o := %[1]s{}\n", s.sym.gofmt())
|
||||
g.Printf("cgopy_incref(unsafe.Pointer(&o))\n")
|
||||
g.Printf("return (cgo_type_%[1]s)(unsafe.Pointer(&o))\n", s.ID())
|
||||
g.Printf("ptr := unsafe.Pointer(&o)\n")
|
||||
g.Printf("cgopy_incref(ptr)\n")
|
||||
g.Printf("return cgo_type_%[1]s(cgopy_get_id(ptr))\n", s.ID())
|
||||
g.Outdent()
|
||||
g.Printf("}\n\n")
|
||||
|
||||
|
@ -418,7 +443,7 @@ func (g *goGen) genStruct(s Struct) {
|
|||
if s.sym.isBasic() {
|
||||
g.Printf("%[1]s(self)\n", s.sym.gofmt())
|
||||
} else {
|
||||
g.Printf("*(*%[1]s)(unsafe.Pointer(self))\n", s.sym.gofmt())
|
||||
g.Printf("*(*%[1]s)(cgopy_get_ptr(int32(self)))\n", s.sym.gofmt())
|
||||
}
|
||||
g.Printf("return v\n")
|
||||
g.Outdent()
|
||||
|
@ -427,16 +452,16 @@ func (g *goGen) genStruct(s Struct) {
|
|||
// support for __str__
|
||||
g.Printf("//export cgo_func_%[1]s_str\n", s.ID())
|
||||
g.Printf(
|
||||
"func cgo_func_%[1]s_str(self %[2]s) string {\n",
|
||||
"func cgo_func_%[1]s_str(self %[2]s) *C.char {\n",
|
||||
s.ID(),
|
||||
s.sym.cgoname,
|
||||
)
|
||||
g.Indent()
|
||||
if (s.prots & ProtoStringer) == 0 {
|
||||
g.Printf("return fmt.Sprintf(\"%%#v\", ")
|
||||
g.Printf("*(*%[1]s)(unsafe.Pointer(self)))\n", s.sym.gofmt())
|
||||
g.Printf("return C.CString(fmt.Sprintf(\"%%#v\", ")
|
||||
g.Printf("*(*%[1]s)(cgopy_get_ptr(int32(self)))))\n", s.sym.gofmt())
|
||||
} else {
|
||||
g.Printf("return (*%[1]s)(unsafe.Pointer(self)).String()\n",
|
||||
g.Printf("return C.CString((*%[1]s)(cgopy_get_ptr(int32(self))).String())\n",
|
||||
s.sym.gofmt(),
|
||||
)
|
||||
}
|
||||
|
@ -478,7 +503,7 @@ func (g *goGen) genMethodBody(s Struct, m Func) {
|
|||
g.Printf(" := ")
|
||||
}
|
||||
|
||||
g.Printf("(*%s)(unsafe.Pointer(self)).%s(",
|
||||
g.Printf("(*%s)(cgopy_get_ptr(int32(self))).%s(",
|
||||
s.sym.gofmt(),
|
||||
m.GoName(),
|
||||
)
|
||||
|
@ -490,7 +515,7 @@ func (g *goGen) genMethodBody(s Struct, m Func) {
|
|||
tail = ", "
|
||||
}
|
||||
if arg.sym.isStruct() {
|
||||
g.Printf("*(*%s)(unsafe.Pointer(%s))%s", arg.sym.gofmt(), arg.Name(), tail)
|
||||
g.Printf("*(*%s)(cgopy_get_ptr(int32(%s)))%s", arg.sym.gofmt(), arg.Name(), tail)
|
||||
} else {
|
||||
g.Printf("%s%s", arg.Name(), tail)
|
||||
}
|
||||
|
@ -517,11 +542,11 @@ func (g *goGen) genMethodBody(s Struct, m Func) {
|
|||
// g.Printf("")
|
||||
// }
|
||||
if res.needWrap() {
|
||||
g.Printf("%s(unsafe.Pointer(&", res.sym.cgoname)
|
||||
g.Printf("%s(cgopy_get_id(unsafe.Pointer(&", res.sym.cgoname)
|
||||
}
|
||||
g.Printf("_gopy_%03d", i)
|
||||
if res.needWrap() {
|
||||
g.Printf("))")
|
||||
g.Printf(")))")
|
||||
}
|
||||
}
|
||||
g.Printf("\n")
|
||||
|
@ -597,7 +622,7 @@ func (g *goGen) genType(sym *symbol) {
|
|||
btyp := sym.GoType().Underlying().String()
|
||||
g.Printf("type %[1]s %[2]s\n\n", sym.cgoname, btyp)
|
||||
} else {
|
||||
g.Printf("type %[1]s unsafe.Pointer\n\n", sym.cgoname)
|
||||
g.Printf("type %[1]s int32\n\n", sym.cgoname)
|
||||
}
|
||||
g.Printf("//export cgo_func_%[1]s_new\n", sym.id)
|
||||
g.Printf("func cgo_func_%[1]s_new() %[2]s {\n", sym.id, sym.cgoname)
|
||||
|
@ -606,8 +631,9 @@ func (g *goGen) genType(sym *symbol) {
|
|||
if sym.isBasic() {
|
||||
g.Printf("return %[1]s(o)\n", sym.cgoname)
|
||||
} else {
|
||||
g.Printf("cgopy_incref(unsafe.Pointer(&o))\n")
|
||||
g.Printf("return (%[1]s)(unsafe.Pointer(&o))\n", sym.cgoname)
|
||||
g.Printf("ptr := unsafe.Pointer(&o)\n")
|
||||
g.Printf("cgopy_incref(ptr)\n")
|
||||
g.Printf("return %[1]s(cgopy_get_id(ptr))\n", sym.cgoname)
|
||||
}
|
||||
g.Outdent()
|
||||
g.Printf("}\n\n")
|
||||
|
@ -623,7 +649,7 @@ func (g *goGen) genType(sym *symbol) {
|
|||
if sym.isBasic() {
|
||||
g.Printf("%[1]s(self)\n", sym.gofmt())
|
||||
} else {
|
||||
g.Printf("*(*%[1]s)(unsafe.Pointer(self))\n", sym.gofmt())
|
||||
g.Printf("*(*%[1]s)(cgopy_get_ptr(int32(self)))\n", sym.gofmt())
|
||||
}
|
||||
g.Printf("return v\n")
|
||||
g.Outdent()
|
||||
|
@ -632,16 +658,16 @@ func (g *goGen) genType(sym *symbol) {
|
|||
// support for __str__
|
||||
g.Printf("//export cgo_func_%[1]s_str\n", sym.id)
|
||||
g.Printf(
|
||||
"func cgo_func_%[1]s_str(self %[2]s) string {\n",
|
||||
"func cgo_func_%[1]s_str(self %[2]s) *C.char {\n",
|
||||
sym.id,
|
||||
sym.cgoname,
|
||||
)
|
||||
g.Indent()
|
||||
g.Printf("return fmt.Sprintf(\"%%#v\", ")
|
||||
g.Printf("return C.CString(fmt.Sprintf(\"%%#v\", ")
|
||||
if sym.isBasic() {
|
||||
g.Printf("%[1]s(self))\n", sym.gofmt())
|
||||
g.Printf("%[1]s(self)))\n", sym.gofmt())
|
||||
} else {
|
||||
g.Printf("*(*%[1]s)(unsafe.Pointer(self)))\n", sym.gofmt())
|
||||
g.Printf("*(*%[1]s)(cgopy_get_ptr(int32(self)))))\n", sym.gofmt())
|
||||
}
|
||||
g.Outdent()
|
||||
g.Printf("}\n\n")
|
||||
|
@ -681,11 +707,11 @@ func (g *goGen) genType(sym *symbol) {
|
|||
esym.cgotypename(),
|
||||
)
|
||||
g.Indent()
|
||||
g.Printf("arr := (*%[1]s)(unsafe.Pointer(self))\n", sym.gofmt())
|
||||
g.Printf("arr := (*%[1]s)(cgopy_get_ptr(self))\n", sym.gofmt())
|
||||
g.Printf("elt := (*arr)[i]\n")
|
||||
if !esym.isBasic() {
|
||||
g.Printf("cgopy_incref(unsafe.Pointer(&elt))\n")
|
||||
g.Printf("return (%[1]s)(unsafe.Pointer(&elt))\n", esym.cgotypename())
|
||||
g.Printf("return %[1]s(cgopy_get_id(unsafe.Pointer(&elt)))\n", esym.cgotypename())
|
||||
} else {
|
||||
if esym.isNamed() {
|
||||
g.Printf("return %[1]s(elt)\n", esym.cgotypename())
|
||||
|
@ -704,10 +730,10 @@ func (g *goGen) genType(sym *symbol) {
|
|||
esym.cgotypename(),
|
||||
)
|
||||
g.Indent()
|
||||
g.Printf("arr := (*%[1]s)(unsafe.Pointer(self))\n", sym.gofmt())
|
||||
g.Printf("arr := (*%[1]s)(cgopy_get_ptr(self))\n", sym.gofmt())
|
||||
g.Printf("(*arr)[i] = ")
|
||||
if !esym.isBasic() {
|
||||
g.Printf("*(*%[1]s)(unsafe.Pointer(v))\n", esym.gofmt())
|
||||
g.Printf("*(*%[1]s)(cgopy_get_ptr(v))\n", esym.gofmt())
|
||||
} else {
|
||||
if esym.isNamed() {
|
||||
g.Printf("%[1]s(v)\n", esym.gofmt())
|
||||
|
@ -736,10 +762,10 @@ func (g *goGen) genType(sym *symbol) {
|
|||
esym.cgotypename(),
|
||||
)
|
||||
g.Indent()
|
||||
g.Printf("slice := (*%[1]s)(unsafe.Pointer(self))\n", sym.gofmt())
|
||||
g.Printf("slice := (*%[1]s)(cgopy_get_ptr(self))\n", sym.gofmt())
|
||||
g.Printf("*slice = append(*slice, ")
|
||||
if !esym.isBasic() {
|
||||
g.Printf("*(*%[1]s)(unsafe.Pointer(v))", esym.gofmt())
|
||||
g.Printf("*(*%[1]s)(cgopy_get_ptr(v))", esym.gofmt())
|
||||
} else {
|
||||
if esym.isNamed() {
|
||||
g.Printf("%[1]s(v)", esym.gofmt())
|
||||
|
@ -1045,7 +1071,7 @@ func (g *goGen) genTypeMethods(sym *symbol) {
|
|||
msym.goname,
|
||||
)
|
||||
} else {
|
||||
g.Printf("(*%s)(unsafe.Pointer(self)).%s(",
|
||||
g.Printf("(*%s)(cgopy_get_ptr(int32(self))).%s(",
|
||||
sym.gofmt(),
|
||||
msym.goname,
|
||||
)
|
||||
|
@ -1058,7 +1084,7 @@ func (g *goGen) genTypeMethods(sym *symbol) {
|
|||
}
|
||||
sarg := g.pkg.syms.symtype(params.At(i).Type())
|
||||
if needWrapType(sarg.GoType()) {
|
||||
g.Printf("*(*%s)(unsafe.Pointer(arg%03d))",
|
||||
g.Printf("*(*%s)(cgopy_get_ptr(int32(arg%03d)))",
|
||||
sarg.gofmt(),
|
||||
i,
|
||||
)
|
||||
|
@ -1083,13 +1109,13 @@ func (g *goGen) genTypeMethods(sym *symbol) {
|
|||
sret := g.pkg.syms.symtype(res.At(i).Type())
|
||||
if needWrapType(sret.GoType()) {
|
||||
g.Printf(
|
||||
"%s(unsafe.Pointer(&",
|
||||
"%s(cgopy_get_id(unsafe.Pointer(&",
|
||||
sret.cgoname,
|
||||
)
|
||||
}
|
||||
g.Printf("res%03d", i)
|
||||
if needWrapType(sret.GoType()) {
|
||||
g.Printf("))")
|
||||
g.Printf(")))")
|
||||
}
|
||||
}
|
||||
g.Printf("\n")
|
||||
|
|
Loading…
Reference in New Issue