114 lines
4.5 KiB
C#
114 lines
4.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Burst.Compiler.IL.Tests
|
|
{
|
|
/// <summary>
|
|
/// This class provides a delegate for each test methods that should have been pre-generated by <see cref="StaticDelegateGenerator"/>
|
|
/// when running the tests locally.
|
|
///
|
|
/// NOTE: This code is a **SUPER LABORIOUS** workaround a bug in mono 5.11 that is preventing us from dynamically calling a delegate
|
|
/// to native code through Delegate DynamicInvoke.
|
|
///
|
|
/// On .NET Framework and newer version of mono, we would not need this, so we are going to keep this code around until
|
|
/// mono is entirely upgraded in Unity.
|
|
/// </summary>
|
|
internal static partial class StaticDelegateRegistry
|
|
{
|
|
private static readonly Dictionary<SignatureKey, StaticDelegateCallback> RegisteredDelegateTypes = new Dictionary<SignatureKey, StaticDelegateCallback>();
|
|
|
|
private static void Register(Type returnType, Type[] arguments, Type typeDelegate, Func<object, object[], object> caller)
|
|
{
|
|
if (returnType == null) throw new ArgumentNullException(nameof(returnType));
|
|
if (arguments == null) throw new ArgumentNullException(nameof(arguments));
|
|
if (typeDelegate == null) throw new ArgumentNullException(nameof(typeDelegate));
|
|
// don't clone as we have the guarantee that it is generated internally
|
|
RegisteredDelegateTypes.Add(new SignatureKey(returnType, arguments), new StaticDelegateCallback(typeDelegate, caller));
|
|
}
|
|
|
|
public static bool Contains(Type returnType, Type[] arguments)
|
|
{
|
|
if (returnType == null) throw new ArgumentNullException(nameof(returnType));
|
|
if (arguments == null) throw new ArgumentNullException(nameof(arguments));
|
|
return RegisteredDelegateTypes.ContainsKey(new SignatureKey(returnType, arguments));
|
|
}
|
|
|
|
public static bool TryFind(Type returnType, Type[] arguments, out StaticDelegateCallback staticDelegate)
|
|
{
|
|
if (returnType == null) throw new ArgumentNullException(nameof(returnType));
|
|
if (arguments == null) throw new ArgumentNullException(nameof(arguments));
|
|
return RegisteredDelegateTypes.TryGetValue(new SignatureKey(returnType, (Type[])arguments.Clone()), out staticDelegate);
|
|
}
|
|
|
|
internal struct SignatureKey : IEquatable<SignatureKey>
|
|
{
|
|
public SignatureKey(Type returnType, Type[] parameterTypes)
|
|
{
|
|
ReturnType = returnType;
|
|
ParameterTypes = parameterTypes;
|
|
}
|
|
|
|
public readonly Type ReturnType;
|
|
|
|
public readonly Type[] ParameterTypes;
|
|
|
|
public bool Equals(SignatureKey other)
|
|
{
|
|
if (ParameterTypes.Length != other.ParameterTypes.Length) return false;
|
|
if (ReturnType != other.ReturnType) return false;
|
|
|
|
for (int i = 0; i < ParameterTypes.Length; i++)
|
|
{
|
|
var arg = ParameterTypes[i];
|
|
var otherArg = other.ParameterTypes[i];
|
|
if (arg != otherArg) return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public override bool Equals(object obj)
|
|
{
|
|
if (ReferenceEquals(null, obj)) return false;
|
|
return obj is SignatureKey other && Equals(other);
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
unchecked
|
|
{
|
|
var hashcode = ReturnType.GetHashCode();
|
|
for (int i = 0; i < ParameterTypes.Length; i++)
|
|
{
|
|
hashcode = (hashcode * 397) ^ ParameterTypes[i].GetHashCode();
|
|
}
|
|
return hashcode;
|
|
}
|
|
}
|
|
|
|
public static bool operator ==(SignatureKey left, SignatureKey right)
|
|
{
|
|
return left.Equals(right);
|
|
}
|
|
|
|
public static bool operator !=(SignatureKey left, SignatureKey right)
|
|
{
|
|
return !left.Equals(right);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
internal struct StaticDelegateCallback
|
|
{
|
|
public StaticDelegateCallback(Type delegateType, Func<object, object[], object> caller)
|
|
{
|
|
DelegateType = delegateType;
|
|
Caller = caller;
|
|
}
|
|
|
|
public readonly Type DelegateType;
|
|
|
|
public readonly Func<object, object[], object> Caller;
|
|
}
|
|
} |