summaryrefslogtreecommitdiff
path: root/Cython/Compiler/ModuleNode.py
diff options
context:
space:
mode:
authorEddie Elizondo <eelizondo@fb.com>2020-02-18 02:23:19 -0800
committerGitHub <noreply@github.com>2020-02-18 11:23:19 +0100
commita87f498d964f4b63a93aba79ed8c5f082fedaa4f (patch)
tree34d505214cc831bd8f1f039070e78fccef6fb0f5 /Cython/Compiler/ModuleNode.py
parent1431cc4e492f06abd191e639903966733201baba (diff)
downloadcython-a87f498d964f4b63a93aba79ed8c5f082fedaa4f.tar.gz
Expand LIMITED_API support (GH-3311)
* Add more limited api support * Fix Fused Functions * Fixed profile * Use PyModule_GetDict * Simplify __Pyx_Globals * Address issues in CommonStructures * ifdef guard CyFunction and FusedFunction
Diffstat (limited to 'Cython/Compiler/ModuleNode.py')
-rw-r--r--Cython/Compiler/ModuleNode.py81
1 files changed, 55 insertions, 26 deletions
diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py
index 2a9e1090e..62b305a50 100644
--- a/Cython/Compiler/ModuleNode.py
+++ b/Cython/Compiler/ModuleNode.py
@@ -1203,6 +1203,18 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
module_state_traverse.putln(
"Py_VISIT(traverse_module_state->%s);" %
entry.type.typeptr_cname)
+ if entry.type.typeobj_cname is not None:
+ module_state.putln("PyObject *%s;" % entry.type.typeobj_cname)
+ module_state_defines.putln("#define %s %s->%s" % (
+ entry.type.typeobj_cname,
+ Naming.modulestateglobal_cname,
+ entry.type.typeobj_cname))
+ module_state_clear.putln(
+ "Py_CLEAR(clear_module_state->%s);" % (
+ entry.type.typeobj_cname))
+ module_state_traverse.putln(
+ "Py_VISIT(traverse_module_state->%s);" % (
+ entry.type.typeobj_cname))
code.putln("#endif")
def generate_cvariable_declarations(self, env, code, definition):
@@ -1365,12 +1377,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
freecount_name = scope.mangle_internal(Naming.freecount_name)
decls = code.globalstate['decls']
- if cinit_func_entry is None:
- decls.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
decls.putln("static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/" %
slot_func)
- if cinit_func_entry is None:
- decls.putln("#endif")
code.putln("")
if freelist_size:
code.putln("static %s[%d];" % (
@@ -1378,8 +1386,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
freelist_size))
code.putln("static int %s = 0;" % freecount_name)
code.putln("")
- if cinit_func_entry is None:
- code.putln("#if !CYTHON_COMPILING_IN_LIMITED_API")
code.putln(
"static PyObject *%s(PyTypeObject *t, %sPyObject *a, %sPyObject *k) {" % (
slot_func, unused_marker, unused_marker))
@@ -1390,10 +1396,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if need_self_cast:
code.putln("%s;" % scope.parent_type.declaration_code("p"))
if base_type:
+ code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
+ code.putln("newfunc new_func = (newfunc)PyType_GetSlot(%s, Py_tp_new);" %
+ base_type.typeptr_cname)
+ code.putln("PyObject *o = new_func(t, a, k);")
+ code.putln("#else")
tp_new = TypeSlots.get_base_slot_function(scope, tp_slot)
if tp_new is None:
tp_new = "%s->tp_new" % base_type.typeptr_cname
code.putln("PyObject *o = %s(t, a, k);" % tp_new)
+ code.putln("#endif")
else:
code.putln("PyObject *o;")
code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
@@ -1425,10 +1437,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("} else {")
code.putln("o = (PyObject *) PyBaseObject_Type.tp_new(t, %s, 0);" % Naming.empty_tuple)
code.putln("}")
- code.putln("#endif")
code.putln("if (unlikely(!o)) return 0;")
if freelist_size and not base_type:
code.putln('}')
+ if not base_type:
+ code.putln("#endif")
if need_self_cast:
code.putln("p = %s;" % type.cast_code("o"))
#if need_self_cast:
@@ -1488,8 +1501,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("return NULL;")
code.putln(
"}")
- if cinit_func_entry is None:
- code.putln("#endif")
def generate_dealloc_function(self, scope, code):
tp_slot = TypeSlots.ConstructorSlot("tp_dealloc", '__dealloc__')
@@ -2234,8 +2245,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
for slot in TypeSlots.slot_table:
if slot.slot_name == "tp_flags":
continue
- if slot.slot_name == "tp_new" and scope.lookup_here("__cinit__") is None:
- continue
if slot.slot_name == "tp_dealloc" and scope.lookup_here("__dealloc__") is None:
continue
if slot.slot_name == "tp_getattro":
@@ -2452,26 +2461,18 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln('int %s;' % Naming.lineno_cname)
code.putln('int %s;' % Naming.clineno_cname)
code.putln('const char *%s;' % Naming.filename_cname)
+ code.putln('#ifdef __Pyx_CyFunction_USED')
+ code.putln('PyObject *%s;' % Naming.cyfunction_type_cname)
+ code.putln('#endif')
+ code.putln('#ifdef __Pyx_FusedFunction_USED')
+ code.putln('PyObject *%s;' % Naming.fusedfunction_type_cname)
+ code.putln('#endif')
def generate_module_state_end(self, env, modules, globalstate):
module_state = globalstate['module_state']
module_state_defines = globalstate['module_state_defines']
module_state_clear = globalstate['module_state_clear']
module_state_traverse = globalstate['module_state_traverse']
- for module in modules:
- definition = module is env
- for entry in env.c_class_entries:
- if definition or entry.defined_in_pxd:
- module_state.putln("PyObject *%s;" % entry.type.typeobj_cname)
- module_state_defines.putln("#define %s %s->%s" % (
- entry.type.typeobj_cname,
- Naming.modulestateglobal_cname,
- entry.type.typeobj_cname))
- module_state_clear.putln("Py_CLEAR(clear_module_state->%s);" %
- entry.type.typeobj_cname)
- module_state_traverse.putln(
- "Py_VISIT(traverse_module_state->%s);" %
- entry.type.typeobj_cname)
module_state.putln('} %s;' % Naming.modulestate_cname)
module_state.putln('')
module_state.putln('#ifdef __cplusplus')
@@ -2542,6 +2543,18 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
Naming.filename_cname,
Naming.modulestateglobal_cname,
Naming.filename_cname))
+ code.putln('#ifdef __Pyx_CyFunction_USED')
+ code.putln('#define %s %s->%s' % (
+ Naming.cyfunction_type_cname,
+ Naming.modulestateglobal_cname,
+ Naming.cyfunction_type_cname))
+ code.putln('#endif')
+ code.putln('#ifdef __Pyx_FusedFunction_USED')
+ code.putln('#define %s %s->%s' %
+ (Naming.fusedfunction_type_cname,
+ Naming.modulestateglobal_cname,
+ Naming.fusedfunction_type_cname))
+ code.putln('#endif')
def generate_module_state_clear(self, env, code):
code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
@@ -2560,6 +2573,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
Naming.empty_bytes)
code.putln('Py_CLEAR(clear_module_state->%s);' %
Naming.empty_unicode)
+ code.putln('#ifdef __Pyx_CyFunction_USED')
+ code.putln('Py_CLEAR(clear_module_state->%s);' %
+ Naming.cyfunction_type_cname)
+ code.putln('#endif')
+ code.putln('#ifdef __Pyx_FusedFunction_USED')
+ code.putln('Py_CLEAR(clear_module_state->%s);' %
+ Naming.fusedfunction_type_cname)
+ code.putln('#endif')
def generate_module_state_traverse(self, env, code):
code.putln("#if CYTHON_COMPILING_IN_LIMITED_API")
@@ -2578,6 +2599,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
Naming.empty_bytes)
code.putln('Py_VISIT(traverse_module_state->%s);' %
Naming.empty_unicode)
+ code.putln('#ifdef __Pyx_CyFunction_USED')
+ code.putln('Py_VISIT(traverse_module_state->%s);' %
+ Naming.cyfunction_type_cname)
+ code.putln('#endif')
+ code.putln('#ifdef __Pyx_FusedFunction_USED')
+ code.putln('Py_VISIT(traverse_module_state->%s);' %
+ Naming.fusedfunction_type_cname)
+ code.putln('#endif')
def generate_module_init_func(self, imported_modules, env, code):
subfunction = self.mod_init_subfunction(self.scope, code)
@@ -3371,7 +3400,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if type.vtabptr_cname:
code.globalstate.use_utility_code(
UtilityCode.load_cached('GetVTable', 'ImportExport.c'))
- code.putln("%s = (struct %s*)__Pyx_GetVtable(%s->tp_dict); %s" % (
+ code.putln("%s = (struct %s*)__Pyx_GetVtable(%s); %s" % (
type.vtabptr_cname,
type.vtabstruct_cname,
type.typeptr_cname,