DelegateManager.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using ILRuntime.CLR.TypeSystem;
  6. using ILRuntime.CLR.Method;
  7. using ILRuntime.Other;
  8. using ILRuntime.Runtime.Intepreter;
  9. namespace ILRuntime.Runtime.Enviorment
  10. {
  11. public class DelegateManager
  12. {
  13. List<DelegateMapNode> methods = new List<DelegateMapNode>();
  14. List<DelegateMapNode> functions = new List<DelegateMapNode>();
  15. IDelegateAdapter zeroParamMethodAdapter = new MethodDelegateAdapter();
  16. IDelegateAdapter dummyAdapter = new DummyDelegateAdapter();
  17. Dictionary<Type, Func<Delegate, Delegate>> clrDelegates = new Dictionary<Type, Func<Delegate, Delegate>>(new ByReferenceKeyComparer<Type>());
  18. Func<Delegate, Delegate> defaultConverter;
  19. Enviorment.AppDomain appdomain;
  20. public DelegateManager(Enviorment.AppDomain appdomain)
  21. {
  22. this.appdomain = appdomain;
  23. defaultConverter = DefaultConverterStub;
  24. }
  25. static Delegate DefaultConverterStub(Delegate dele)
  26. {
  27. return dele;
  28. }
  29. public void RegisterDelegateConvertor<T>(Func<Delegate, Delegate> action)
  30. {
  31. var type = typeof(T);
  32. if (type.IsSubclassOf(typeof(Delegate)))
  33. {
  34. clrDelegates[type] = action;
  35. }
  36. else
  37. throw new NotSupportedException();
  38. }
  39. public void RegisterMethodDelegate<T1>()
  40. {
  41. DelegateMapNode node = new Enviorment.DelegateManager.DelegateMapNode();
  42. node.Adapter = new MethodDelegateAdapter<T1>();
  43. node.ParameterTypes = new Type[] { typeof(T1) };
  44. methods.Add(node);
  45. RegisterDelegateConvertor<Action<T1>>(defaultConverter);
  46. }
  47. public void RegisterMethodDelegate<T1, T2>()
  48. {
  49. DelegateMapNode node = new Enviorment.DelegateManager.DelegateMapNode();
  50. node.Adapter = new MethodDelegateAdapter<T1, T2>();
  51. node.ParameterTypes = new Type[] { typeof(T1), typeof(T2) };
  52. methods.Add(node);
  53. RegisterDelegateConvertor<Action<T1, T2>>(defaultConverter);
  54. }
  55. public void RegisterMethodDelegate<T1, T2, T3>()
  56. {
  57. DelegateMapNode node = new Enviorment.DelegateManager.DelegateMapNode();
  58. node.Adapter = new MethodDelegateAdapter<T1, T2, T3>();
  59. node.ParameterTypes = new Type[] { typeof(T1), typeof(T2), typeof(T3) };
  60. methods.Add(node);
  61. RegisterDelegateConvertor<Action<T1, T2, T3>>(defaultConverter);
  62. }
  63. public void RegisterMethodDelegate<T1, T2, T3, T4>()
  64. {
  65. DelegateMapNode node = new Enviorment.DelegateManager.DelegateMapNode();
  66. node.Adapter = new MethodDelegateAdapter<T1, T2, T3, T4>();
  67. node.ParameterTypes = new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4) };
  68. methods.Add(node);
  69. RegisterDelegateConvertor<Action<T1, T2, T3, T4>>(defaultConverter);
  70. }
  71. #if NET_4_6 || NET_STANDARD_2_0
  72. public void RegisterMethodDelegate<T1, T2, T3, T4, T5>()
  73. {
  74. DelegateMapNode node = new Enviorment.DelegateManager.DelegateMapNode();
  75. node.Adapter = new MethodDelegateAdapter<T1, T2, T3, T4, T5>();
  76. node.ParameterTypes = new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5) };
  77. methods.Add(node);
  78. RegisterDelegateConvertor<Action<T1, T2, T3, T4, T5>>(defaultConverter);
  79. }
  80. #endif
  81. public void RegisterFunctionDelegate<TResult>()
  82. {
  83. DelegateMapNode node = new Enviorment.DelegateManager.DelegateMapNode();
  84. node.Adapter = new FunctionDelegateAdapter<TResult>();
  85. node.ParameterTypes = new Type[] { typeof(TResult) };
  86. functions.Add(node);
  87. RegisterDelegateConvertor<Func<TResult>>(defaultConverter);
  88. }
  89. public void RegisterFunctionDelegate<T1, TResult>()
  90. {
  91. DelegateMapNode node = new Enviorment.DelegateManager.DelegateMapNode();
  92. node.Adapter = new FunctionDelegateAdapter<T1, TResult>();
  93. node.ParameterTypes = new Type[] { typeof(T1), typeof(TResult) };
  94. functions.Add(node);
  95. RegisterDelegateConvertor<Func<T1, TResult>>(defaultConverter);
  96. }
  97. public void RegisterFunctionDelegate<T1, T2, TResult>()
  98. {
  99. DelegateMapNode node = new Enviorment.DelegateManager.DelegateMapNode();
  100. node.Adapter = new FunctionDelegateAdapter<T1, T2, TResult>();
  101. node.ParameterTypes = new Type[] { typeof(T1), typeof(T2), typeof(TResult) };
  102. functions.Add(node);
  103. RegisterDelegateConvertor<Func<T1, T2, TResult>>(defaultConverter);
  104. }
  105. public void RegisterFunctionDelegate<T1, T2, T3, TResult>()
  106. {
  107. DelegateMapNode node = new Enviorment.DelegateManager.DelegateMapNode();
  108. node.Adapter = new FunctionDelegateAdapter<T1, T2, T3, TResult>();
  109. node.ParameterTypes = new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(TResult) };
  110. functions.Add(node);
  111. RegisterDelegateConvertor<Func<T1, T2, T3, TResult>>(defaultConverter);
  112. }
  113. public void RegisterFunctionDelegate<T1, T2, T3, T4, TResult>()
  114. {
  115. DelegateMapNode node = new Enviorment.DelegateManager.DelegateMapNode();
  116. node.Adapter = new FunctionDelegateAdapter<T1, T2, T3, T4, TResult>();
  117. node.ParameterTypes = new Type[] { typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(TResult) };
  118. functions.Add(node);
  119. RegisterDelegateConvertor<Func<T1, T2, T3, T4, TResult>>(defaultConverter);
  120. }
  121. internal Delegate ConvertToDelegate(Type clrDelegateType, IDelegateAdapter adapter)
  122. {
  123. Func<Delegate, Delegate> func;
  124. if(adapter is DummyDelegateAdapter)
  125. {
  126. DelegateAdapter.ThrowAdapterNotFound(adapter.Method);
  127. return null;
  128. }
  129. if (clrDelegates.TryGetValue(clrDelegateType, out func))
  130. {
  131. return func(adapter.Delegate);
  132. }
  133. else
  134. {
  135. StringBuilder sb = new StringBuilder();
  136. string clsName, rName;
  137. bool isByRef;
  138. clrDelegateType.GetClassName(out clsName, out rName, out isByRef);
  139. sb.AppendLine("Cannot find convertor for " + rName);
  140. sb.AppendLine("Please add following code:");
  141. sb.Append("appdomain.DelegateManager.RegisterDelegateConvertor<");
  142. sb.Append(rName);
  143. sb.AppendLine(">((act) =>");
  144. sb.AppendLine("{");
  145. sb.Append(" return new ");
  146. sb.Append(rName);
  147. sb.Append("((");
  148. var mi = clrDelegateType.GetMethod("Invoke");
  149. bool first = true;
  150. foreach(var i in mi.GetParameters())
  151. {
  152. if (first)
  153. {
  154. first = false;
  155. }
  156. else
  157. sb.Append(", ");
  158. sb.Append(i.Name);
  159. }
  160. sb.AppendLine(") =>");
  161. sb.AppendLine(" {");
  162. if(mi.ReturnType != appdomain.VoidType.TypeForCLR)
  163. {
  164. sb.Append(" return ((Func<");
  165. first = true;
  166. foreach (var i in mi.GetParameters())
  167. {
  168. if (first)
  169. {
  170. first = false;
  171. }
  172. else
  173. sb.Append(", ");
  174. i.ParameterType.GetClassName(out clsName, out rName, out isByRef);
  175. sb.Append(rName);
  176. }
  177. if (!first)
  178. sb.Append(", ");
  179. mi.ReturnType.GetClassName(out clsName, out rName, out isByRef);
  180. sb.Append(rName);
  181. }
  182. else
  183. {
  184. sb.Append(" ((Action<");
  185. first = true;
  186. foreach (var i in mi.GetParameters())
  187. {
  188. if (first)
  189. {
  190. first = false;
  191. }
  192. else
  193. sb.Append(", ");
  194. i.ParameterType.GetClassName(out clsName, out rName, out isByRef);
  195. sb.Append(rName);
  196. }
  197. }
  198. sb.Append(">)act)(");
  199. first = true;
  200. foreach (var i in mi.GetParameters())
  201. {
  202. if (first)
  203. {
  204. first = false;
  205. }
  206. else
  207. sb.Append(", ");
  208. sb.Append(i.Name);
  209. }
  210. sb.AppendLine(");");
  211. sb.AppendLine(" });");
  212. sb.AppendLine("});");
  213. throw new KeyNotFoundException(sb.ToString());
  214. }
  215. }
  216. internal IDelegateAdapter FindDelegateAdapter(CLRType type, ILTypeInstance ins, ILMethod ilMethod)
  217. {
  218. IDelegateAdapter dele;
  219. if (ins != null)
  220. {
  221. dele = (ins).GetDelegateAdapter(ilMethod);
  222. if (dele == null)
  223. {
  224. var invokeMethod =
  225. type.GetMethod("Invoke",
  226. ilMethod.ParameterCount);
  227. if (invokeMethod == null && ilMethod.IsExtend)
  228. {
  229. invokeMethod = type.GetMethod("Invoke", ilMethod.ParameterCount - 1);
  230. }
  231. dele = appdomain.DelegateManager.FindDelegateAdapter(
  232. ins, ilMethod, invokeMethod);
  233. }
  234. }
  235. else
  236. {
  237. if (ilMethod.DelegateAdapter == null)
  238. {
  239. var invokeMethod = type.GetMethod("Invoke", ilMethod.ParameterCount);
  240. ilMethod.DelegateAdapter = appdomain.DelegateManager.FindDelegateAdapter(null, ilMethod, invokeMethod);
  241. }
  242. dele = ilMethod.DelegateAdapter;
  243. }
  244. return dele;
  245. }
  246. /// <summary>
  247. /// ilMethod代表的delegate会赋值给method对应的delegate,一般两者参数类型都一致,
  248. /// 但新版本的支持泛型协变之后,有些时候会不一致,所以此处判断是用method判断,而不是用ilMethod判断
  249. /// </summary>
  250. /// <param name="instance"></param>
  251. /// <param name="ilMethod"></param>
  252. /// <param name="method"></param>
  253. /// <returns></returns>
  254. internal IDelegateAdapter FindDelegateAdapter(ILTypeInstance instance, ILMethod ilMethod, IMethod method)
  255. {
  256. IDelegateAdapter res;
  257. var parameterCount = method.ParameterCount;
  258. var returnTypeForCLR = method.ReturnType.TypeForCLR;
  259. if (method.ReturnType == appdomain.VoidType)
  260. {
  261. if (parameterCount == 0)
  262. {
  263. res = zeroParamMethodAdapter.Instantiate(appdomain, instance, ilMethod);
  264. if (instance != null)
  265. instance.SetDelegateAdapter(ilMethod, res);
  266. return res;
  267. }
  268. foreach (var i in methods)
  269. {
  270. var parameterTypes = i.ParameterTypes;
  271. if (parameterTypes.Length == parameterCount)
  272. {
  273. bool match = true;
  274. for (int j = 0; j < parameterCount; j++)
  275. {
  276. if (parameterTypes[j] != method.Parameters[j].TypeForCLR)
  277. {
  278. match = false;
  279. break;
  280. }
  281. }
  282. if (match)
  283. {
  284. res = i.Adapter.Instantiate(appdomain, instance, ilMethod);
  285. if (instance != null)
  286. instance.SetDelegateAdapter(ilMethod, res);
  287. return res;
  288. }
  289. }
  290. }
  291. }
  292. else
  293. {
  294. foreach (var i in functions)
  295. {
  296. var parameterTypes = i.ParameterTypes;
  297. if (parameterTypes.Length == parameterCount + 1)
  298. {
  299. bool match = true;
  300. for (int j = 0; j < parameterCount; j++)
  301. {
  302. if (parameterTypes[j] != method.Parameters[j].TypeForCLR)
  303. {
  304. match = false;
  305. break;
  306. }
  307. }
  308. if (match)
  309. {
  310. if (returnTypeForCLR == parameterTypes[parameterCount])
  311. {
  312. res = i.Adapter.Instantiate(appdomain, instance, ilMethod);
  313. if (instance != null)
  314. instance.SetDelegateAdapter(ilMethod, res);
  315. return res;
  316. }
  317. }
  318. }
  319. }
  320. }
  321. res = dummyAdapter.Instantiate(appdomain, instance, ilMethod);
  322. if (instance != null)
  323. instance.SetDelegateAdapter(ilMethod, res);
  324. return res;
  325. }
  326. class DelegateMapNode
  327. {
  328. public IDelegateAdapter Adapter { get; set; }
  329. public Type[] ParameterTypes { get; set; }
  330. }
  331. }
  332. }