From 9a166327fe03b013ec644f7be4795d744a64d5b5 Mon Sep 17 00:00:00 2001 From: Sebastien Binet Date: Tue, 1 Sep 2015 17:06:40 +0200 Subject: [PATCH] bind: handle all types as opaque pointers Change-Id: I06a021ced190401afd10cda9057238f4399cd60f --- bind/gencpy.go | 85 ++++++++---- bind/gencpy_func.go | 16 +-- bind/gencpy_struct.go | 18 +-- bind/gencpy_type.go | 11 +- bind/gengo.go | 306 ++++++++++++++++-------------------------- bind/symtab.go | 104 ++++++-------- bind/types.go | 33 ----- bind/vars.go | 5 - 8 files changed, 236 insertions(+), 342 deletions(-) diff --git a/bind/gencpy.go b/bind/gencpy.go index ce49438..f06bf6a 100644 --- a/bind/gencpy.go +++ b/bind/gencpy.go @@ -53,19 +53,43 @@ typedef struct _gopy_object gopy_object; // --- gopy object model --- +typedef GoUint8 *cgo_type_bool; +typedef GoUint8 *cgo_type_byte; + +typedef GoInt *cgo_type_int; +typedef GoInt8 *cgo_type_int8; +typedef GoInt16 *cgo_type_int16; +typedef GoInt32 *cgo_type_int32; +typedef GoInt64 *cgo_type_int64; + +typedef GoUint *cgo_type_uint; +typedef GoUint8 *cgo_type_uint8; +typedef GoUint16 *cgo_type_uint16; +typedef GoUint32 *cgo_type_uint32; +typedef GoUint64 *cgo_type_uint64; + +typedef GoFloat32 *cgo_type_float32; +typedef GoFloat64 *cgo_type_float64; +typedef GoComplex64 *cgo_type_complex64; +typedef GoComplex128 *cgo_type_complex128; + +typedef GoString *cgo_type_string; +typedef void *cgo_type_rune; /* FIXME */ + +typedef GoInterface *cgo_type_interface; // helpers for cgopy #define def_cnv(name, c2py, py2c, gotype) \ static int \ - cgopy_cnv_py2c_ ## name(PyObject *o, gotype *addr) { \ - *addr = py2c(o); \ + cgopy_cnv_py2c_ ## name(PyObject *o, cgo_type_ ## name *addr) { \ + **((gotype**)addr) = py2c(o); \ return 1; \ } \ \ static PyObject* \ - cgopy_cnv_c2py_ ## name(gotype *addr) { \ - return c2py(*addr); \ + cgopy_cnv_c2py_ ## name(cgo_type_ ## name *addr) { \ + return c2py(**((gotype**)addr)); \ } #if (GOINTBITS == 4) @@ -76,11 +100,12 @@ typedef struct _gopy_object gopy_object; def_cnv(uint, PyInt_FromLong, PyInt_AsLong, GoUint) #endif -def_cnv( int8, PyInt_FromLong, PyInt_AsLong, GoInt8) -def_cnv( int16, PyInt_FromLong, PyInt_AsLong, GoInt16) -def_cnv( int32, PyInt_FromLong, PyInt_AsLong, GoInt32) +def_cnv( int8, PyInt_FromLong, PyInt_AsLong, GoInt8) +def_cnv( int16, PyInt_FromLong, PyInt_AsLong, GoInt16) +def_cnv( int32, PyInt_FromLong, PyInt_AsLong, GoInt32) def_cnv( int64, PyLong_FromLong, PyLong_AsLong, GoInt64) -def_cnv(uint8, PyInt_FromLong, PyInt_AsLong, GoUint8) + +def_cnv( uint8, PyInt_FromLong, PyInt_AsLong, GoUint8) def_cnv(uint16, PyInt_FromLong, PyInt_AsLong, GoUint16) def_cnv(uint32, PyInt_FromLong, PyInt_AsLong, GoUint32) def_cnv(uint64, PyLong_FromUnsignedLong, PyLong_AsUnsignedLong, GoUint64) @@ -90,70 +115,72 @@ def_cnv(float64, PyFloat_FromDouble, PyFloat_AsDouble, GoFloat64) #undef def_cnv static int -cgopy_cnv_py2c_bool(PyObject *o, GoUint8 *addr) { - *addr = (o == Py_True) ? 1 : 0; +cgopy_cnv_py2c_bool(PyObject *o, cgo_type_bool *addr) { + **(GoUint8**)addr = (o == Py_True) ? 1 : 0; return 1; } static PyObject* -cgopy_cnv_c2py_bool(GoUint8 *addr) { - long v = *addr; +cgopy_cnv_c2py_bool(cgo_type_bool *addr) { + long v = **(GoUint8**)addr; return PyBool_FromLong(v); } static int -cgopy_cnv_py2c_string(PyObject *o, GoString *addr) { +cgopy_cnv_py2c_string(PyObject *o, cgo_type_string *addr) { const char *str = PyString_AsString(o); if (str == NULL) { return 0; } - *addr = _cgopy_GoString((char*)str); + **((GoString**)addr) = _cgopy_GoString((char*)str); return 1; } static PyObject* -cgopy_cnv_c2py_string(GoString *addr) { - const char *str = _cgopy_CString(*addr); +cgopy_cnv_c2py_string(cgo_type_string *addr) { + const char *str = _cgopy_CString(**(GoString**)addr); PyObject *pystr = PyString_FromString(str); free((void*)str); return pystr; } static int -cgopy_cnv_py2c_float32(PyObject *o, GoFloat32 *addr) { - GoFloat32 v = PyFloat_AsDouble(o); - *addr = v; +cgopy_cnv_py2c_float32(PyObject *o, cgo_type_float32 *addr) { + GoFloat64 v = PyFloat_AsDouble(o); + **(GoFloat32**)addr = v; return 1; } static PyObject* -cgopy_cnv_c2py_float32(GoFloat32 *addr) { - GoFloat64 v = *addr; +cgopy_cnv_c2py_float32(cgo_type_float32 *addr) { + GoFloat64 v = **(GoFloat32**)addr; return PyFloat_FromDouble(v); } static int -cgopy_cnv_py2c_complex64(PyObject *o, GoComplex64 *addr) { +cgopy_cnv_py2c_complex64(PyObject *o, cgo_type_complex64 *addr) { Py_complex v = PyComplex_AsCComplex(o); - *addr = v.real + v.imag * _Complex_I; + **(GoComplex64**)addr = v.real + v.imag * _Complex_I; return 1; } static PyObject* -cgopy_cnv_c2py_complex64(GoComplex64 *addr) { - return PyComplex_FromDoubles(creal(*addr), cimag(*addr)); +cgopy_cnv_c2py_complex64(cgo_type_complex64 *addr) { + GoComplex64 v = **(GoComplex64**)addr; + return PyComplex_FromDoubles(creal(v), cimag(v)); } static int -cgopy_cnv_py2c_complex128(PyObject *o, GoComplex128 *addr) { +cgopy_cnv_py2c_complex128(PyObject *o, cgo_type_complex128 *addr) { Py_complex v = PyComplex_AsCComplex(o); - *addr = v.real + v.imag * _Complex_I; + **(GoComplex128**)addr = v.real + v.imag * _Complex_I; return 1; } static PyObject* -cgopy_cnv_c2py_complex128(GoComplex128 *addr) { - return PyComplex_FromDoubles(creal(*addr), cimag(*addr)); +cgopy_cnv_c2py_complex128(cgo_type_complex128 *addr) { + GoComplex128 v = **(GoComplex128**)addr; + return PyComplex_FromDoubles(creal(v), cimag(v)); } ` ) diff --git a/bind/gencpy_func.go b/bind/gencpy_func.go index 9977a3c..e0e2600 100644 --- a/bind/gencpy_func.go +++ b/bind/gencpy_func.go @@ -150,9 +150,9 @@ func (g *cpyGen) _genFunc(sym *symbol, fsym *symbol) { if hasError(sig) { switch nres { case 1: - g.impl.Printf("if (!_cgopy_ErrorIsNil(ret)) {\n") + g.impl.Printf("if (!_cgopy_ErrorIsNil(*(GoInterface*)(ret))) {\n") g.impl.Indent() - g.impl.Printf("const char* c_err_str = _cgopy_ErrorString(ret);\n") + g.impl.Printf("const char* c_err_str = _cgopy_ErrorString(*(GoInterface*)(ret));\n") g.impl.Printf("PyErr_SetString(PyExc_RuntimeError, c_err_str);\n") g.impl.Printf("free((void*)c_err_str);\n") g.impl.Printf("return NULL;\n") @@ -164,9 +164,9 @@ func (g *cpyGen) _genFunc(sym *symbol, fsym *symbol) { return case 2: - g.impl.Printf("if (!_cgopy_ErrorIsNil(ret.r1)) {\n") + g.impl.Printf("if (!_cgopy_ErrorIsNil(*(GoInterface*)(ret.r1))) {\n") g.impl.Indent() - g.impl.Printf("const char* c_err_str = _cgopy_ErrorString(ret.r1);\n") + g.impl.Printf("const char* c_err_str = _cgopy_ErrorString(*(GoInterface*)(ret.r1));\n") g.impl.Printf("PyErr_SetString(PyExc_RuntimeError, c_err_str);\n") g.impl.Printf("free((void*)c_err_str);\n") g.impl.Printf("return NULL;\n") @@ -286,9 +286,9 @@ func (g *cpyGen) genFuncBody(f Func) { if f.err { switch len(res) { case 1: - g.impl.Printf("if (!_cgopy_ErrorIsNil(c_gopy_ret)) {\n") + g.impl.Printf("if (!_cgopy_ErrorIsNil(*(GoInterface*)(c_gopy_ret))) {\n") g.impl.Indent() - g.impl.Printf("const char* c_err_str = _cgopy_ErrorString(c_gopy_ret);\n") + g.impl.Printf("const char* c_err_str = _cgopy_ErrorString(*(GoInterface*)(c_gopy_ret));\n") g.impl.Printf("PyErr_SetString(PyExc_RuntimeError, c_err_str);\n") g.impl.Printf("free((void*)c_err_str);\n") g.impl.Printf("return NULL;\n") @@ -298,9 +298,9 @@ func (g *cpyGen) genFuncBody(f Func) { return case 2: - g.impl.Printf("if (!_cgopy_ErrorIsNil(c_gopy_ret.r1)) {\n") + g.impl.Printf("if (!_cgopy_ErrorIsNil(*(GoInterface*)(c_gopy_ret.r1))) {\n") g.impl.Indent() - g.impl.Printf("const char* c_err_str = _cgopy_ErrorString(c_gopy_ret.r1);\n") + g.impl.Printf("const char* c_err_str = _cgopy_ErrorString(*(GoInterface*)(c_gopy_ret.r1));\n") g.impl.Printf("PyErr_SetString(PyExc_RuntimeError, c_err_str);\n") g.impl.Printf("free((void*)c_err_str);\n") g.impl.Printf("return NULL;\n") diff --git a/bind/gencpy_struct.go b/bind/gencpy_struct.go index 7f591d9..8abcddf 100644 --- a/bind/gencpy_struct.go +++ b/bind/gencpy_struct.go @@ -263,14 +263,12 @@ func (g *cpyGen) genStructMemberGetter(cpy Struct, i int, f types.Object) { results = []*Var{ifield} ) - if needWrapType(ft) { - g.decl.Printf("\n/* wrapper for field %s.%s.%s */\n", - pkg.Name(), - cpy.GoName(), - f.Name(), - ) - g.decl.Printf("typedef void* %[1]s_field_%d;\n", cpy.sym.cgoname, i+1) - } + g.decl.Printf("\n/* wrapper for field %s.%s.%s */\n", + pkg.Name(), + cpy.GoName(), + f.Name(), + ) + g.decl.Printf("typedef void* %[1]s_field_%d;\n", cpy.sym.cgoname, i+1) g.decl.Printf("\n/* getter for %[1]s.%[2]s.%[3]s */\n", pkg.Name(), cpy.sym.goname, f.Name(), @@ -297,9 +295,7 @@ func (g *cpyGen) genStructMemberGetter(cpy Struct, i int, f types.Object) { g.impl.Printf("PyObject *o = NULL;\n") ftname := g.pkg.syms.symtype(ft).cgoname - if needWrapType(ft) { - ftname = fmt.Sprintf("%[1]s_field_%d", cpy.sym.cgoname, i+1) - } + ftname = fmt.Sprintf("%[1]s_field_%d", cpy.sym.cgoname, i+1) g.impl.Printf( "%[1]s c_ret = %[2]s(self->cgopy); /*wrap*/\n", ftname, diff --git a/bind/gencpy_type.go b/bind/gencpy_type.go index 83a45f2..7e088ee 100644 --- a/bind/gencpy_type.go +++ b/bind/gencpy_type.go @@ -324,7 +324,6 @@ func (g *cpyGen) genTypeInit(sym *symbol) { g.impl.Outdent() g.impl.Printf("}\n\n") // if-arg - case sym.isMap(): g.impl.Printf("if (arg != NULL) {\n") g.impl.Indent() @@ -449,7 +448,7 @@ func (g *cpyGen) genTypeTPStr(sym *symbol) { sym.cgoname, sym.cpyname, ) - g.impl.Printf("GoString str = cgo_func_%[1]s_str(c_self);\n", + g.impl.Printf("cgo_type_string str = cgo_func_%[1]s_str(c_self);\n", sym.id, ) g.impl.Printf("return cgopy_cnv_c2py_string(&str);\n") @@ -992,9 +991,9 @@ func (g *cpyGen) genTypeTPCall(sym *symbol) { if hasError(sig) { switch len(res) { case 1: - g.impl.Printf("if (!_cgopy_ErrorIsNil(c_gopy_ret)) {\n") + g.impl.Printf("if (!_cgopy_ErrorIsNil(*(GoInterface*)(c_gopy_ret))) {\n") g.impl.Indent() - g.impl.Printf("const char* c_err_str = _cgopy_ErrorString(c_gopy_ret);\n") + g.impl.Printf("const char* c_err_str = _cgopy_ErrorString(*(GoInterface*)(c_gopy_ret));\n") g.impl.Printf("PyErr_SetString(PyExc_RuntimeError, c_err_str);\n") g.impl.Printf("free((void*)c_err_str);\n") g.impl.Printf("return NULL;\n") @@ -1006,9 +1005,9 @@ func (g *cpyGen) genTypeTPCall(sym *symbol) { return case 2: - g.impl.Printf("if (!_cgopy_ErrorIsNil(c_gopy_ret.r1)) {\n") + g.impl.Printf("if (!_cgopy_ErrorIsNil(*(GoInterface*)(c_gopy_ret.r1))) {\n") g.impl.Indent() - g.impl.Printf("const char* c_err_str = _cgopy_ErrorString(c_gopy_ret.r1);\n") + g.impl.Printf("const char* c_err_str = _cgopy_ErrorString(*(GoInterface*)(c_gopy_ret.r1));\n") g.impl.Printf("PyErr_SetString(PyExc_RuntimeError, c_err_str);\n") g.impl.Printf("free((void*)c_err_str);\n") g.impl.Printf("return NULL;\n") diff --git a/bind/gengo.go b/bind/gengo.go index 29a4814..fc709d4 100644 --- a/bind/gengo.go +++ b/bind/gengo.go @@ -36,6 +36,12 @@ import ( var _ = unsafe.Pointer(nil) var _ = fmt.Sprintf +// --- begin cgo builtin types --- + +%[4]s + +// --- end cgo builtin types --- + // --- begin cgo helpers --- //export _cgopy_GoString @@ -235,17 +241,14 @@ func (g *goGen) genFuncBody(f Func) { if i+1 < len(args) { tail = ", " } - head := arg.Name() - if arg.needWrap() { - head = fmt.Sprintf( - "*(*%s)(unsafe.Pointer(%s))", - types.TypeString( - arg.GoType(), - func(*types.Package) string { return g.pkg.Name() }, - ), - arg.Name(), - ) - } + head := fmt.Sprintf( + "*(*%s)(unsafe.Pointer(%s))", + types.TypeString( + arg.GoType(), + func(*types.Package) string { return g.pkg.Name() }, + ), + arg.Name(), + ) g.Printf("%s%s", head, tail) } g.Printf(")\n") @@ -254,10 +257,7 @@ func (g *goGen) genFuncBody(f Func) { return } - for i, res := range results { - if !res.needWrap() { - continue - } + for i := range results { g.Printf("cgopy_incref(unsafe.Pointer(&_gopy_%03d))\n", i) } @@ -266,16 +266,7 @@ func (g *goGen) genFuncBody(f Func) { if i > 0 { g.Printf(", ") } - // if needWrap(res.GoType()) { - // g.Printf("") - // } - if res.needWrap() { - g.Printf("%s(unsafe.Pointer(&", res.sym.cgoname) - } - g.Printf("_gopy_%03d", i) - if res.needWrap() { - g.Printf("))") - } + g.Printf("%s(unsafe.Pointer(&_gopy_%03d))", res.sym.cgoname, i) } g.Printf("\n") } @@ -296,12 +287,9 @@ func (g *goGen) genStruct(s Struct) { ft := f.Type() fsym := g.pkg.syms.symtype(ft) - ftname := fsym.cgotypename() - 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) - } + 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) // -- getter -- @@ -316,12 +304,8 @@ func (g *goGen) genStruct(s Struct) { 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()) - } else { - g.Printf("return ret.%s\n", f.Name()) - } + g.Printf("cgopy_incref(unsafe.Pointer(&ret.%s))\n", f.Name()) + g.Printf("return %s(unsafe.Pointer(&ret.%s))\n", ftname, f.Name()) g.Outdent() g.Printf("}\n\n") @@ -332,9 +316,7 @@ 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)(unsafe.Pointer(v))", fsym.gofmt()) g.Printf( "(*%[1]s)(unsafe.Pointer(self)).%[2]s = %[3]s\n", s.sym.gofmt(), @@ -366,11 +348,7 @@ func (g *goGen) genStruct(s Struct) { ) g.Indent() g.Printf("var v interface{} = ") - 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)(unsafe.Pointer(self))\n", s.sym.gofmt()) g.Printf("return v\n") g.Outdent() g.Printf("}\n\n") @@ -378,19 +356,22 @@ 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) cgo_type_string {\n", s.ID(), s.sym.cgoname, ) g.Indent() + g.Printf("o := ") if (s.prots & ProtoStringer) == 0 { - g.Printf("return fmt.Sprintf(\"%%#v\", ") + g.Printf("fmt.Sprintf(\"%%#v\", ") g.Printf("*(*%[1]s)(unsafe.Pointer(self)))\n", s.sym.gofmt()) } else { - g.Printf("return (*%[1]s)(unsafe.Pointer(self)).String()\n", + g.Printf("(*%[1]s)(unsafe.Pointer(self)).String()\n", s.sym.gofmt(), ) } + g.Printf("cgopy_incref(unsafe.Pointer(&o))\n") + g.Printf("return (cgo_type_string)(unsafe.Pointer(&o))\n") g.Outdent() g.Printf("}\n\n") } @@ -440,7 +421,15 @@ func (g *goGen) genMethodBody(s Struct, m Func) { if i+1 < len(args) { tail = ", " } - g.Printf("%s%s", arg.Name(), tail) + head := fmt.Sprintf( + "*(*%s)(unsafe.Pointer(%s))", + types.TypeString( + arg.GoType(), + func(*types.Package) string { return g.pkg.Name() }, + ), + arg.Name(), + ) + g.Printf("%s%s", head, tail) } g.Printf(")\n") @@ -448,21 +437,16 @@ func (g *goGen) genMethodBody(s Struct, m Func) { return } + for i := range results { + g.Printf("cgopy_incref(unsafe.Pointer(&_gopy_%03d))\n", i) + } + g.Printf("return ") for i, res := range results { if i > 0 { g.Printf(", ") } - // if needWrap(res.GoType()) { - // g.Printf("") - // } - if res.needWrap() { - g.Printf("%s(unsafe.Pointer(&", res.sym.cgoname) - } - g.Printf("_gopy_%03d", i) - if res.needWrap() { - g.Printf("))") - } + g.Printf("%s(unsafe.Pointer(&_gopy_%03d))", res.sym.cgoname, i) } g.Printf("\n") @@ -471,32 +455,27 @@ func (g *goGen) genMethodBody(s Struct, m Func) { func (g *goGen) genConst(o Const) { sym := o.sym g.Printf("//export cgo_func_%s_get\n", o.id) - g.Printf("func cgo_func_%[1]s_get() %[2]s {\n", o.id, sym.cgotypename()) + g.Printf("func cgo_func_%[1]s_get() %[2]s {\n", o.id, sym.cgoname) g.Indent() - g.Printf("return %s(%s.%s)\n", sym.cgotypename(), o.pkg.Name(), o.obj.Name()) + g.Printf("v := %s.%s\n", o.pkg.Name(), o.obj.Name()) + g.Printf("cgopy_incref(unsafe.Pointer(&v))\n") + g.Printf("return (%s)(unsafe.Pointer(&v))\n", sym.cgoname) g.Outdent() g.Printf("}\n\n") } func (g *goGen) genVar(o Var) { pkgname := o.pkg.Name() - typ := o.GoType() - ret := o.sym.cgotypename() + ret := o.sym.cgoname g.Printf("//export cgo_func_%s_get\n", o.id) g.Printf("func cgo_func_%[1]s_get() %[2]s {\n", o.id, ret) g.Indent() - if o.needWrap() { - g.Printf("cgopy_incref(unsafe.Pointer(&%s.%s))\n", pkgname, o.Name()) - } + g.Printf("cgopy_incref(unsafe.Pointer(&%s.%s))\n", pkgname, o.Name()) g.Printf("return ") - if o.needWrap() { - g.Printf("%s(unsafe.Pointer(&%s.%s))", - ret, pkgname, o.Name(), - ) - } else { - g.Printf("%s(%s.%s)", ret, pkgname, o.Name()) - } + g.Printf("%s(unsafe.Pointer(&%s.%s))", + ret, pkgname, o.Name(), + ) g.Printf("\n") g.Outdent() g.Printf("}\n\n") @@ -504,12 +483,7 @@ func (g *goGen) genVar(o Var) { g.Printf("//export cgo_func_%s_set\n", o.id) g.Printf("func cgo_func_%[1]s_set(v %[2]s) {\n", o.id, ret) g.Indent() - vset := "v" - if needWrapType(typ) { - vset = fmt.Sprintf("*(*%s)(unsafe.Pointer(v))", o.sym.gofmt()) - } else { - vset = fmt.Sprintf("%s(v)", o.sym.gofmt()) - } + vset := fmt.Sprintf("*(*%s)(unsafe.Pointer(v))", o.sym.gofmt()) g.Printf( "%[1]s.%[2]s = %[3]s\n", pkgname, o.Name(), vset, @@ -532,23 +506,13 @@ func (g *goGen) genType(sym *symbol) { g.Printf("\n// --- wrapping %s ---\n\n", sym.gofmt()) g.Printf("//export %[1]s\n", sym.cgoname) g.Printf("// %[1]s wraps %[2]s\n", sym.cgoname, sym.gofmt()) - if sym.isBasic() { - // we need to reach at the underlying type - 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 unsafe.Pointer\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) g.Indent() g.Printf("var o %[1]s\n", sym.gofmt()) - 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("cgopy_incref(unsafe.Pointer(&o))\n") + g.Printf("return (%[1]s)(unsafe.Pointer(&o))\n", sym.cgoname) g.Outdent() g.Printf("}\n\n") @@ -560,11 +524,7 @@ func (g *goGen) genType(sym *symbol) { ) g.Indent() g.Printf("var v interface{} = ") - 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)(unsafe.Pointer(self))\n", sym.gofmt()) g.Printf("return v\n") g.Outdent() g.Printf("}\n\n") @@ -572,17 +532,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) cgo_type_string {\n", sym.id, sym.cgoname, ) g.Indent() - g.Printf("return fmt.Sprintf(\"%%#v\", ") - if sym.isBasic() { - g.Printf("%[1]s(self))\n", sym.gofmt()) - } else { - g.Printf("*(*%[1]s)(unsafe.Pointer(self)))\n", sym.gofmt()) - } + g.Printf("o := ") + g.Printf("fmt.Sprintf(\"%%#v\", ") + g.Printf("*(*%[1]s)(unsafe.Pointer(self)))\n", sym.gofmt()) + g.Printf("cgopy_incref(unsafe.Pointer(&o))\n") + g.Printf("return (cgo_type_string)(unsafe.Pointer(&o))\n") g.Outdent() g.Printf("}\n\n") @@ -623,16 +582,9 @@ func (g *goGen) genType(sym *symbol) { g.Indent() g.Printf("arr := (*%[1]s)(unsafe.Pointer(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()) - } else { - if esym.isNamed() { - g.Printf("return %[1]s(elt)\n", esym.cgotypename()) - } else { - g.Printf("return elt\n") - } - } + g.Printf("cgopy_incref(unsafe.Pointer(&elt))\n") + g.Printf("return (%[1]s)(unsafe.Pointer(&elt))\n", esym.cgotypename()) + g.Outdent() g.Printf("}\n\n") @@ -646,15 +598,8 @@ func (g *goGen) genType(sym *symbol) { g.Indent() g.Printf("arr := (*%[1]s)(unsafe.Pointer(self))\n", sym.gofmt()) g.Printf("(*arr)[i] = ") - if !esym.isBasic() { - g.Printf("*(*%[1]s)(unsafe.Pointer(v))\n", esym.gofmt()) - } else { - if esym.isNamed() { - g.Printf("%[1]s(v)\n", esym.gofmt()) - } else { - g.Printf("v\n") - } - } + g.Printf("*(*%[1]s)(unsafe.Pointer(&v))\n", esym.gofmt()) + g.Outdent() g.Printf("}\n\n") } @@ -678,15 +623,7 @@ func (g *goGen) genType(sym *symbol) { g.Indent() g.Printf("slice := (*%[1]s)(unsafe.Pointer(self))\n", sym.gofmt()) g.Printf("*slice = append(*slice, ") - if !esym.isBasic() { - g.Printf("*(*%[1]s)(unsafe.Pointer(v))", esym.gofmt()) - } else { - if esym.isNamed() { - g.Printf("%[1]s(v)", esym.gofmt()) - } else { - g.Printf("v") - } - } + g.Printf("*(*%[1]s)(unsafe.Pointer(v))", esym.gofmt()) g.Printf(")\n") g.Outdent() g.Printf("}\n\n") @@ -767,27 +704,18 @@ func (g *goGen) genTypeTPCall(sym *symbol) { } arg := params.At(i) sarg := g.pkg.syms.symtype(arg.Type()) - if sarg.isBasic() { - g.Printf("%sarg%03d", comma, i) - } else { - g.Printf( - "%s*(*%s)(unsafe.Pointer(arg%03d))", - comma, - sarg.gofmt(), - i, - ) - } + g.Printf( + "%s*(*%s)(unsafe.Pointer(arg%03d))", + comma, + sarg.gofmt(), + i, + ) } } g.Printf(")\n") if res != nil && res.Len() > 0 { for i := 0; i < res.Len(); i++ { - ret := res.At(i) - sret := g.pkg.syms.symtype(ret.Type()) - if !needWrapType(sret.GoType()) { - continue - } - g.Printf("cgopy_incref(unsafe.Pointer(&arg%03d))", i) + g.Printf("cgopy_incref(unsafe.Pointer(&arg%03d))\n", i) } g.Printf("return ") @@ -797,13 +725,7 @@ func (g *goGen) genTypeTPCall(sym *symbol) { } ret := res.At(i) sret := g.pkg.syms.symtype(ret.Type()) - if needWrapType(ret.Type()) { - g.Printf("%s(unsafe.Pointer(&", sret.cgotypename()) - } - g.Printf("res%03d", i) - if needWrapType(ret.Type()) { - g.Printf("))") - } + g.Printf("%s(unsafe.Pointer(&res%03d))", sret.cgotypename()) } g.Printf("\n") } @@ -887,17 +809,10 @@ func (g *goGen) genTypeMethods(sym *symbol) { g.Printf(" := ") } } - if sym.isBasic() { - g.Printf("(*%s)(unsafe.Pointer(&self)).%s(", - sym.gofmt(), - msym.goname, - ) - } else { - g.Printf("(*%s)(unsafe.Pointer(self)).%s(", - sym.gofmt(), - msym.goname, - ) - } + g.Printf("(*%s)(unsafe.Pointer(self)).%s(", + sym.gofmt(), + msym.goname, + ) if params != nil { for i := 0; i < params.Len(); i++ { @@ -905,14 +820,10 @@ func (g *goGen) genTypeMethods(sym *symbol) { g.Printf(", ") } sarg := g.pkg.syms.symtype(params.At(i).Type()) - if needWrapType(sarg.GoType()) { - g.Printf("*(*%s)(unsafe.Pointer(arg%03d))", - sarg.gofmt(), - i, - ) - } else { - g.Printf("arg%03d", i) - } + g.Printf("*(*%s)(unsafe.Pointer(arg%03d))", + sarg.gofmt(), + i, + ) } } g.Printf(")\n") @@ -929,16 +840,11 @@ func (g *goGen) genTypeMethods(sym *symbol) { g.Printf(", ") } sret := g.pkg.syms.symtype(res.At(i).Type()) - if needWrapType(sret.GoType()) { - g.Printf( - "%s(unsafe.Pointer(&", - sret.cgoname, - ) - } - g.Printf("res%03d", i) - if needWrapType(sret.GoType()) { - g.Printf("))") - } + g.Printf( + "%s(unsafe.Pointer(&res%03d))", + sret.cgoname, + i, + ) } g.Printf("\n") @@ -949,17 +855,39 @@ func (g *goGen) genTypeMethods(sym *symbol) { func (g *goGen) genPreamble() { n := g.pkg.pkg.Name() - pkgimport := fmt.Sprintf("%q", g.pkg.pkg.Path()) - if g.pkg.n == 0 { - pkgimport = fmt.Sprintf("_ %q", g.pkg.pkg.Path()) - } pkgcfg, err := getPkgConfig(g.lang) if err != nil { panic(err) } - g.Printf(goPreamble, n, pkgcfg, pkgimport) + pkgimport := fmt.Sprintf("%q", g.pkg.pkg.Path()) + if g.pkg.n == 0 { + pkgimport = fmt.Sprintf("_ %q", g.pkg.pkg.Path()) + } + + builtins := []string{} + for _, name := range []string{ + "bool", + "byte", + "int", "int8", "int16", "int32", "int64", + "uint", "uint8", "uint16", "uint32", "uint64", + "float32", "float64", + "complex64", "complex128", + "string", "rune", + "interface", + } { + builtins = append(builtins, + fmt.Sprintf("//export cgo_type_%[1]s", name), + fmt.Sprintf("type cgo_type_%[1]s unsafe.Pointer", name), + "", + ) + } + + g.Printf(goPreamble, + n, pkgcfg, pkgimport, + strings.Join(builtins, "\n"), + ) } func (g *goGen) tupleString(tuple []*Var) string { diff --git a/bind/symtab.go b/bind/symtab.go index 119b959..387ff3a 100644 --- a/bind/symtab.go +++ b/bind/symtab.go @@ -154,25 +154,6 @@ func (s symbol) GoType() types.Type { } func (s symbol) cgotypename() string { - typ := s.gotyp - switch typ := typ.(type) { - case *types.Basic: - n := typ.Name() - if strings.HasPrefix(n, "untyped ") { - n = string(n[len("untyped "):]) - } - return n - case *types.Named: - obj := s.goobj - switch typ.Underlying().(type) { - case *types.Struct: - return s.cgoname - case *types.Interface: - if obj.Name() == "error" { - return "error" - } - } - } return s.cgoname } @@ -516,12 +497,13 @@ func (sym *symtab) addMapType(pkg *types.Package, obj types.Object, t types.Type cgoname: "cgo_type_" + id, cpyname: "cpy_type_" + id, pyfmt: "O&", - pybuf: elt.pybuf,//fmt.Sprintf("%d%s", typ.Len(), elt.pybuf), + pybuf: elt.pybuf, //fmt.Sprintf("%d%s", typ.Len(), elt.pybuf), pysig: "object", c2py: "cgopy_cnv_c2py_" + id, py2c: "cgopy_cnv_py2c_" + id, pychk: fmt.Sprintf("cpy_func_%[1]s_check(%%s)", id), - }} + } +} func (sym *symtab) addSliceType(pkg *types.Package, obj types.Object, t types.Type, kind symkind, id, n string) { fn := sym.typename(t, nil) @@ -732,7 +714,7 @@ func init() { gotyp: look("bool").Type(), kind: skType | skBasic, goname: "bool", - cgoname: "GoUint8", + cgoname: "cgo_type_bool", cpyname: "GoUint8", pyfmt: "O&", pybuf: "?", @@ -748,9 +730,9 @@ func init() { gotyp: look("byte").Type(), kind: skType | skBasic, goname: "byte", - cpyname: "uint8_t", - cgoname: "GoUint8", - pyfmt: "b", + cgoname: "cgo_type_byte", + cpyname: "GoUint8", + pyfmt: "O&", pybuf: "B", pysig: "int", // FIXME(sbinet) py2/py3 pychk: "PyByte_Check(%s)", @@ -763,8 +745,8 @@ func init() { kind: skType | skBasic, goname: "int", cpyname: "int", - cgoname: "GoInt", - pyfmt: "i", + cgoname: "cgo_type_int", + pyfmt: "O&", pybuf: "i", pysig: "int", c2py: "cgopy_cnv_c2py_int", @@ -779,8 +761,8 @@ func init() { kind: skType | skBasic, goname: "int8", cpyname: "int8_t", - cgoname: "GoInt8", - pyfmt: "b", + cgoname: "cgo_type_int8", + pyfmt: "O&", pybuf: "b", pysig: "int", c2py: "cgopy_cnv_c2py_int8", @@ -795,8 +777,8 @@ func init() { kind: skType | skBasic, goname: "int16", cpyname: "int16_t", - cgoname: "GoInt16", - pyfmt: "h", + cgoname: "cgo_type_int16", + pyfmt: "O&", pybuf: "h", pysig: "int", c2py: "cgopy_cnv_c2py_int16", @@ -811,8 +793,8 @@ func init() { kind: skType | skBasic, goname: "int32", cpyname: "int32_t", - cgoname: "GoInt32", - pyfmt: "i", + cgoname: "cgo_type_int32", + pyfmt: "O&", pybuf: "i", pysig: "int", c2py: "cgopy_cnv_c2py_int32", @@ -827,8 +809,8 @@ func init() { kind: skType | skBasic, goname: "int64", cpyname: "int64_t", - cgoname: "GoInt64", - pyfmt: "k", + cgoname: "cgo_type_int64", + pyfmt: "O&", pybuf: "q", pysig: "long", c2py: "cgopy_cnv_c2py_int64", @@ -843,8 +825,8 @@ func init() { kind: skType | skBasic, goname: "uint", cpyname: "unsigned int", - cgoname: "GoUint", - pyfmt: "I", + cgoname: "cgo_type_uint", + pyfmt: "O&", pybuf: "I", pysig: "int", c2py: "cgopy_cnv_c2py_uint", @@ -859,8 +841,8 @@ func init() { kind: skType | skBasic, goname: "uint8", cpyname: "uint8_t", - cgoname: "GoUint8", - pyfmt: "B", + cgoname: "cgo_type_uint8", + pyfmt: "O&", pybuf: "B", pysig: "int", c2py: "cgopy_cnv_c2py_uint8", @@ -875,8 +857,8 @@ func init() { kind: skType | skBasic, goname: "uint16", cpyname: "uint16_t", - cgoname: "GoUint16", - pyfmt: "H", + cgoname: "cgo_type_uint16", + pyfmt: "O&", pybuf: "H", pysig: "int", c2py: "cgopy_cnv_c2py_uint16", @@ -891,8 +873,8 @@ func init() { kind: skType | skBasic, goname: "uint32", cpyname: "uint32_t", - cgoname: "GoUint32", - pyfmt: "I", + cgoname: "cgo_type_uint32", + pyfmt: "O&", pybuf: "I", pysig: "long", c2py: "cgopy_cnv_c2py_uint32", @@ -907,8 +889,8 @@ func init() { kind: skType | skBasic, goname: "uint64", cpyname: "uint64_t", - cgoname: "GoUint64", - pyfmt: "K", + cgoname: "cgo_type_uint64", + pyfmt: "O&", pybuf: "Q", pysig: "long", c2py: "cgopy_cnv_c2py_uint64", @@ -923,8 +905,8 @@ func init() { kind: skType | skBasic, goname: "float32", cpyname: "float", - cgoname: "GoFloat32", - pyfmt: "f", + cgoname: "cgo_type_float32", + pyfmt: "O&", pybuf: "f", pysig: "float", c2py: "cgopy_cnv_c2py_float32", @@ -939,8 +921,8 @@ func init() { kind: skType | skBasic, goname: "float64", cpyname: "double", - cgoname: "GoFloat64", - pyfmt: "d", + cgoname: "cgo_type_float64", + pyfmt: "O&", pybuf: "d", pysig: "float", c2py: "cgopy_cnv_c2py_float64", @@ -955,8 +937,8 @@ func init() { kind: skType | skBasic, goname: "complex64", cpyname: "float complex", - cgoname: "GoComplex64", - pyfmt: "D", + cgoname: "cgo_type_complex64", + pyfmt: "O&", pybuf: "ff", pysig: "complex", c2py: "cgopy_cnv_c2py_complex64", @@ -971,8 +953,8 @@ func init() { kind: skType | skBasic, goname: "complex128", cpyname: "double complex", - cgoname: "GoComplex128", - pyfmt: "D", + cgoname: "cgo_type_complex128", + pyfmt: "O&", pybuf: "dd", pysig: "complex", c2py: "cgopy_cnv_c2py_complex128", @@ -986,8 +968,8 @@ func init() { gotyp: look("string").Type(), kind: skType | skBasic, goname: "string", - cpyname: "GoString", - cgoname: "GoString", + cpyname: "cgo_type_string", + cgoname: "cgo_type_string", pyfmt: "O&", pybuf: "s", pysig: "str", @@ -1003,7 +985,7 @@ func init() { kind: skType | skBasic, goname: "rune", cpyname: "GoRune", - cgoname: "GoRune", + cgoname: "cgo_type_rune", pyfmt: "O&", pybuf: "p", pysig: "str", @@ -1018,7 +1000,7 @@ func init() { gotyp: look("error").Type(), kind: skType | skInterface, goname: "error", - cgoname: "GoInterface", + cgoname: "cgo_type_interface", cpyname: "GoInterface", pyfmt: "O&", pybuf: "PP", @@ -1036,8 +1018,8 @@ func init() { kind: skType | skBasic, goname: "int", cpyname: "int64_t", - cgoname: "GoInt", - pyfmt: "k", + cgoname: "cgo_type_int", + pyfmt: "O&", pybuf: "q", pysig: "int", c2py: "cgopy_cnv_c2py_int", @@ -1051,8 +1033,8 @@ func init() { kind: skType | skBasic, goname: "uint", cpyname: "uint64_t", - cgoname: "GoUint", - pyfmt: "K", + cgoname: "cgo_type_uint", + pyfmt: "O&", pybuf: "Q", pysig: "int", c2py: "cgopy_cnv_c2py_uint", diff --git a/bind/types.go b/bind/types.go index 21db5b6..bd178de 100644 --- a/bind/types.go +++ b/bind/types.go @@ -19,36 +19,3 @@ type Type interface { Object GoType() types.Type } - -func needWrapType(typ types.Type) bool { - switch typ := typ.(type) { - case *types.Basic: - return false - case *types.Struct: - return true - case *types.Named: - switch ut := typ.Underlying().(type) { - case *types.Basic: - return false - default: - return needWrapType(ut) - } - case *types.Array: - return true - case *types.Map: - return true - case *types.Slice: - return true - case *types.Interface: - wrap := true - if typ.Underlying() == universe.syms["error"].GoType().Underlying() { - wrap = false - } - return wrap - case *types.Signature: - return true - case *types.Pointer: - return needWrapType(typ.Elem()) - } - return false -} diff --git a/bind/vars.go b/bind/vars.go index 502507d..6f25d34 100644 --- a/bind/vars.go +++ b/bind/vars.go @@ -125,8 +125,3 @@ func (v *Var) genFuncPreamble(g *printer) { func (v *Var) getFuncArg() string { return "c_" + v.Name() } - -func (v *Var) needWrap() bool { - typ := v.GoType() - return needWrapType(typ) -}