summaryrefslogtreecommitdiff
path: root/Cython/Utility
diff options
context:
space:
mode:
authorAnselm Kruis <Anselm.Kruis@atos.net>2018-08-14 12:46:46 +0200
committerAnselm Kruis <Anselm.Kruis@atos.net>2018-08-14 12:46:46 +0200
commitc1a6417489dfc9140cc64407fbcfa0684ba95ba1 (patch)
treea3e85e48b65c30edd8df4e9f844e5c2a67ba0991 /Cython/Utility
parent60d135b706d4cf6fb3abf74af227ada2cdd65fe8 (diff)
downloadcython-c1a6417489dfc9140cc64407fbcfa0684ba95ba1.tar.gz
make __Pyx_PyFunction_FastCallNoKw compatible with Stackless Python
Compute the offset of the PyFrameObject member "f_localsplus" at runtime, because the layout of PyFrameObject differs between regular C-python and Stackless Python.
Diffstat (limited to 'Cython/Utility')
-rw-r--r--Cython/Utility/ModuleSetupCode.c39
-rw-r--r--Cython/Utility/ObjectHandling.c3
2 files changed, 40 insertions, 2 deletions
diff --git a/Cython/Utility/ModuleSetupCode.c b/Cython/Utility/ModuleSetupCode.c
index d7f8cb053..1e8c17ca7 100644
--- a/Cython/Utility/ModuleSetupCode.c
+++ b/Cython/Utility/ModuleSetupCode.c
@@ -412,6 +412,45 @@ class __Pyx_FakeReference {
#define __Pyx_PyFastCFunction_Check(func) 0
#endif
+/* back port from Python 3 */
+#ifndef Py_BUILD_ASSERT_EXPR
+/* Assert a build-time dependency, as an expression.
+
+ Your compile will fail if the condition isn't true, or can't be evaluated
+ by the compiler. This can be used in an expression: its value is 0.
+
+ Example:
+
+ #define foo_to_char(foo) \
+ ((char *)(foo) \
+ + Py_BUILD_ASSERT_EXPR(offsetof(struct foo, string) == 0))
+
+ Written by Rusty Russell, public domain, http://ccodearchive.net/ */
+#define Py_BUILD_ASSERT_EXPR(cond) \
+ (sizeof(char [1 - 2*!(cond)]) - 1)
+#endif
+#ifndef Py_MEMBER_SIZE
+/* Get the size of a structure member in bytes */
+#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member)
+#endif
+
+#ifdef CYTHON_FAST_PYCALL
+ #include "frameobject.h"
+ // offsetof(PyFrameObject, f_localsplus) differs between regular C-Python and Stackless Python.
+ // Therefore the offset is computed at run time from PyFrame_type.tp_basicsize. That is feasible,
+ // because f_localsplus is the last field of PyFrameObject (checked by Py_BUILD_ASSERT_EXPR).
+ static size_t __pyx_pyframe_localsplus_offset = 0;
+ #define __Pxy_PyFrame_Initialize_Offsets() \
+ ((void)Py_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)), \
+ (void)(__pyx_pyframe_localsplus_offset = PyFrame_Type.tp_basicsize - Py_MEMBER_SIZE(PyFrameObject, f_localsplus)))
+ #define __Pyx_PyFrame_GetLocalsplus(frame) \
+ (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset))
+#else
+ #define __Pxy_PyFrame_Initialize_Offsets() /* empty */
+ // not used
+ // #define __Pyx_PyFrame_GetLocalsplus(frame) ((frame)->f_localsplus)
+#endif
+
#if CYTHON_USE_DICT_VERSIONS
#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag)
#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) \
diff --git a/Cython/Utility/ObjectHandling.c b/Cython/Utility/ObjectHandling.c
index 9cc240f18..10735eb33 100644
--- a/Cython/Utility/ObjectHandling.c
+++ b/Cython/Utility/ObjectHandling.c
@@ -1942,7 +1942,6 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args,
// copied from CPython 3.6 ceval.c
#if CYTHON_FAST_PYCALL
-#include "frameobject.h"
static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na,
PyObject *globals) {
@@ -1963,7 +1962,7 @@ static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args
return NULL;
}
- fastlocals = f->f_localsplus;
+ fastlocals = __Pyx_PyFrame_GetLocalsplus(f);
for (i = 0; i < na; i++) {
Py_INCREF(*args);