From 601fec8048151ee07d0ccf3a40a26c4ba7d7a5f5 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Sun, 22 Sep 2019 12:30:08 +0200 Subject: [PATCH] Fix static delegate functions being garbage collected --- PorygonSharp/EvalValues/DelegateEvalValue.cs | 10 +++--- PorygonSharp/EvalValues/EvalValue.cs | 32 +++++++++++--------- PorygonSharp/EvalValues/EvalValueCreator.cs | 3 +- PorygonSharp/StaticScope.cs | 2 ++ PorygonSharp/Utilities/Caster.cs | 1 - 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/PorygonSharp/EvalValues/DelegateEvalValue.cs b/PorygonSharp/EvalValues/DelegateEvalValue.cs index da20220..f1f3d27 100644 --- a/PorygonSharp/EvalValues/DelegateEvalValue.cs +++ b/PorygonSharp/EvalValues/DelegateEvalValue.cs @@ -5,21 +5,21 @@ using PorygonSharp.Utilities; namespace PorygonSharp.EvalValues { - public class DelegateEvalValue + public class DelegateEvalValue : EvalValue { private delegate IntPtr InvokeDelegate(IntPtr _, IntPtr options, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]IntPtr[] parameters, int parameterCount); private readonly Delegate _delegate; private readonly InvokeDelegate _handler; - public readonly IntPtr Pointer; + private readonly IntPtr _funcPtr; public DelegateEvalValue(Delegate del) { _delegate = del; _handler = Invoke; - var funcPtr = Marshal.GetFunctionPointerForDelegate(_handler); - Pointer = EvalValueCreator.CreateFunctionEvalValue(funcPtr, IntPtr.Zero); + _funcPtr = Marshal.GetFunctionPointerForDelegate(_handler); + Handle = EvalValueCreator.CreateFunctionEvalValue(_funcPtr, IntPtr.Zero); } private IntPtr Invoke(IntPtr _, IntPtr options, IntPtr[] parPtrs, int parameterCount) @@ -35,7 +35,5 @@ namespace PorygonSharp.EvalValues var result = _delegate.DynamicInvoke(parameters); return EvalValueCreator.CreateValue(result).GetPointer(); } - - } } \ No newline at end of file diff --git a/PorygonSharp/EvalValues/EvalValue.cs b/PorygonSharp/EvalValues/EvalValue.cs index 4f64a7e..602f6c7 100644 --- a/PorygonSharp/EvalValues/EvalValue.cs +++ b/PorygonSharp/EvalValues/EvalValue.cs @@ -6,49 +6,51 @@ namespace PorygonSharp.EvalValues { public class EvalValue : IDisposable { - private IntPtr _handle; + protected IntPtr Handle; public EvalValue(IntPtr handle) { - _handle = handle; + Handle = handle; } + + protected EvalValue(){} public void Dispose() { - if (_handle != IntPtr.Zero) + if (Handle != IntPtr.Zero) { - Marshal.FreeHGlobal(_handle); - _handle = IntPtr.Zero; + Marshal.FreeHGlobal(Handle); + Handle = IntPtr.Zero; } } public TypeClass GetTypeClass() { - return (TypeClass)GetTypeClass(_handle); + return (TypeClass)GetTypeClass(Handle); } public long EvaluateInteger() { - return EvaluateInteger(_handle); + return EvaluateInteger(Handle); } public double EvaluateFloat() { - return EvaluateFloat(_handle); + return EvaluateFloat(Handle); } public bool EvaluateBool() { - return EvaluateBool(_handle) == 1; + return EvaluateBool(Handle) == 1; } public string EvaluateString() { - var stringLength = GetStringLength(_handle); + var stringLength = GetStringLength(Handle); // The library uses 16 bit chars for strings, so create a byte array of twice the length given. var byteArr = new byte[stringLength * 2]; - var result = EvaluateString(_handle, byteArr, stringLength); + var result = EvaluateString(Handle, byteArr, stringLength); if (result != 0) { throw new Exception("Something went wrong while evaluating a string."); @@ -59,13 +61,13 @@ namespace PorygonSharp.EvalValues private object EvaluateGenericObject() { - var ptr = EvaluateUserDataObj(_handle); + var ptr = EvaluateUserDataObj(Handle); return GCHandle.FromIntPtr(ptr).Target; } public object GetObjectValue() { - if (_handle == IntPtr.Zero) + if (Handle == IntPtr.Zero) return null; switch (GetTypeClass()) { @@ -80,7 +82,7 @@ namespace PorygonSharp.EvalValues case TypeClass.UserData: return EvaluateGenericObject(); case TypeClass.Table: - var val = new TableEvalValue(_handle); + var val = new TableEvalValue(Handle); return val.EvaluateNumericalTable(); default: throw new ArgumentOutOfRangeException(); @@ -89,7 +91,7 @@ namespace PorygonSharp.EvalValues internal IntPtr GetPointer() { - return _handle; + return Handle; } [DllImport("PorygonLang", EntryPoint = "GetEvalValueTypeClass", CallingConvention = CallingConvention.Cdecl)] diff --git a/PorygonSharp/EvalValues/EvalValueCreator.cs b/PorygonSharp/EvalValues/EvalValueCreator.cs index cc5c698..488f000 100644 --- a/PorygonSharp/EvalValues/EvalValueCreator.cs +++ b/PorygonSharp/EvalValues/EvalValueCreator.cs @@ -80,8 +80,7 @@ namespace PorygonSharp.EvalValues private static EvalValue CreateDelegateEvalValue(Delegate del) { - var val = new DelegateEvalValue(del); - return new EvalValue(val.Pointer); + return new DelegateEvalValue(del); } [DllImport("PorygonLang", EntryPoint = "CreateNilEvalValue",CallingConvention = CallingConvention.Cdecl)] diff --git a/PorygonSharp/StaticScope.cs b/PorygonSharp/StaticScope.cs index d7b12d2..5055a1e 100644 --- a/PorygonSharp/StaticScope.cs +++ b/PorygonSharp/StaticScope.cs @@ -10,6 +10,7 @@ namespace PorygonSharp public static class StaticScope { private static List _variables = new List(); + private static List _evalValues = new List(); public static void RegisterStaticVariable(string name, object o) { var type = o.GetType(); @@ -19,6 +20,7 @@ namespace PorygonSharp var hash = name.ScriptHash(); var value = EvalValueCreator.CreateValue(o); _variables.Add(o); + _evalValues.Add(value); RegisterStaticVariable(hash, scriptType.Value, value.GetPointer()); } diff --git a/PorygonSharp/Utilities/Caster.cs b/PorygonSharp/Utilities/Caster.cs index 0cfed82..6901f9b 100644 --- a/PorygonSharp/Utilities/Caster.cs +++ b/PorygonSharp/Utilities/Caster.cs @@ -1,7 +1,6 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Runtime.CompilerServices; using PorygonSharp.EvalValues; namespace PorygonSharp.Utilities