summaryrefslogtreecommitdiff
path: root/Cython/Compiler/ModuleNode.py
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2014-01-12 10:16:15 +0100
committerStefan Behnel <stefan_ml@behnel.de>2014-01-12 10:16:15 +0100
commit1a56a04bfe1b8460ecf3886c3de9268cb5e0c93a (patch)
treecdb64b4ec743987bf1973a317ba1af2dd0c4dabc /Cython/Compiler/ModuleNode.py
parent6b47bbfe0c86f90b7407e2c59ee5f02db175d16a (diff)
downloadcython-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.py17
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('}')