diff options
author | Anselm Kruis <Anselm.Kruis@atos.net> | 2018-08-14 12:46:46 +0200 |
---|---|---|
committer | Anselm Kruis <Anselm.Kruis@atos.net> | 2018-08-14 12:46:46 +0200 |
commit | c1a6417489dfc9140cc64407fbcfa0684ba95ba1 (patch) | |
tree | a3e85e48b65c30edd8df4e9f844e5c2a67ba0991 | |
parent | 60d135b706d4cf6fb3abf74af227ada2cdd65fe8 (diff) | |
download | cython-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.
-rw-r--r-- | Cython/Compiler/ModuleNode.py | 1 | ||||
-rw-r--r-- | Cython/Utility/ModuleSetupCode.c | 39 | ||||
-rw-r--r-- | Cython/Utility/ObjectHandling.c | 3 |
3 files changed, 41 insertions, 2 deletions
diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 8a9186e01..5d41fe08c 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -2357,6 +2357,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): env.use_utility_code(UtilityCode.load("CheckBinaryVersion", "ModuleSetupCode.c")) code.put_error_if_neg(self.pos, "__Pyx_check_binary_version()") + code.putln("__Pxy_PyFrame_Initialize_Offsets();") code.putln("%s = PyTuple_New(0); %s" % ( Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos))) code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % ( 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); |