No Description
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 4.1KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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 Dictionary<DelegateKey, Type>();
  17. public static Type NewDelegateType(Type ret, Type[] parameters)
  18. {
  19. var key = new DelegateKey(ret, (Type[])parameters.Clone());
  20. Type delegateType;
  21. if (!DelegateTypes.TryGetValue(key, out delegateType))
  22. {
  23. var assemblyName = Guid.NewGuid().ToString();
  24. var name = new AssemblyName(assemblyName);
  25. var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
  26. var moduleBuilder = assemblyBuilder.DefineDynamicModule(name.Name);
  27. assemblyBuilder.DefineVersionInfoResource();
  28. var typeBuilder = moduleBuilder.DefineType("CustomDelegate", System.Reflection.TypeAttributes.Public | System.Reflection.TypeAttributes.Sealed | System.Reflection.TypeAttributes.AutoClass, typeof(MulticastDelegate));
  29. var constructor = typeof(UnmanagedFunctionPointerAttribute).GetConstructors()[0];
  30. // Make sure that we setup the C calling convention on the unmanaged delegate
  31. var customAttribute = new CustomAttributeBuilder(constructor, new object[] { CallingConvention.Cdecl });
  32. typeBuilder.SetCustomAttribute(customAttribute);
  33. typeBuilder.DefineConstructor(System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.HideBySig | System.Reflection.MethodAttributes.RTSpecialName, CallingConventions.Standard, _DelegateCtorSignature).SetImplementationFlags(System.Reflection.MethodImplAttributes.CodeTypeMask);
  34. 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);
  35. delegateType = typeBuilder.CreateType();
  36. DelegateTypes.Add(key, delegateType);
  37. }
  38. return delegateType;
  39. }
  40. private struct DelegateKey : IEquatable<DelegateKey>
  41. {
  42. public DelegateKey(Type returnType, Type[] arguments)
  43. {
  44. ReturnType = returnType;
  45. Arguments = arguments;
  46. }
  47. public readonly Type ReturnType;
  48. public readonly Type[] Arguments;
  49. public bool Equals(DelegateKey other)
  50. {
  51. if (ReturnType.Equals(other.ReturnType) && Arguments.Length == other.Arguments.Length)
  52. {
  53. for (int i = 0; i < Arguments.Length; i++)
  54. {
  55. if (Arguments[i] != other.Arguments[i])
  56. {
  57. return false;
  58. }
  59. }
  60. return true;
  61. }
  62. return false;
  63. }
  64. public override bool Equals(object obj)
  65. {
  66. if (ReferenceEquals(null, obj)) return false;
  67. return obj is DelegateKey && Equals((DelegateKey) obj);
  68. }
  69. public override int GetHashCode()
  70. {
  71. unchecked
  72. {
  73. int hashcode = (ReturnType.GetHashCode() * 397) ^ Arguments.Length.GetHashCode();
  74. for (int i = 0; i < Arguments.Length; i++)
  75. {
  76. hashcode = (hashcode * 397) ^ Arguments[i].GetHashCode();
  77. }
  78. return hashcode;
  79. }
  80. }
  81. }
  82. }
  83. }
  84. #endif