diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2014-01-19 20:18:50 +0100 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2014-01-19 20:18:50 +0100 |
commit | d557a3d71780967782d89e22eacebcc1b2b195fc (patch) | |
tree | 33fefe18e861984ea89a2203f12a4d6a1033a77e /Cython/Compiler/ModuleNode.py | |
parent | df302bfc3d78b677692a0826cab77eea80d8ead7 (diff) | |
download | cython-d557a3d71780967782d89e22eacebcc1b2b195fc.tar.gz |
generate cdef classes and closure classes in a deterministic order to reduce C code churn on regeneration
also fixes a problem where duplicate entries (one used, one unused) could be selected somewhat arbitrarily during type sorting (apparently applied to but worked for memoryview/-slice)
Diffstat (limited to 'Cython/Compiler/ModuleNode.py')
-rw-r--r-- | Cython/Compiler/ModuleNode.py | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index ce7de2659..62b75808d 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -411,13 +411,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): self.find_referenced_modules(imported_module, module_list, modules_seen) module_list.append(env) - def sort_types_by_inheritance(self, type_dict, getkey): + def sort_types_by_inheritance(self, type_dict, type_order, getkey): # copy the types into a list moving each parent type before # its first child - type_items = type_dict.items() type_list = [] - for i, item in enumerate(type_items): - key, new_entry = item + for i, key in enumerate(type_order): + new_entry = type_dict[key] # collect all base classes to check for children hierarchy = set() @@ -442,43 +441,52 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): return type_list def sort_type_hierarchy(self, module_list, env): - vtab_dict = {} - vtabslot_dict = {} + # poor developer's OrderedDict + vtab_dict, vtab_dict_order = {}, [] + vtabslot_dict, vtabslot_dict_order = {}, [] for module in module_list: for entry in module.c_class_entries: - if not entry.in_cinclude: + if entry.used and not entry.in_cinclude: type = entry.type - if type.vtabstruct_cname: - vtab_dict[type.vtabstruct_cname] = entry + key = type.vtabstruct_cname + if not key: + continue + assert key not in vtab_dict, key + vtab_dict[key] = entry + vtab_dict_order.append(key) all_defined_here = module is env for entry in module.type_entries: - if all_defined_here or entry.defined_in_pxd: + if entry.used and (all_defined_here or entry.defined_in_pxd): type = entry.type if type.is_extension_type and not entry.in_cinclude: type = entry.type - vtabslot_dict[type.objstruct_cname] = entry + key = type.objstruct_cname + assert key not in vtabslot_dict, key + vtabslot_dict[key] = entry + vtabslot_dict_order.append(key) def vtabstruct_cname(entry_type): return entry_type.vtabstruct_cname vtab_list = self.sort_types_by_inheritance( - vtab_dict, vtabstruct_cname) + vtab_dict, vtab_dict_order, vtabstruct_cname) def objstruct_cname(entry_type): return entry_type.objstruct_cname vtabslot_list = self.sort_types_by_inheritance( - vtabslot_dict, objstruct_cname) + vtabslot_dict, vtabslot_dict_order, objstruct_cname) return (vtab_list, vtabslot_list) def sort_cdef_classes(self, env): key_func = operator.attrgetter('objstruct_cname') - entry_dict = {} + entry_dict, entry_order = {}, [] for entry in env.c_class_entries: key = key_func(entry.type) - assert key not in entry_dict + assert key not in entry_dict, key entry_dict[key] = entry + entry_order.append(key) env.c_class_entries[:] = self.sort_types_by_inheritance( - entry_dict, key_func) + entry_dict, entry_order, key_func) def generate_type_definitions(self, env, modules, vtab_list, vtabslot_list, code): # TODO: Why are these separated out? |