From c3c2ff654a3bfe8b6145d638660e5dc2f0fb96cd Mon Sep 17 00:00:00 2001 From: Jonathan <30329245+CookStar@users.noreply.github.com> Date: Fri, 14 May 2021 01:49:16 +0900 Subject: [PATCH 1/3] Fixed MemberFunction not returning the correct return type. --- addons/source-python/packages/source-python/memory/helpers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/source-python/packages/source-python/memory/helpers.py b/addons/source-python/packages/source-python/memory/helpers.py index 4f7ec86c4..f2a676421 100644 --- a/addons/source-python/packages/source-python/memory/helpers.py +++ b/addons/source-python/packages/source-python/memory/helpers.py @@ -317,7 +317,8 @@ 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 + func.address, func.convention, func.arguments, + func.return_type if func.converter is None else func.converter ) # This should always hold a TypeManager instance From 414535307762a7762006e1da27051605be358a0c Mon Sep 17 00:00:00 2001 From: Jonathan <30329245+CookStar@users.noreply.github.com> Date: Sun, 16 May 2021 11:45:56 +0900 Subject: [PATCH 2/3] Restored copy constructor of CFunction. --- src/core/modules/memory/memory_function.cpp | 23 +++++++++++++++++++++ src/core/modules/memory/memory_function.h | 5 +++-- src/core/modules/memory/memory_wrap.cpp | 6 +++--- 3 files changed, 29 insertions(+), 5 deletions(-) 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." From 71f7511f22c795a9cbfe631a77602ae1ebe4683e Mon Sep 17 00:00:00 2001 From: Jonathan <30329245+CookStar@users.noreply.github.com> Date: Sun, 16 May 2021 11:50:52 +0900 Subject: [PATCH 3/3] Changed MemberFunction to be initialized from a copy. --- .../source-python/packages/source-python/memory/helpers.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) mode change 100644 => 100755 addons/source-python/packages/source-python/memory/helpers.py 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 f2a676421..c113f5887 --- a/addons/source-python/packages/source-python/memory/helpers.py +++ b/addons/source-python/packages/source-python/memory/helpers.py @@ -316,10 +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 if func.converter is None else func.converter - ) + super().__init__(func) # This should always hold a TypeManager instance self._manager = manager