bind: handle all types as opaque pointers

Change-Id: I06a021ced190401afd10cda9057238f4399cd60f
This commit is contained in:
Sebastien Binet 2015-09-01 17:06:40 +02:00
parent 33f3ca06ba
commit 9a166327fe
8 changed files with 236 additions and 342 deletions

View File

@ -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));
}
`
)

View File

@ -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")

View File

@ -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,

View File

@ -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")

View File

@ -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 {

View File

@ -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",

View File

@ -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
}

View File

@ -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)
}