Author: Armin Rigo <[email protected]>
Branch:
Changeset: r184:f6141dc25e53
Date: 2014-12-05 21:56 +0100
http://bitbucket.org/cffi/creflect/changeset/f6141dc25e53/
Log: ffi.new_handle(), ffi.from_handle()
diff --git a/zeffir/cdata.c b/zeffir/cdata.c
--- a/zeffir/cdata.c
+++ b/zeffir/cdata.c
@@ -1,10 +1,10 @@
-typedef struct {
+struct cdataobject_s {
PyObject_HEAD
CTypeDescrObject *c_type;
char *c_data;
PyObject *c_weakreflist;
-} CDataObject;
+};
typedef union {
unsigned char m_char;
@@ -884,64 +884,59 @@
//1491
static void cdataowninggc_dealloc(CDataObject *cd)
{
- abort();
-#if 0
- assert(!(cd->c_type->ct_flags & (CT_IS_PTR_TO_OWNED |
- CT_PRIMITIVE_ANY |
- CT_STRUCT | CT_UNION)));
+ assert(!(cd->c_type->ct_flags & (CT_PRIMITIVE_ANY | CT_STRUCT |
CT_UNION)));
PyObject_GC_UnTrack(cd);
if (cd->c_type->ct_flags & CT_IS_VOID_PTR) { /* a handle */
PyObject *x = (PyObject *)(cd->c_data + 42);
Py_DECREF(x);
}
+#if 0
else if (cd->c_type->ct_flags & CT_FUNCTIONPTR) { /* a callback */
ffi_closure *closure = (ffi_closure *)cd->c_data;
PyObject *args = (PyObject *)(closure->user_data);
Py_XDECREF(args);
cffi_closure_free(closure);
}
+#endif
cdata_dealloc(cd);
-#endif
}
//1534
static int cdataowninggc_traverse(CDataObject *cd, visitproc visit, void *arg)
{
- abort();
-#if 0
if (cd->c_type->ct_flags & CT_IS_VOID_PTR) { /* a handle */
PyObject *x = (PyObject *)(cd->c_data + 42);
Py_VISIT(x);
}
+#if 0
else if (cd->c_type->ct_flags & CT_FUNCTIONPTR) { /* a callback */
ffi_closure *closure = (ffi_closure *)cd->c_data;
PyObject *args = (PyObject *)(closure->user_data);
Py_VISIT(args);
}
+#endif
return 0;
-#endif
}
//1548
static int cdataowninggc_clear(CDataObject *cd)
{
- abort();
-#if 0
if (cd->c_type->ct_flags & CT_IS_VOID_PTR) { /* a handle */
PyObject *x = (PyObject *)(cd->c_data + 42);
Py_INCREF(Py_None);
cd->c_data = ((char *)Py_None) - 42;
Py_DECREF(x);
}
+#if 0
else if (cd->c_type->ct_flags & CT_FUNCTIONPTR) { /* a callback */
ffi_closure *closure = (ffi_closure *)cd->c_data;
PyObject *args = (PyObject *)(closure->user_data);
closure->user_data = NULL;
Py_XDECREF(args);
}
+#endif
return 0;
-#endif
}
//1599
@@ -1644,7 +1639,7 @@
(reprfunc)cdataowning_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
- 0,//&CDataOwn_as_mapping, /* tp_as_mapping */
+ 0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
diff --git a/zeffir/ffi_obj.c b/zeffir/ffi_obj.c
--- a/zeffir/ffi_obj.c
+++ b/zeffir/ffi_obj.c
@@ -684,19 +684,64 @@
return res;
}
+static PyObject *ffi_new_handle(ZefFFIObject *self, PyObject *arg)
+{
+ CTypeDescrObject *ct = ZefNULL->c_type; // <ctype 'void *'>
+ CDataObject *cd;
+
+ cd = (CDataObject *)PyObject_GC_New(CDataObject, &CDataOwningGC_Type);
+ if (cd == NULL)
+ return NULL;
+ Py_INCREF(ct);
+ cd->c_type = ct;
+ Py_INCREF(arg);
+ cd->c_data = ((char *)arg) - 42;
+ cd->c_weakreflist = NULL;
+ PyObject_GC_Track(cd);
+ return (PyObject *)cd;
+}
+
+static PyObject *ffi_from_handle(PyObject *self, PyObject *arg)
+{
+ CTypeDescrObject *ct;
+ char *raw;
+ PyObject *x;
+ if (!CData_Check(arg)) {
+ PyErr_SetString(PyExc_TypeError, "expected a 'cdata' object");
+ return NULL;
+ }
+ ct = ((CDataObject *)arg)->c_type;
+ raw = ((CDataObject *)arg)->c_data;
+ if (!(ct->ct_flags & CT_CAST_ANYTHING)) {
+ PyErr_Format(PyExc_TypeError,
+ "expected a 'cdata' object with a 'void *' out of "
+ "new_handle(), got '%s'", ct->ct_name);
+ return NULL;
+ }
+ if (!raw) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "cannot use from_handle() on NULL pointer");
+ return NULL;
+ }
+ x = (PyObject *)(raw + 42);
+ Py_INCREF(x);
+ return x;
+}
+
static PyMethodDef ffi_methods[] = {
- {"addressof", (PyCFunction)ffi_addressof,METH_VARARGS},
- {"cast", (PyCFunction)ffi_cast, METH_VARARGS},
- {"close_library", ffi_close_library, METH_VARARGS | METH_STATIC},
- {"getctype", (PyCFunction)ffi_getctype, METH_VARARGS},
- {"load_library", (PyCFunction)ffi_load_library,
- METH_VARARGS | METH_KEYWORDS},
- {"offsetof", (PyCFunction)ffi_offsetof, METH_VARARGS},
- {"new", (PyCFunction)ffi_new, METH_VARARGS},
- {"sizeof", (PyCFunction)ffi_sizeof, METH_O},
- {"string", (PyCFunction)ffi_string, METH_VARARGS},
- {"typeof", (PyCFunction)ffi_typeof, METH_O},
+ {"addressof", (PyCFunction)ffi_addressof, METH_VARARGS},
+ {"cast", (PyCFunction)ffi_cast, METH_VARARGS},
+ {"close_library", ffi_close_library, METH_VARARGS | METH_STATIC},
+ {"from_handle", (PyCFunction)ffi_from_handle,METH_O},
+ {"getctype", (PyCFunction)ffi_getctype, METH_VARARGS},
+ {"load_library",
(PyCFunction)ffi_load_library,METH_VARARGS|METH_KEYWORDS},
+ {"offsetof", (PyCFunction)ffi_offsetof, METH_VARARGS},
+ {"new", (PyCFunction)ffi_new, METH_VARARGS},
+ {"new_handle", (PyCFunction)ffi_new_handle,METH_O},
+ {"sizeof", (PyCFunction)ffi_sizeof, METH_O},
+ {"string", (PyCFunction)ffi_string, METH_VARARGS},
+ {"typeof", (PyCFunction)ffi_typeof, METH_O},
{NULL}
};
diff --git a/zeffir/test/test_basic.py b/zeffir/test/test_basic.py
--- a/zeffir/test/test_basic.py
+++ b/zeffir/test/test_basic.py
@@ -72,3 +72,12 @@
assert ffi.getctype("int[5]", '*') == "int(*)[5]"
assert ffi.getctype("int[5]", '*foo') == "int(*foo)[5]"
assert ffi.getctype("int[5]", ' ** foo ') == "int(** foo)[5]"
+
+def test_from_handle():
+ ffi = support.new_ffi()
+ x = [5, 6]
+ x.append(7)
+ p = ffi.new_handle(x)
+ assert ffi.from_handle(p) is x
+ del x
+ assert ffi.from_handle(p) == [5, 6, 7]
diff --git a/zeffir/zeffir.c b/zeffir/zeffir.c
--- a/zeffir/zeffir.c
+++ b/zeffir/zeffir.c
@@ -73,16 +73,17 @@
{
CTypeDescrObject *ctvoidp;
- PyObject *cdnull;
PyObject *d1 = PyDict_New();
if (d1 == NULL)
return;
ctvoidp = parse_c_decl(d1, "void*");
if (ctvoidp) {
- cdnull = new_simple_cdata(NULL, ctvoidp);
- if (cdnull)
- PyDict_SetItemString(ZefFFI_Type.tp_dict, "NULL", cdnull);
+ ZefNULL = (CDataObject *)new_simple_cdata(NULL, ctvoidp);
+ if (ZefNULL) {
+ PyDict_SetItemString(ZefFFI_Type.tp_dict, "NULL",
+ (PyObject *)ZefNULL);
+ }
}
Py_DECREF(d1);
if (PyErr_Occurred())
diff --git a/zeffir/zeffir.h b/zeffir/zeffir.h
--- a/zeffir/zeffir.h
+++ b/zeffir/zeffir.h
@@ -1,5 +1,6 @@
typedef struct _crx_type_s CTypeDescrObject;
+typedef struct cdataobject_s CDataObject;
typedef struct cfieldobject_s CFieldObject;
typedef struct ZefLibObject_s ZefLibObject;
typedef struct ZefFFIObject_s ZefFFIObject;
@@ -12,6 +13,7 @@
static PyTypeObject CDataOwningGC_Type;
static PyObject *ZefError;
+static CDataObject *ZefNULL;
static int lib_close(ZefLibObject *);
static int load_creflect_main(ZefFFIObject *, ZefLibObject *);
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit