On Wed, Oct 14, 2009 at 2:26 PM, Stefan Behnel <[email protected]> wrote:
>
> Lisandro Dalcin wrote:
>> I think I'll use
>> PyLong_{From|As}VoidPtr for importing/exporting the API structure...
>> Making it simpler will make it also portable across all CPython
>> versions.
>
> But it wouldn't make it compatible with other non-Cython C-APIs, would it?
> I think that's a requirement. If there's a standard way, Cython should be
> 100% compatible with that.
>
Please note I was talking JUST about the refnanny support module. The
import/export of its C-API (actually a pointer to a struct) what
rather ad-hoc and used PyCObject... I do not really see the point of
bothering about the refnanny module "properly" exporting its API and
complicating the implementation now that CObjects are not available in
all Python runtimes.
>
>> Additionally, I'll make a heavy renaming of some refnanny stuff,
>> things will be now named "__Pyx_RefNanny[XXX]".
>
> What's that for?
>
Just for the sake of the generated C code being more easier to follow
and understand... We always talk about "refnanny", why not generate
the C code using that name consistently where appropriate.
Additionally, I'm changing the way of using the CYTHON_REFNANNY macro
with the preprocessor... Now you have to explicitly #define it to 1,
(as we require for complex support, and C-level profiling) ...
See the attached patch to see exactly what I'm talking about.
--
Lisandro Dalcín
---------------
Centro Internacional de Métodos Computacionales en Ingeniería (CIMEC)
Instituto de Desarrollo Tecnológico para la Industria Química (INTEC)
Consejo Nacional de Investigaciones Científicas y Técnicas (CONICET)
PTLC - Güemes 3450, (3000) Santa Fe, Argentina
Tel/Fax: +54-(0)342-451.1594
diff -r eec15f6bb917 Cython/Compiler/Code.py
--- a/Cython/Compiler/Code.py
+++ b/Cython/Compiler/Code.py
@@ -1273,10 +1273,10 @@
return self.globalstate.lookup_filename(filename)
def put_setup_refcount_context(self, name):
- self.putln('__Pyx_SetupRefcountContext("%s");' % name)
+ self.putln('__Pyx_RefNannySetupContext("%s");' % name)
def put_finish_refcount_context(self):
- self.putln("__Pyx_FinishRefcountContext();")
+ self.putln("__Pyx_RefNannyFinishContext();")
def put_trace_call(self, name, pos):
self.putln('__Pyx_TraceCall("%s", %s[%s], %s);' % (name, Naming.filetable_cname, self.lookup_filename(pos[0]), pos[1]));
diff -r eec15f6bb917 Cython/Compiler/ModuleNode.py
--- a/Cython/Compiler/ModuleNode.py
+++ b/Cython/Compiler/ModuleNode.py
@@ -260,7 +260,7 @@
globalstate.module_pos = self.pos
globalstate.directives = self.directives
- globalstate.use_utility_code(refcount_utility_code)
+ globalstate.use_utility_code(refnanny_utility_code)
code = globalstate['before_global_var']
code.putln('#define __Pyx_MODULE_NAME "%s"' % self.full_module_name)
@@ -1634,18 +1634,19 @@
code.putln("{")
tempdecl_code = code.insertion_point()
+ code.putln("#if CYTHON_REFNANNY")
+ code.putln("void* __pyx_refnanny = NULL;")
+ code.putln("__Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"refnanny\");")
+ code.putln("if (!__Pyx_RefNanny) {")
+ code.putln(" PyErr_Clear();")
+ code.putln(" __Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"Cython.Runtime.refnanny\");")
+ code.putln(" if (!__Pyx_RefNanny)")
+ code.putln(" Py_FatalError(\"failed to import 'refnanny' module\");")
+ code.putln("}")
+ code.putln("__pyx_refnanny = __Pyx_RefNanny->SetupContext(\"%s\", __LINE__, __FILE__);"% header3)
+ code.putln("#endif")
+
self.generate_filename_init_call(code)
- code.putln("#ifdef CYTHON_REFNANNY")
- code.putln("void* __pyx_refchk = NULL;")
- code.putln("__Pyx_Refnanny = __Pyx_ImportRefcountAPI(\"refnanny\");")
- code.putln("if (!__Pyx_Refnanny) {")
- code.putln(" PyErr_Clear();")
- code.putln(" __Pyx_Refnanny = __Pyx_ImportRefcountAPI(\"Cython.Runtime.refnanny\");")
- code.putln(" if (!__Pyx_Refnanny)")
- code.putln(" Py_FatalError(\"failed to import refnanny module\");")
- code.putln("}")
- code.putln("__pyx_refchk = __Pyx_Refnanny->NewContext(\"%s\", __LINE__, __FILE__);"% header3)
- code.putln("#endif")
code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)));
code.putln("#if PY_MAJOR_VERSION < 3");
@@ -2444,36 +2445,51 @@
""" % {'IMPORT_STAR' : Naming.import_star,
'IMPORT_STAR_SET' : Naming.import_star_set }
-refcount_utility_code = UtilityCode(proto="""
-#ifdef CYTHON_REFNANNY
-typedef struct {
- void (*INCREF)(void*, PyObject*, int);
- void (*DECREF)(void*, PyObject*, int);
- void (*GOTREF)(void*, PyObject*, int);
- void (*GIVEREF)(void*, PyObject*, int);
- void* (*NewContext)(const char*, int, const char*);
- void (*FinishContext)(void**);
-} __Pyx_RefnannyAPIStruct;
-static __Pyx_RefnannyAPIStruct *__Pyx_Refnanny = NULL;
-#define __Pyx_ImportRefcountAPI(name) \
- (__Pyx_RefnannyAPIStruct *) PyCObject_Import((char *)name, (char *)\"RefnannyAPI\")
-#define __Pyx_INCREF(r) __Pyx_Refnanny->INCREF(__pyx_refchk, (PyObject *)(r), __LINE__)
-#define __Pyx_DECREF(r) __Pyx_Refnanny->DECREF(__pyx_refchk, (PyObject *)(r), __LINE__)
-#define __Pyx_GOTREF(r) __Pyx_Refnanny->GOTREF(__pyx_refchk, (PyObject *)(r), __LINE__)
-#define __Pyx_GIVEREF(r) __Pyx_Refnanny->GIVEREF(__pyx_refchk, (PyObject *)(r), __LINE__)
-#define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r);} } while(0)
-#define __Pyx_SetupRefcountContext(name) \
- void* __pyx_refchk = __Pyx_Refnanny->NewContext((name), __LINE__, __FILE__)
-#define __Pyx_FinishRefcountContext() \
- __Pyx_Refnanny->FinishContext(&__pyx_refchk)
+refnanny_utility_code = UtilityCode(proto="""
+#ifndef CYTHON_REFNANNY
+ #define CYTHON_REFNANNY 0
+#endif
+
+#if CYTHON_REFNANNY
+ typedef struct {
+ void (*INCREF)(void*, PyObject*, int);
+ void (*DECREF)(void*, PyObject*, int);
+ void (*GOTREF)(void*, PyObject*, int);
+ void (*GIVEREF)(void*, PyObject*, int);
+ void* (*SetupContext)(const char*, int, const char*);
+ void (*FinishContext)(void**);
+ } __Pyx_RefNannyAPIStruct;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+ static __Pyx_RefNannyAPIStruct * __Pyx_RefNannyImportAPI(const char *modname) {
+ PyObject *m = NULL, *p = NULL;
+ void *r = NULL;
+ m = PyImport_ImportModule((char *)modname);
+ if (!m) goto end;
+ p = PyObject_GetAttrString(m, (char *)\"RefNannyAPI\");
+ if (!p) goto end;
+ r = PyLong_AsVoidPtr(p);
+ end:
+ Py_XDECREF(p);
+ Py_XDECREF(m);
+ return (__Pyx_RefNannyAPIStruct *)r;
+ }
+ #define __Pyx_RefNannySetupContext(name) \
+ void *__pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+ #define __Pyx_RefNannyFinishContext() \
+ __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+ #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r);} } while(0)
#else
-#define __Pyx_INCREF(r) Py_INCREF(r)
-#define __Pyx_DECREF(r) Py_DECREF(r)
-#define __Pyx_GOTREF(r)
-#define __Pyx_GIVEREF(r)
-#define __Pyx_XDECREF(r) Py_XDECREF(r)
-#define __Pyx_SetupRefcountContext(name)
-#define __Pyx_FinishRefcountContext()
+ #define __Pyx_RefNannySetupContext(name)
+ #define __Pyx_RefNannyFinishContext()
+ #define __Pyx_INCREF(r) Py_INCREF(r)
+ #define __Pyx_DECREF(r) Py_DECREF(r)
+ #define __Pyx_GOTREF(r)
+ #define __Pyx_GIVEREF(r)
+ #define __Pyx_XDECREF(r) Py_XDECREF(r)
#endif /* CYTHON_REFNANNY */
#define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);} } while(0)
#define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r);} } while(0)
diff -r eec15f6bb917 Cython/Runtime/refnanny.pyx
--- a/Cython/Runtime/refnanny.pyx
+++ b/Cython/Runtime/refnanny.pyx
@@ -69,7 +69,7 @@
# exception has been fetched, in case we are called from
# exception-handling code.
-cdef PyObject* NewContext(char* funcname, int lineno, char* filename) except NULL:
+cdef PyObject* SetupContext(char* funcname, int lineno, char* filename) except NULL:
if Context is None:
# Context may be None during finalize phase.
# In that case, we don't want to be doing anything fancy
@@ -143,23 +143,23 @@
ctx[0] = NULL
PyErr_Restore(type, value, tb)
-cdef extern from "Python.h":
- object PyCObject_FromVoidPtr(void*, void (*)(void*))
-
-ctypedef struct RefnannyAPIStruct:
+ctypedef struct RefNannyAPIStruct:
void (*INCREF)(PyObject*, PyObject*, int)
void (*DECREF)(PyObject*, PyObject*, int)
void (*GOTREF)(PyObject*, PyObject*, int)
void (*GIVEREF)(PyObject*, PyObject*, int)
- PyObject* (*NewContext)(char*, int, char*) except NULL
+ PyObject* (*SetupContext)(char*, int, char*) except NULL
void (*FinishContext)(PyObject**)
-cdef RefnannyAPIStruct api
+cdef RefNannyAPIStruct api
api.INCREF = INCREF
api.DECREF = DECREF
api.GOTREF = GOTREF
api.GIVEREF = GIVEREF
-api.NewContext = NewContext
+api.SetupContext = SetupContext
api.FinishContext = FinishContext
-RefnannyAPI = PyCObject_FromVoidPtr(<void*>&api, NULL)
+cdef extern from "Python.h":
+ object PyLong_FromVoidPtr(void*)
+
+RefNannyAPI = PyLong_FromVoidPtr(<void*>&api)
diff -r eec15f6bb917 runtests.py
--- a/runtests.py
+++ b/runtests.py
@@ -730,7 +730,7 @@
build_in_temp=True,
pyxbuild_dir=os.path.join(WORKDIR, "support"))
sys.path.insert(0, os.path.split(libpath)[0])
- CFLAGS.append("-DCYTHON_REFNANNY")
+ CFLAGS.append("-DCYTHON_REFNANNY=1")
test_bugs = False
if options.tickets:
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev