diff --git a/addons/source-python/packages/source-python/memory/helpers.py b/addons/source-python/packages/source-python/memory/helpers.py old mode 100644 new mode 100755 index 4f7ec86c4..c113f5887 --- a/addons/source-python/packages/source-python/memory/helpers.py +++ b/addons/source-python/packages/source-python/memory/helpers.py @@ -316,9 +316,7 @@ class MemberFunction(Function): def __init__(self, manager, return_type, func, this): """Initialize the instance.""" self._function = func - super().__init__( - func.address, func.convention, func.arguments, func.return_type - ) + super().__init__(func) # This should always hold a TypeManager instance self._manager = manager diff --git a/src/core/modules/memory/memory_function.cpp b/src/core/modules/memory/memory_function.cpp index e81ff68b4..6f91149c4 100755 --- a/src/core/modules/memory/memory_function.cpp +++ b/src/core/modules/memory/memory_function.cpp @@ -179,6 +179,29 @@ CFunction::CFunction(unsigned long ulAddr, Convention_t eCallingConvention, m_oConverter = oConverter; } +CFunction::CFunction(const CFunction& obj) + :CPointer(obj) +{ + m_tArgs = obj.m_tArgs; + m_eReturnType = obj.m_eReturnType; + m_oConverter = obj.m_oConverter; + + m_eCallingConvention = obj.m_eCallingConvention; + m_iCallingConvention = obj.m_iCallingConvention; + + if (m_eCallingConvention != CONV_CUSTOM) + { + m_pCallingConvention = MakeDynamicHooksConvention(m_eCallingConvention, ObjectToDataTypeVector(m_tArgs), m_eReturnType); + m_oCallingConvention = object(); + } + else + { + m_pCallingConvention = obj.m_pCallingConvention; + m_oCallingConvention = obj.m_oCallingConvention; + Py_INCREF(m_oCallingConvention.ptr()); + } +} + CFunction::~CFunction() { if (!m_pCallingConvention) diff --git a/src/core/modules/memory/memory_function.h b/src/core/modules/memory/memory_function.h index b680dca26..9e78dc58d 100755 --- a/src/core/modules/memory/memory_function.h +++ b/src/core/modules/memory/memory_function.h @@ -53,13 +53,15 @@ enum Convention_t // ============================================================================ // >> CFunction // ============================================================================ -class CFunction: public CPointer, private boost::noncopyable +class CFunction: public CPointer { public: CFunction(unsigned long ulAddr, object oCallingConvention, object oArgs, object oReturnType); CFunction(unsigned long ulAddr, Convention_t eCallingConvention, int iCallingConvention, boost::python::tuple tArgs, DataType_t eReturnType, object oConverter); + CFunction(const CFunction& obj); + ~CFunction(); bool IsCallable(); @@ -105,7 +107,6 @@ class CFunction: public CPointer, private boost::noncopyable // DynamicHooks calling convention (built-in and custom) ICallingConvention* m_pCallingConvention; - bool m_bAllocatedCallingConvention; // Custom calling convention object m_oCallingConvention; diff --git a/src/core/modules/memory/memory_wrap.cpp b/src/core/modules/memory/memory_wrap.cpp index 828d9942a..d4c1c5709 100755 --- a/src/core/modules/memory/memory_wrap.cpp +++ b/src/core/modules/memory/memory_wrap.cpp @@ -453,9 +453,9 @@ void export_type_info_iter(scope _memory) // ============================================================================ void export_function(scope _memory) { - class_, boost::noncopyable >("Function", init()) - // Don't allow copies, because they will hold references to our calling convention. - // .def(init()) + class_ >("Function", init()) + .def(init()) + .def("__call__", raw_method(&CFunction::Call), "Calls the function dynamically."