You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
4.5 KiB
114 lines
4.5 KiB
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; |
|
} |
|
} |