diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2020-04-26 20:28:56 +0200 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2020-04-26 20:28:56 +0200 |
commit | 4dbce65d359473c1dc37eb0c325ae177aa0774a2 (patch) | |
tree | 32c331cf02c822b5c3a9824595d9a5555d11162d | |
parent | bc40c5f4873ad41a63de64c94331c45f0def148d (diff) | |
download | cython-4dbce65d359473c1dc37eb0c325ae177aa0774a2.tar.gz |
Clean up and repair the type spec generation for the limited API, leaving more of the work to the TypeSlots instead of special-casing all sorts of things.
-rw-r--r-- | Cython/Compiler/ModuleNode.py | 44 | ||||
-rw-r--r-- | Cython/Compiler/TypeSlots.py | 55 |
2 files changed, 50 insertions, 49 deletions
diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 1be6e7f27..51458036d 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -2231,45 +2231,23 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): def generate_typeobj_spec(self, modname, entry, code): type = entry.type scope = type.scope + code.putln("static PyType_Slot %s_slots[] = {" % type.typeobj_cname) + for slot in TypeSlots.slot_table: + slot.generate_spec(scope, code) + code.putln("{0, 0},") + code.putln("};") + if type.typedef_flag: objstruct = type.objstruct_cname else: objstruct = "struct %s" % type.objstruct_cname classname = scope.class_name.as_c_string_literal() - code.putln("static PyType_Slot %s_slots[] = {" % type.typeobj_cname) - has_tp_getattro = False - for slot in TypeSlots.slot_table: - if slot.slot_name == "tp_flags": - continue - if slot.slot_name == "tp_dealloc" and scope.lookup_here("__dealloc__") is None: - continue - if slot.slot_name == "tp_getattro": - has_tp_getattro = True - if slot.slot_name == "tp_as_number": - slot.generate_substructure_spec(scope, code) - continue - if slot.slot_name == "tp_as_sequence": - slot.generate_substructure_spec(scope, code) - continue - if slot.slot_name == "tp_as_mapping": - slot.generate_substructure_spec(scope, code) - continue - if slot.slot_name == "tp_as_buffer": # Can't support tp_as_buffer - continue - v = TypeSlots.get_slot_by_name(slot.slot_name).spec_slot_value(scope) - if v is not None: - code.putln(" {Py_%s, (void *)%s}," % (slot.slot_name, v)) - if not has_tp_getattro: - code.putln(" {Py_tp_getattro, __Pyx_PyObject_GenericGetAttr},") - code.putln(" {0, 0},") - code.putln("};") - code.putln("static PyType_Spec %s_spec = {" % type.typeobj_cname) - code.putln(" \"%s.%s\"," % (self.full_module_name, classname.replace("\"", ""))) - code.putln(" sizeof(%s)," % objstruct) - code.putln(" 0,") - code.putln(" %s," % TypeSlots.get_slot_by_name("tp_flags").spec_slot_value(scope)) - code.putln(" %s_slots," % type.typeobj_cname) + code.putln('"%s.%s",' % (self.full_module_name, classname.replace('"', ''))) + code.putln("sizeof(%s)," % objstruct) + code.putln("0,") + code.putln("%s," % TypeSlots.get_slot_by_name("tp_flags").slot_code(scope)) + code.putln("%s_slots," % type.typeobj_cname) code.putln("};") def generate_typeobj_definition(self, modname, entry, code): diff --git a/Cython/Compiler/TypeSlots.py b/Cython/Compiler/TypeSlots.py index 5ff5d8e3c..4236e8ec6 100644 --- a/Cython/Compiler/TypeSlots.py +++ b/Cython/Compiler/TypeSlots.py @@ -229,6 +229,12 @@ class SlotDescriptor(object): self.py3 = py3 self.py2 = py2 + def slot_code(self, scope): + raise NotImplemented() + + def spec_value(self, scope): + return self.slot_code(scope) + def preprocessor_guard_code(self): ifdef = self.ifdef py2 = self.py2 @@ -242,15 +248,20 @@ class SlotDescriptor(object): guard = ("#if PY_MAJOR_VERSION >= 3") return guard - def spec_slot_value(self, scope): + def generate_spec(self, scope, code): if self.is_initialised_dynamically: - return None - result = self.slot_code(scope) - if result == "0": - return None - return result + return + value = self.spec_value(scope) + if value == "0": + return + preprocessor_guard = self.preprocessor_guard_code() + if preprocessor_guard: + code.putln(preprocessor_guard) + code.putln("{Py_%s, (void *)%s}," % (self.slot_name, value)) + if preprocessor_guard: + code.putln("#endif") - def generate(self, scope, code, spec=False): + def generate(self, scope, code): preprocessor_guard = self.preprocessor_guard_code() if preprocessor_guard: code.putln(preprocessor_guard) @@ -279,11 +290,7 @@ class SlotDescriptor(object): code.putln("#else") end_pypy_guard = True - if spec: - if value != "0": - code.putln("{Py_%s, (void *)%s}," % (self.slot_name, value)) - else: - code.putln("%s, /*%s*/" % (value, self.slot_name)) + code.putln("%s, /*%s*/" % (value, self.slot_name)) if end_pypy_guard: code.putln("#endif") @@ -449,6 +456,11 @@ class ConstructorSlot(InternalMethodSlot): return slot_code or '0' return InternalMethodSlot.slot_code(self, scope) + def spec_value(self, scope): + if self.slot_name == "tp_dealloc" and not scope.lookup_here("__dealloc__"): + return "0" + return self.slot_code(scope) + def generate_dynamic_init_code(self, scope, code): if self.slot_code(scope) != '0': return @@ -484,6 +496,11 @@ class SyntheticSlot(InternalMethodSlot): else: return self.default_value + def spec_value(self, scope): + if self.slot_name == "tp_getattro" and not scope.defines_any_special(self.user_methods): + return "__Pyx_PyObject_GenericGetAttr" + return self.slot_code(scope) + class RichcmpSlot(MethodSlot): def slot_code(self, scope): @@ -514,6 +531,10 @@ class TypeFlagsSlot(SlotDescriptor): value += "|Py_TPFLAGS_HAVE_GC" return value + def generate_spec(self, scope, code): + # Flags are stored in the PyType_Spec, not in a PyType_Slot. + return + class DocStringSlot(SlotDescriptor): # Descriptor for the docstring slot. @@ -567,10 +588,12 @@ class SuiteSlot(SlotDescriptor): if self.ifdef: code.putln("#endif") - def generate_substructure_spec(self, scope, code): - if not self.is_empty(scope): - for slot in self.sub_slots: - slot.generate(scope, code, spec=True) + def generate_spec(self, scope, code): + if self.slot_name == "tp_as_buffer": + # Cannot currently support the buffer protocol in the limited C-API. + return + for slot in self.sub_slots: + slot.generate_spec(scope, code) substructures = [] # List of all SuiteSlot instances |