@@ -154,26 +154,11 @@ CFunction::CFunction(unsigned long ulAddr, object oCallingConvention, object oAr
154154
155155 // A custom calling convention will be used...
156156 m_eCallingConvention = CONV_CUSTOM ;
157-
158- // Check if default_convention is defined.
159- if (PyObject_HasAttrString (oCallingConvention.ptr (), " default_convention" ))
160- {
161- // Extract default_convention and pass it to oCallingConvention.
162- Convention_t eCallingConvention = extract<Convention_t>(oCallingConvention.attr (" default_convention" ));
163- m_oCallingConvention = oCallingConvention (m_tArgs, m_eReturnType, 4 , eCallingConvention);
164- }
165- else
166- {
167- m_oCallingConvention = oCallingConvention (m_tArgs, m_eReturnType);
168- }
169-
157+ m_oCallingConvention = oCallingConvention (m_tArgs, m_eReturnType);
170158 m_pCallingConvention = extract<ICallingConvention*>(m_oCallingConvention);
171159
172160 // Reserve a Python reference for DynamicHooks.
173161 Py_INCREF (m_oCallingConvention.ptr ());
174-
175- // Initialize our wrapper so that Python overrides are properly resolved.
176- detail::initialize_wrapper (m_oCallingConvention.ptr (), get_pointer ((ICallingConventionWrapper *)m_pCallingConvention));
177162 }
178163
179164 // Step 4: Get the DynCall calling convention
@@ -196,8 +181,11 @@ CFunction::CFunction(unsigned long ulAddr, Convention_t eCallingConvention,
196181
197182CFunction::~CFunction ()
198183{
184+ if (!m_pCallingConvention)
185+ return ;
186+
199187 // If the convention isn't flagged as hooked, then we need to take care of it.
200- if (m_pCallingConvention && !m_pCallingConvention->m_bHooked )
188+ if (!m_pCallingConvention->m_bHooked )
201189 {
202190 // If we don't have a Python instance, then we can safely delete it.
203191 if (m_oCallingConvention.is_none ())
@@ -206,6 +194,10 @@ CFunction::~CFunction()
206194 else if (Py_REFCNT (m_oCallingConvention.ptr ()) > 1 )
207195 Py_DECREF (m_oCallingConvention.ptr ());
208196 }
197+ // If we are using a built-in convention that is currently hooked, let's flag it as no longer hooked
198+ // so that we know we are not bound to a CFunction anymore and can be deleted.
199+ else if (m_eCallingConvention != CONV_CUSTOM && !dynamic_cast <ICallingConventionWrapper *>(m_pCallingConvention))
200+ m_pCallingConvention->m_bHooked = false ;
209201
210202 m_pCallingConvention = NULL ;
211203}
@@ -439,17 +431,24 @@ void CFunction::DeleteHook()
439431
440432 g_mapCallbacks.erase (pHook);
441433
442- // Flag the convention as no longer hooked and being taken care of by DynamicHooks.
443- pHook->m_pCallingConvention ->m_bHooked = false ;
444-
445- // Release the Python reference we reserved for DynamicHooks.
446434 ICallingConventionWrapper *pConv = dynamic_cast <ICallingConventionWrapper *>(pHook->m_pCallingConvention );
447435 if (pConv)
448436 {
449- PyObject *pOwner = detail::wrapper_base_::owner (pConv);
450- if (pOwner && Py_REFCNT (pOwner))
451- Py_DECREF (pOwner);
437+ if (pConv->m_bHooked )
438+ {
439+ // Flag the convention as no longer hooked and being taken care of by DynamicHooks.
440+ pHook->m_pCallingConvention ->m_bHooked = false ;
441+
442+ // Release the Python reference we reserved for DynamicHooks.
443+ PyObject *pOwner = detail::wrapper_base_::owner (pConv);
444+ if (pOwner && Py_REFCNT (pOwner))
445+ Py_DECREF (pOwner);
446+ }
452447 }
448+ // If we are a built-in convention bound to a CHook instance but not flagged as hooked anymore, then that
449+ // means we are no longer bound to a CFunction instance and can be safely deleted.
450+ else if (!pHook->m_pCallingConvention ->m_bHooked )
451+ delete pHook->m_pCallingConvention ;
453452
454453 // Set the calling convention to NULL, because DynamicHooks will delete it otherwise.
455454 pHook->m_pCallingConvention = NULL ;
0 commit comments