[pypy-commit] cffi cffi-1.0: ffi.gc(), copied straight from zeffir
arigo
noreply at buildbot.pypy.org
Sun Apr 26 11:29:08 CEST 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r1841:e0ca28cfacbd
Date: 2015-04-26 11:29 +0200
http://bitbucket.org/cffi/cffi/changeset/e0ca28cfacbd/
Log: ffi.gc(), copied straight from zeffir
diff --git a/_cffi1/cffi1_module.c b/_cffi1/cffi1_module.c
--- a/_cffi1/cffi1_module.c
+++ b/_cffi1/cffi1_module.c
@@ -10,6 +10,7 @@
#include "ffi_obj.c"
#include "cglob.c"
+#include "cgc.c"
#include "lib_obj.c"
diff --git a/_cffi1/cgc.c b/_cffi1/cgc.c
new file mode 100644
--- /dev/null
+++ b/_cffi1/cgc.c
@@ -0,0 +1,80 @@
+
+/* translated to C from cffi/gc_weakref.py */
+
+
+static PyObject *const_name_pop;
+
+static PyObject *gc_wref_remove(PyObject *ffi_wref_data, PyObject *arg)
+{
+ PyObject *destructor, *cdata, *x;
+ PyObject *res = PyObject_CallMethodObjArgs(ffi_wref_data,
+ const_name_pop, arg, NULL);
+ if (res == NULL)
+ return NULL;
+
+ assert(PyTuple_Check(res));
+ destructor = PyTuple_GET_ITEM(res, 0);
+ cdata = PyTuple_GET_ITEM(res, 1);
+ x = PyObject_CallFunctionObjArgs(destructor, cdata, NULL);
+ Py_DECREF(res);
+ if (x == NULL)
+ return NULL;
+ Py_DECREF(x);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef remove_callback = {
+ "gc_wref_remove", (PyCFunction)gc_wref_remove, METH_O
+};
+
+static PyObject *gc_weakrefs_build(FFIObject *ffi, CDataObject *cd,
+ PyObject *destructor)
+{
+ PyObject *new_cdata, *ref = NULL, *tup = NULL;
+
+ if (ffi->gc_wrefs == NULL) {
+ /* initialize */
+ PyObject *data;
+
+ if (const_name_pop == NULL) {
+ const_name_pop = PyString_InternFromString("pop");
+ if (const_name_pop == NULL)
+ return NULL;
+ }
+ data = PyDict_New();
+ if (data == NULL)
+ return NULL;
+ ffi->gc_wrefs = PyCFunction_New(&remove_callback, data);
+ Py_DECREF(data);
+ if (ffi->gc_wrefs == NULL)
+ return NULL;
+ }
+
+ new_cdata = do_cast(cd->c_type, (PyObject *)cd);
+ if (new_cdata == NULL)
+ goto error;
+
+ ref = PyWeakref_NewRef(new_cdata, ffi->gc_wrefs);
+ if (ref == NULL)
+ goto error;
+
+ tup = PyTuple_Pack(2, destructor, cd);
+ if (tup == NULL)
+ goto error;
+
+ /* the 'self' of the function 'gc_wrefs' is actually the data dict */
+ if (PyDict_SetItem(PyCFunction_GET_SELF(ffi->gc_wrefs), ref, tup) < 0)
+ goto error;
+
+ Py_DECREF(tup);
+ Py_DECREF(ref);
+ return new_cdata;
+
+ error:
+ Py_XDECREF(new_cdata);
+ Py_XDECREF(ref);
+ Py_XDECREF(tup);
+ return NULL;
+}
diff --git a/_cffi1/ffi_obj.c b/_cffi1/ffi_obj.c
--- a/_cffi1/ffi_obj.c
+++ b/_cffi1/ffi_obj.c
@@ -546,8 +546,15 @@
return direct_from_buffer(g_ct_chararray, arg);
}
-#if 0
-static PyObject *ffi_gc(ZefFFIObject *self, PyObject *args)
+PyDoc_STRVAR(ffi_gc_doc,
+"Return a new cdata object that points to the same data.\n"
+"Later, when this new cdata object is garbage-collected,\n"
+"'destructor(old_cdata_object)' will be called.");
+
+static PyObject *gc_weakrefs_build(FFIObject *ffi, CDataObject *cd,
+ PyObject *destructor); /* forward */
+
+static PyObject *ffi_gc(FFIObject *self, PyObject *args)
{
CDataObject *cd;
PyObject *destructor;
@@ -557,7 +564,6 @@
return gc_weakrefs_build(self, cd, destructor);
}
-#endif
PyDoc_STRVAR(ffi_callback_doc,
"Return a callback object or a decorator making such a callback object.\n"
@@ -731,9 +737,7 @@
{"cast", (PyCFunction)ffi_cast, METH_VARARGS, ffi_cast_doc},
{"from_buffer",(PyCFunction)ffi_from_buffer,METH_O, ffi_from_buffer_doc},
{"from_handle",(PyCFunction)ffi_from_handle,METH_O, ffi_from_handle_doc},
-#if 0
- {"gc", (PyCFunction)ffi_gc, METH_VARARGS},
-#endif
+ {"gc", (PyCFunction)ffi_gc, METH_VARARGS, ffi_gc_doc},
{"getctype", (PyCFunction)ffi_getctype, METH_VARARGS, ffi_getctype_doc},
#ifdef MS_WIN32
{"getwinerror",(PyCFunction)ffi_getwinerror,METH_VARARGS, ffi_getwinerror_doc},
More information about the pypy-commit
mailing list