@@ -142,6 +142,9 @@ CFunction::CFunction(unsigned long ulAddr, object oCallingConvention, object oAr
142142 // If this line succeeds the user wants to create a function with the built-in calling conventions
143143 m_eCallingConvention = extract<Convention_t>(oCallingConvention);
144144 m_pCallingConvention = MakeDynamicHooksConvention (m_eCallingConvention, ObjectToDataTypeVector (m_tArgs), m_eReturnType);
145+
146+ // We allocated the calling convention, we are responsible to cleanup.
147+ m_bAllocatedCallingConvention = true ;
145148 }
146149 catch ( ... )
147150 {
@@ -154,8 +157,12 @@ CFunction::CFunction(unsigned long ulAddr, object oCallingConvention, object oAr
154157 // FIXME:
155158 // This is required to fix a crash, but it will also cause a memory leak,
156159 // because no calling convention object that is created via this method will ever be deleted.
160+ // TODO: Pretty sure this was required due to the missing held type definition. It was added, but wasn't tested yet.
157161 Py_INCREF (_oCallingConvention.ptr ());
158162 m_pCallingConvention = extract<ICallingConvention*>(_oCallingConvention);
163+
164+ // We didn't allocate the calling convention, someone else is responsible for it.
165+ m_bAllocatedCallingConvention = false ;
159166 }
160167
161168 // Step 4: Get the DynCall calling convention
@@ -170,11 +177,32 @@ CFunction::CFunction(unsigned long ulAddr, Convention_t eCallingConvention,
170177 m_eCallingConvention = eCallingConvention;
171178 m_iCallingConvention = iCallingConvention;
172179 m_pCallingConvention = pCallingConvention;
180+
181+ // We didn't allocate the calling convention, someone else is responsible for it.
182+ m_bAllocatedCallingConvention = false ;
183+
173184 m_tArgs = tArgs;
174185 m_eReturnType = eReturnType;
175186 m_oConverter = oConverter;
176187}
177188
189+ CFunction::~CFunction ()
190+ {
191+ // If we didn't allocate the calling convention, then it is not our responsibility.
192+ if (!m_bAllocatedCallingConvention)
193+ return ;
194+
195+ CHook* pHook = GetHookManager ()->FindHook ((void *) m_ulAddr);
196+
197+ // DynamicHooks will take care of it for us from there.
198+ if (pHook && pHook->m_pCallingConvention == m_pCallingConvention)
199+ return ;
200+
201+ // Cleanup.
202+ delete m_pCallingConvention;
203+ m_pCallingConvention = NULL ;
204+ }
205+
178206bool CFunction::IsCallable ()
179207{
180208 return (m_eCallingConvention != CONV_CUSTOM ) && (m_iCallingConvention != -1 );
0 commit comments