diff options
author | Eddie Elizondo <eelizondo@fb.com> | 2020-02-18 02:23:19 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-18 11:23:19 +0100 |
commit | a87f498d964f4b63a93aba79ed8c5f082fedaa4f (patch) | |
tree | 34d505214cc831bd8f1f039070e78fccef6fb0f5 /Cython/Compiler/ModuleNode.py | |
parent | 1431cc4e492f06abd191e639903966733201baba (diff) | |
download | cython-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.py | 81 |
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, |