Commit 721f6ecd authored by Mark Florisson's avatar Mark Florisson

Share code object between specializations

parent d5103c1f
......@@ -2246,6 +2246,8 @@ class FusedCFuncDefNode(StatListNode):
defaults would result in many different tuples)
specialized_pycfuncs List of synthesized pycfunction nodes for the
specializations
code_object CodeObjectNode shared by all specializations and the
fused function
"""
__signatures__ = None
......@@ -2669,11 +2671,15 @@ def __pyx_fused_cpdef(signatures, args, kwargs):
defaults_tuple = TupleNode(self.pos, args=args)
defaults_tuple.analyse_types(env, skip_children=True)
self.defaults_tuple = ProxyNode(defaults_tuple)
self.code_object = ProxyNode(self.specialized_pycfuncs[0].code_object)
fused_func = self.resulting_fused_function.arg
fused_func.defaults_tuple = CloneNode(self.defaults_tuple)
fused_func.code_object = CloneNode(self.code_object)
self.resulting_fused_function.arg.defaults_tuple = CloneNode(
self.defaults_tuple)
for pycfunc in self.specialized_pycfuncs:
pycfunc.defaults_tuple = CloneNode(self.defaults_tuple)
pycfunc.code_object = CloneNode(self.code_object)
def synthesize_defnodes(self):
"""
......@@ -2719,6 +2725,7 @@ def __pyx_fused_cpdef(signatures, args, kwargs):
if self.py_func:
self.defaults_tuple.generate_evaluation_code(code)
self.code_object.generate_evaluation_code(code)
for stat in self.stats:
code.mark_pos(stat.pos)
......@@ -2741,6 +2748,7 @@ def __pyx_fused_cpdef(signatures, args, kwargs):
# Dispose of results
self.resulting_fused_function.generate_disposal_code(code)
self.defaults_tuple.generate_disposal_code(code)
self.code_object.generate_disposal_code(code)
for default in self.defaults:
if default is not None:
......
......@@ -5,6 +5,8 @@
### low level tests
cimport cython
cdef extern from *:
# evil hack to access the internal utility function
ctypedef struct PyCodeObject
......@@ -97,3 +99,31 @@ def assert_multi_step_code_object_reuse(recursions=0):
assert_multi_step_code_object_reuse(recursions-1)
else:
raise_keyerror()
def assert_simple_code_object_reuse_fused(cython.floating dummy):
"""
DISABLED: searching for code objects based on C lineno breaks for specializations
>> try: assert_simple_code_object_reuse_fused["float"](1.0)
... except KeyError: t1 = tb()
>> try: assert_simple_code_object_reuse_fused["double"](1.0)
... except KeyError: t2 = tb()
>> check_code_object_identity_recursively(t1.tb_next, t2.tb_next)
"""
raise KeyError
def assert_multi_step_code_object_reuse_fused(recursions=0, cython.floating dummy = 2.0):
"""
DISABLED: searching for code objects based on C lineno breaks for specializations
>> for depth in range(5):
... try: assert_multi_step_code_object_reuse_fused(depth, 1.0)
... except KeyError: t1 = tb()
... try: assert_multi_step_code_object_reuse_fused(depth, 1.0)
... except KeyError: t2 = tb()
... check_code_object_identity_recursively(t1.tb_next, t2.tb_next)
"""
if recursions:
assert_multi_step_code_object_reuse(recursions-1)
else:
raise_keyerror()
......@@ -294,3 +294,13 @@ cdef class CBaseClass(object):
def __repr__(self):
return "<%s.%s object>" % (__name__, type(self).__name__)
def getcode(func):
return getattr(func, '__code__', None) or func.func_code
def test_code_object(cython.floating dummy = 2.0):
"""
A test for default arguments is in cyfunction_defaults
>>> getcode(test_code_object) is getcode(test_code_object[float])
True
"""
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