@@ -154,26 +154,11 @@ CFunction::CFunction(unsigned long ulAddr, object oCallingConvention, object oAr
154
154
155
155
// A custom calling convention will be used...
156
156
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);
170
158
m_pCallingConvention = extract<ICallingConvention*>(m_oCallingConvention);
171
159
172
160
// Reserve a Python reference for DynamicHooks.
173
161
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));
177
162
}
178
163
179
164
// Step 4: Get the DynCall calling convention
@@ -196,8 +181,11 @@ CFunction::CFunction(unsigned long ulAddr, Convention_t eCallingConvention,
196
181
197
182
CFunction::~CFunction ()
198
183
{
184
+ if (!m_pCallingConvention)
185
+ return ;
186
+
199
187
// 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 )
201
189
{
202
190
// If we don't have a Python instance, then we can safely delete it.
203
191
if (m_oCallingConvention.is_none ())
@@ -206,6 +194,10 @@ CFunction::~CFunction()
206
194
else if (Py_REFCNT (m_oCallingConvention.ptr ()) > 1 )
207
195
Py_DECREF (m_oCallingConvention.ptr ());
208
196
}
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 ;
209
201
210
202
m_pCallingConvention = NULL ;
211
203
}
@@ -439,17 +431,24 @@ void CFunction::DeleteHook()
439
431
440
432
g_mapCallbacks.erase (pHook);
441
433
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.
446
434
ICallingConventionWrapper *pConv = dynamic_cast <ICallingConventionWrapper *>(pHook->m_pCallingConvention );
447
435
if (pConv)
448
436
{
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
+ }
452
447
}
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 ;
453
452
454
453
// Set the calling convention to NULL, because DynamicHooks will delete it otherwise.
455
454
pHook->m_pCallingConvention = NULL ;
0 commit comments