설명 없음
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.

DelegateHelper.cs 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #if BURST_TESTS_ONLY
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Reflection;
  5. using System.Reflection.Emit;
  6. using System.Runtime.InteropServices;
  7. namespace Burst.Compiler.IL.Tests.Helpers
  8. {
  9. internal static class DelegateHelper
  10. {
  11. private static readonly Type[] _DelegateCtorSignature = new Type[2]
  12. {
  13. typeof(object),
  14. typeof(IntPtr)
  15. };
  16. private static readonly Dictionary<DelegateKey, Type> DelegateTypes = new();
  17. public static Type NewDelegateType(Type ret, Type[] parameters)
  18. {
  19. lock (DelegateTypes)
  20. {
  21. var key = new DelegateKey(ret, (Type[])parameters.Clone());
  22. Type delegateType;
  23. if (!DelegateTypes.TryGetValue(key, out delegateType))
  24. {
  25. var assemblyName = Guid.NewGuid().ToString();
  26. var name = new AssemblyName(assemblyName);
  27. #if NETFRAMEWORK
  28. var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
  29. assemblyBuilder.DefineVersionInfoResource();
  30. #else
  31. var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
  32. #endif
  33. var moduleBuilder = assemblyBuilder.DefineDynamicModule(name.Name);
  34. var typeBuilder = moduleBuilder.DefineType("CustomDelegate", System.Reflection.TypeAttributes.Public | System.Reflection.TypeAttributes.Sealed | System.Reflection.TypeAttributes.AutoClass, typeof(MulticastDelegate));
  35. // For .Net7, there is also an empty default constructor, and we probably can't assume its position, so we scan the possibles, and throw if we can't find a match
  36. ConstructorInfo constructor = default;
  37. foreach (var possibleConstructor in typeof(UnmanagedFunctionPointerAttribute).GetConstructors())
  38. {
  39. if (possibleConstructor.GetParameters().Length==1 && possibleConstructor.GetParameters()[0].ParameterType == typeof(CallingConvention))
  40. {
  41. constructor = possibleConstructor;
  42. break;
  43. }
  44. }
  45. if (constructor == null)
  46. {
  47. throw new InvalidOperationException("We expect to have a constructor for UnmanagedFunctionPointerAttribute that takes a single calling convention argument, but none were found.");
  48. }
  49. // Make sure that we setup the C calling convention on the unmanaged delegate
  50. var customAttribute = new CustomAttributeBuilder(constructor, new object[] { CallingConvention.Cdecl });
  51. typeBuilder.SetCustomAttribute(customAttribute);
  52. typeBuilder.DefineConstructor(System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.HideBySig | System.Reflection.MethodAttributes.RTSpecialName, CallingConventions.Standard, _DelegateCtorSignature).SetImplementationFlags(System.Reflection.MethodImplAttributes.CodeTypeMask);
  53. typeBuilder.DefineMethod("Invoke", System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Virtual | System.Reflection.MethodAttributes.HideBySig | System.Reflection.MethodAttributes.VtableLayoutMask, ret, parameters).SetImplementationFlags(System.Reflection.MethodImplAttributes.CodeTypeMask);
  54. delegateType = typeBuilder.CreateType();
  55. DelegateTypes.Add(key, delegateType);
  56. }
  57. return delegateType;
  58. }
  59. }
  60. private struct DelegateKey : IEquatable<DelegateKey>
  61. {
  62. public DelegateKey(Type returnType, Type[] arguments)
  63. {
  64. ReturnType = returnType;
  65. Arguments = arguments;
  66. }
  67. public readonly Type ReturnType;
  68. public readonly Type[] Arguments;
  69. public bool Equals(DelegateKey other)
  70. {
  71. if (ReturnType.Equals(other.ReturnType) && Arguments.Length == other.Arguments.Length)
  72. {
  73. for (int i = 0; i < Arguments.Length; i++)
  74. {
  75. if (Arguments[i] != other.Arguments[i])
  76. {
  77. return false;
  78. }
  79. }
  80. return true;
  81. }
  82. return false;
  83. }
  84. public override bool Equals(object obj)
  85. {
  86. if (ReferenceEquals(null, obj)) return false;
  87. return obj is DelegateKey && Equals((DelegateKey) obj);
  88. }
  89. public override int GetHashCode()
  90. {
  91. unchecked
  92. {
  93. int hashcode = (ReturnType.GetHashCode() * 397) ^ Arguments.Length.GetHashCode();
  94. for (int i = 0; i < Arguments.Length; i++)
  95. {
  96. hashcode = (hashcode * 397) ^ Arguments[i].GetHashCode();
  97. }
  98. return hashcode;
  99. }
  100. }
  101. }
  102. }
  103. }
  104. #endif