Commit c1a64174 authored by Anselm Kruis's avatar Anselm Kruis

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.
parent 60d135b7
......@@ -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" % (
......
......@@ -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) \
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment