Fix static delegate functions being garbage collected

This commit is contained in:
Deukhoofd 2019-09-22 12:30:08 +02:00
parent b6934d153a
commit 601fec8048
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
5 changed files with 24 additions and 24 deletions

View File

@ -5,21 +5,21 @@ using PorygonSharp.Utilities;
namespace PorygonSharp.EvalValues namespace PorygonSharp.EvalValues
{ {
public class DelegateEvalValue public class DelegateEvalValue : EvalValue
{ {
private delegate IntPtr InvokeDelegate(IntPtr _, IntPtr options, private delegate IntPtr InvokeDelegate(IntPtr _, IntPtr options,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]IntPtr[] parameters, int parameterCount); [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]IntPtr[] parameters, int parameterCount);
private readonly Delegate _delegate; private readonly Delegate _delegate;
private readonly InvokeDelegate _handler; private readonly InvokeDelegate _handler;
public readonly IntPtr Pointer; private readonly IntPtr _funcPtr;
public DelegateEvalValue(Delegate del) public DelegateEvalValue(Delegate del)
{ {
_delegate = del; _delegate = del;
_handler = Invoke; _handler = Invoke;
var funcPtr = Marshal.GetFunctionPointerForDelegate(_handler); _funcPtr = Marshal.GetFunctionPointerForDelegate(_handler);
Pointer = EvalValueCreator.CreateFunctionEvalValue(funcPtr, IntPtr.Zero); Handle = EvalValueCreator.CreateFunctionEvalValue(_funcPtr, IntPtr.Zero);
} }
private IntPtr Invoke(IntPtr _, IntPtr options, IntPtr[] parPtrs, int parameterCount) private IntPtr Invoke(IntPtr _, IntPtr options, IntPtr[] parPtrs, int parameterCount)
@ -35,7 +35,5 @@ namespace PorygonSharp.EvalValues
var result = _delegate.DynamicInvoke(parameters); var result = _delegate.DynamicInvoke(parameters);
return EvalValueCreator.CreateValue(result).GetPointer(); return EvalValueCreator.CreateValue(result).GetPointer();
} }
} }
} }

View File

@ -6,49 +6,51 @@ namespace PorygonSharp.EvalValues
{ {
public class EvalValue : IDisposable public class EvalValue : IDisposable
{ {
private IntPtr _handle; protected IntPtr Handle;
public EvalValue(IntPtr handle) public EvalValue(IntPtr handle)
{ {
_handle = handle; Handle = handle;
} }
protected EvalValue(){}
public void Dispose() public void Dispose()
{ {
if (_handle != IntPtr.Zero) if (Handle != IntPtr.Zero)
{ {
Marshal.FreeHGlobal(_handle); Marshal.FreeHGlobal(Handle);
_handle = IntPtr.Zero; Handle = IntPtr.Zero;
} }
} }
public TypeClass GetTypeClass() public TypeClass GetTypeClass()
{ {
return (TypeClass)GetTypeClass(_handle); return (TypeClass)GetTypeClass(Handle);
} }
public long EvaluateInteger() public long EvaluateInteger()
{ {
return EvaluateInteger(_handle); return EvaluateInteger(Handle);
} }
public double EvaluateFloat() public double EvaluateFloat()
{ {
return EvaluateFloat(_handle); return EvaluateFloat(Handle);
} }
public bool EvaluateBool() public bool EvaluateBool()
{ {
return EvaluateBool(_handle) == 1; return EvaluateBool(Handle) == 1;
} }
public string EvaluateString() 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. // 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 byteArr = new byte[stringLength * 2];
var result = EvaluateString(_handle, byteArr, stringLength); var result = EvaluateString(Handle, byteArr, stringLength);
if (result != 0) if (result != 0)
{ {
throw new Exception("Something went wrong while evaluating a string."); throw new Exception("Something went wrong while evaluating a string.");
@ -59,13 +61,13 @@ namespace PorygonSharp.EvalValues
private object EvaluateGenericObject() private object EvaluateGenericObject()
{ {
var ptr = EvaluateUserDataObj(_handle); var ptr = EvaluateUserDataObj(Handle);
return GCHandle.FromIntPtr(ptr).Target; return GCHandle.FromIntPtr(ptr).Target;
} }
public object GetObjectValue() public object GetObjectValue()
{ {
if (_handle == IntPtr.Zero) if (Handle == IntPtr.Zero)
return null; return null;
switch (GetTypeClass()) switch (GetTypeClass())
{ {
@ -80,7 +82,7 @@ namespace PorygonSharp.EvalValues
case TypeClass.UserData: case TypeClass.UserData:
return EvaluateGenericObject(); return EvaluateGenericObject();
case TypeClass.Table: case TypeClass.Table:
var val = new TableEvalValue(_handle); var val = new TableEvalValue(Handle);
return val.EvaluateNumericalTable(); return val.EvaluateNumericalTable();
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
@ -89,7 +91,7 @@ namespace PorygonSharp.EvalValues
internal IntPtr GetPointer() internal IntPtr GetPointer()
{ {
return _handle; return Handle;
} }
[DllImport("PorygonLang", EntryPoint = "GetEvalValueTypeClass", CallingConvention = CallingConvention.Cdecl)] [DllImport("PorygonLang", EntryPoint = "GetEvalValueTypeClass", CallingConvention = CallingConvention.Cdecl)]

View File

@ -80,8 +80,7 @@ namespace PorygonSharp.EvalValues
private static EvalValue CreateDelegateEvalValue(Delegate del) private static EvalValue CreateDelegateEvalValue(Delegate del)
{ {
var val = new DelegateEvalValue(del); return new DelegateEvalValue(del);
return new EvalValue(val.Pointer);
} }
[DllImport("PorygonLang", EntryPoint = "CreateNilEvalValue",CallingConvention = CallingConvention.Cdecl)] [DllImport("PorygonLang", EntryPoint = "CreateNilEvalValue",CallingConvention = CallingConvention.Cdecl)]

View File

@ -10,6 +10,7 @@ namespace PorygonSharp
public static class StaticScope public static class StaticScope
{ {
private static List<object> _variables = new List<object>(); private static List<object> _variables = new List<object>();
private static List<EvalValue> _evalValues = new List<EvalValue>();
public static void RegisterStaticVariable(string name, object o) public static void RegisterStaticVariable(string name, object o)
{ {
var type = o.GetType(); var type = o.GetType();
@ -19,6 +20,7 @@ namespace PorygonSharp
var hash = name.ScriptHash(); var hash = name.ScriptHash();
var value = EvalValueCreator.CreateValue(o); var value = EvalValueCreator.CreateValue(o);
_variables.Add(o); _variables.Add(o);
_evalValues.Add(value);
RegisterStaticVariable(hash, scriptType.Value, value.GetPointer()); RegisterStaticVariable(hash, scriptType.Value, value.GetPointer());
} }

View File

@ -1,7 +1,6 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices;
using PorygonSharp.EvalValues; using PorygonSharp.EvalValues;
namespace PorygonSharp.Utilities namespace PorygonSharp.Utilities