Commit fe4c5c0c authored by Stefan Behnel's avatar Stefan Behnel

try a potentially safer way to find out if we know the tp_new slot function of a type

parent 84c076b2
from Cython.Compiler import TypeSlots
from Cython.Compiler.ExprNodes import not_a_constant from Cython.Compiler.ExprNodes import not_a_constant
import cython import cython
cython.declare(UtilityCode=object, EncodedString=object, BytesLiteral=object, cython.declare(UtilityCode=object, EncodedString=object, BytesLiteral=object,
...@@ -2182,25 +2183,27 @@ class OptimizeBuiltinCalls(Visitor.MethodDispatcherTransform): ...@@ -2182,25 +2183,27 @@ class OptimizeBuiltinCalls(Visitor.MethodDispatcherTransform):
if type_arg.type_entry: if type_arg.type_entry:
ext_type = type_arg.type_entry.type ext_type = type_arg.type_entry.type
if ext_type.is_extension_type and not ext_type.is_external: if ext_type.is_extension_type and not ext_type.is_external:
cython_scope = self.context.cython_scope tp_slot = TypeSlots.ConstructorSlot("tp_new", '__new__')
PyTypeObjectPtr = PyrexTypes.CPtrType( slot_func_cname = TypeSlots.get_slot_function(ext_type.scope, tp_slot)
cython_scope.lookup('PyTypeObject').type) if slot_func_cname:
pyx_tp_new_kwargs_func_type = PyrexTypes.CFuncType( cython_scope = self.context.cython_scope
PyrexTypes.py_object_type, [ PyTypeObjectPtr = PyrexTypes.CPtrType(
PyrexTypes.CFuncTypeArg("type", PyTypeObjectPtr, None), cython_scope.lookup('PyTypeObject').type)
PyrexTypes.CFuncTypeArg("args", PyrexTypes.py_object_type, None), pyx_tp_new_kwargs_func_type = PyrexTypes.CFuncType(
PyrexTypes.CFuncTypeArg("kwargs", PyrexTypes.py_object_type, None), PyrexTypes.py_object_type, [
]) PyrexTypes.CFuncTypeArg("type", PyTypeObjectPtr, None),
PyrexTypes.CFuncTypeArg("args", PyrexTypes.py_object_type, None),
type_arg = ExprNodes.CastNode(type_arg, PyTypeObjectPtr) PyrexTypes.CFuncTypeArg("kwargs", PyrexTypes.py_object_type, None),
slot_func_cname = ext_type.scope.mangle_internal("tp_new") ])
if not kwargs:
kwargs = ExprNodes.NullNode(node.pos, type=PyrexTypes.py_object_type) # hack? type_arg = ExprNodes.CastNode(type_arg, PyTypeObjectPtr)
return ExprNodes.PythonCapiCallNode( if not kwargs:
node.pos, slot_func_cname, kwargs = ExprNodes.NullNode(node.pos, type=PyrexTypes.py_object_type) # hack?
pyx_tp_new_kwargs_func_type, return ExprNodes.PythonCapiCallNode(
args=[type_arg, args_tuple, kwargs], node.pos, slot_func_cname,
is_temp=True) pyx_tp_new_kwargs_func_type,
args=[type_arg, args_tuple, kwargs],
is_temp=True)
else: else:
# arbitrary variable, needs a None check for safety # arbitrary variable, needs a None check for safety
type_arg = type_arg.as_none_safe_node( type_arg = type_arg.as_none_safe_node(
......
...@@ -493,11 +493,13 @@ def get_special_method_signature(name): ...@@ -493,11 +493,13 @@ def get_special_method_signature(name):
else: else:
return None return None
def get_property_accessor_signature(name): def get_property_accessor_signature(name):
# Return signature of accessor for an extension type # Return signature of accessor for an extension type
# property, else None. # property, else None.
return property_accessor_signatures.get(name) return property_accessor_signatures.get(name)
def get_base_slot_function(scope, slot): def get_base_slot_function(scope, slot):
# Returns the function implementing this slot in the baseclass. # Returns the function implementing this slot in the baseclass.
# This is useful for enabling the compiler to optimize calls # This is useful for enabling the compiler to optimize calls
...@@ -511,6 +513,18 @@ def get_base_slot_function(scope, slot): ...@@ -511,6 +513,18 @@ def get_base_slot_function(scope, slot):
return parent_slot return parent_slot
return None return None
def get_slot_function(scope, slot):
# Returns the function implementing this slot in the baseclass.
# This is useful for enabling the compiler to optimize calls
# that recursively climb the class hierarchy.
slot_code = slot.slot_code(scope)
if slot_code != '0':
entry = scope.parent_scope.lookup_here(scope.parent_type.name)
if entry.visibility != 'extern':
return slot_code
return None
#------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------
# #
# Signatures for generic Python functions and methods. # Signatures for generic Python functions and methods.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment