diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2014-01-12 10:16:15 +0100 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2014-01-12 10:16:15 +0100 |
commit | 1a56a04bfe1b8460ecf3886c3de9268cb5e0c93a (patch) | |
tree | cdb64b4ec743987bf1973a317ba1af2dd0c4dabc /Cython/Compiler/ModuleNode.py | |
parent | 6b47bbfe0c86f90b7407e2c59ee5f02db175d16a (diff) | |
download | cython-1a56a04bfe1b8460ecf3886c3de9268cb5e0c93a.tar.gz |
call object.__new__() only when we expect an error due to an abstract class being instantiated
Diffstat (limited to 'Cython/Compiler/ModuleNode.py')
-rw-r--r-- | Cython/Compiler/ModuleNode.py | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 13d626b03..02bac9cbd 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -1075,6 +1075,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): have_entries, (py_attrs, py_buffers, memoryview_slices) = \ scope.get_refcounted_entries() + is_final_type = scope.parent_type.is_final_type if scope.is_internal: # internal classes (should) never need None inits, normal zeroing will do py_attrs = [] @@ -1124,9 +1125,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): if freelist_size: code.globalstate.use_utility_code( UtilityCode.load_cached("IncludeStringH", "StringTools.c")) + if is_final_type: + abstract_check = '' + else: + abstract_check = ' & ((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)' obj_struct = type.declaration_code("", deref=True) - code.putln("if (likely((%s > 0) & (t->tp_basicsize == sizeof(%s)) & ((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0))) {" % ( - freecount_name, obj_struct)) + code.putln("if (likely((%s > 0) & (t->tp_basicsize == sizeof(%s))%s)) {" % ( + freecount_name, obj_struct, abstract_check)) code.putln("o = (PyObject*)%s[--%s];" % ( freelist_name, freecount_name)) code.putln("memset(o, 0, sizeof(%s));" % obj_struct) @@ -1134,7 +1139,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): if scope.needs_gc(): code.putln("PyObject_GC_Track(o);") code.putln("} else {") - code.putln("o = (PyObject *) PyBaseObject_Type.tp_new(t, %s, 0);" % Naming.empty_tuple) + if not is_final_type: + code.putln("if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {") + code.putln("o = (*t->tp_alloc)(t, 0);") + if not is_final_type: + code.putln("} else {") + code.putln("o = (PyObject *) PyBaseObject_Type.tp_new(t, %s, 0);" % Naming.empty_tuple) + code.putln("}") code.putln("if (unlikely(!o)) return 0;") if freelist_size and not base_type: code.putln('}') |