Extensions.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using ILRuntime.Runtime.Stack;
  6. namespace ILRuntime.Runtime
  7. {
  8. public static class Extensions
  9. {
  10. public static bool GetJITFlags(this Mono.Cecil.CustomAttribute attribute, Enviorment.AppDomain appdomain, out int flags)
  11. {
  12. var at = appdomain.GetType(attribute.AttributeType, null, null);
  13. flags = ILRuntimeJITFlags.None;
  14. if (at == appdomain.JITAttributeType)
  15. {
  16. if (attribute.HasConstructorArguments)
  17. {
  18. flags = (int)attribute.ConstructorArguments[0].Value;
  19. }
  20. else
  21. flags = ILRuntimeJITFlags.JITOnDemand;
  22. return true;
  23. }
  24. else
  25. return false;
  26. }
  27. public static void GetClassName(this Type type, out string clsName, out string realClsName, out bool isByRef, bool simpleClassName = false)
  28. {
  29. isByRef = type.IsByRef;
  30. int arrayRank = 1;
  31. if (isByRef)
  32. {
  33. type = type.GetElementType();
  34. }
  35. bool isArray = type.IsArray;
  36. if (isArray)
  37. {
  38. arrayRank = type.GetArrayRank();
  39. type = type.GetElementType();
  40. if (type.IsArray)
  41. {
  42. type.GetClassName(out clsName, out realClsName, out isByRef, simpleClassName);
  43. clsName += "_Array";
  44. if (!simpleClassName)
  45. clsName += "_Binding";
  46. if (arrayRank > 1)
  47. clsName += arrayRank;
  48. if (arrayRank <= 1)
  49. realClsName += "[]";
  50. else
  51. {
  52. StringBuilder sb = new StringBuilder();
  53. sb.Append(realClsName);
  54. sb.Append('[');
  55. for (int i = 0; i < arrayRank - 1; i++)
  56. {
  57. sb.Append(',');
  58. }
  59. sb.Append(']');
  60. realClsName = sb.ToString();
  61. }
  62. return;
  63. }
  64. }
  65. string realNamespace = null;
  66. bool isNestedGeneric = false;
  67. if (type.IsNested)
  68. {
  69. string bClsName, bRealClsName;
  70. bool tmp;
  71. var rt = type.ReflectedType;
  72. if(rt.IsGenericType && rt.IsGenericTypeDefinition)
  73. {
  74. if (type.IsGenericType)
  75. {
  76. rt = rt.MakeGenericType(type.GetGenericArguments());
  77. isNestedGeneric = true;
  78. }
  79. }
  80. GetClassName(rt, out bClsName, out bRealClsName, out tmp);
  81. clsName = bClsName + "_";
  82. realNamespace = bRealClsName + ".";
  83. }
  84. else
  85. {
  86. clsName = simpleClassName ? "" : (!string.IsNullOrEmpty(type.Namespace) ? type.Namespace.Replace(".", "_") + "_" : "");
  87. if (string.IsNullOrEmpty(type.Namespace))
  88. {
  89. if (type.IsArray)
  90. {
  91. var elementType = type.GetElementType();
  92. if (elementType.IsNested && elementType.DeclaringType != null)
  93. {
  94. realNamespace = elementType.Namespace + "." + elementType.DeclaringType.Name + ".";
  95. }
  96. else
  97. {
  98. realNamespace = elementType.Namespace + ".";
  99. }
  100. }
  101. else
  102. {
  103. realNamespace = "global::";
  104. }
  105. }
  106. else
  107. {
  108. realNamespace = type.Namespace + ".";
  109. }
  110. }
  111. clsName = clsName + type.Name.Replace(".", "_").Replace("`", "_").Replace("<", "_").Replace(">", "_");
  112. bool isGeneric = false;
  113. string ga = null;
  114. if (type.IsGenericType && !isNestedGeneric)
  115. {
  116. isGeneric = true;
  117. clsName += "_";
  118. ga = "<";
  119. var args = type.GetGenericArguments();
  120. bool first = true;
  121. foreach (var j in args)
  122. {
  123. if (first)
  124. first = false;
  125. else
  126. {
  127. clsName += "_";
  128. ga += ", ";
  129. }
  130. string a, b;
  131. bool tmp;
  132. GetClassName(j, out a, out b, out tmp, true);
  133. clsName += a;
  134. ga += b;
  135. }
  136. ga += ">";
  137. }
  138. if (isArray)
  139. {
  140. clsName += "_Array";
  141. if (arrayRank > 1)
  142. clsName += arrayRank;
  143. }
  144. if (!simpleClassName)
  145. clsName += "_Binding";
  146. realClsName = realNamespace;
  147. if (isGeneric)
  148. {
  149. int idx = type.Name.IndexOf("`");
  150. if (idx > 0)
  151. {
  152. realClsName += type.Name.Substring(0, idx);
  153. realClsName += ga;
  154. }
  155. else
  156. realClsName += type.Name;
  157. }
  158. else
  159. realClsName += type.Name;
  160. if (isArray)
  161. {
  162. if (arrayRank <= 1)
  163. realClsName += "[]";
  164. else
  165. {
  166. StringBuilder sb = new StringBuilder();
  167. sb.Append(realClsName);
  168. sb.Append('[');
  169. for(int i=0;i<arrayRank - 1; i++)
  170. {
  171. sb.Append(',');
  172. }
  173. sb.Append(']');
  174. realClsName = sb.ToString();
  175. }
  176. }
  177. }
  178. public static int ToInt32(this object obj)
  179. {
  180. if (obj is int)
  181. return (int)obj;
  182. if (obj is float)
  183. return (int)(float)obj;
  184. if (obj is long)
  185. return (int)(long)obj;
  186. if (obj is short)
  187. return (int)(short)obj;
  188. if (obj is double)
  189. return (int)(double)obj;
  190. if (obj is byte)
  191. return (int)(byte)obj;
  192. if (obj is Intepreter.ILEnumTypeInstance)
  193. return (int)((Intepreter.ILEnumTypeInstance)obj)[0];
  194. if (obj is uint)
  195. return (int)(uint)obj;
  196. if (obj is ushort)
  197. return (int)(ushort)obj;
  198. if (obj is sbyte)
  199. return (int)(sbyte)obj;
  200. return Convert.ToInt32(obj);
  201. }
  202. public static long ToInt64(this object obj)
  203. {
  204. if (obj is long)
  205. return (long)obj;
  206. if (obj is int)
  207. return (long)(int)obj;
  208. if (obj is float)
  209. return (long)(float)obj;
  210. if (obj is short)
  211. return (long)(short)obj;
  212. if (obj is double)
  213. return (long)(double)obj;
  214. if (obj is byte)
  215. return (long)(byte)obj;
  216. if (obj is uint)
  217. return (long)(uint)obj;
  218. if (obj is ushort)
  219. return (long)(ushort)obj;
  220. if (obj is sbyte)
  221. return (long)(sbyte)obj;
  222. throw new InvalidCastException();
  223. }
  224. public static short ToInt16(this object obj)
  225. {
  226. if (obj is short)
  227. return (short)obj;
  228. if (obj is long)
  229. return (short)(long)obj;
  230. if (obj is int)
  231. return (short)(int)obj;
  232. if (obj is float)
  233. return (short)(float)obj;
  234. if (obj is double)
  235. return (short)(double)obj;
  236. if (obj is byte)
  237. return (short)(byte)obj;
  238. if (obj is uint)
  239. return (short)(uint)obj;
  240. if (obj is ushort)
  241. return (short)(ushort)obj;
  242. if (obj is sbyte)
  243. return (short)(sbyte)obj;
  244. throw new InvalidCastException();
  245. }
  246. public static float ToFloat(this object obj)
  247. {
  248. if (obj is float)
  249. return (float)obj;
  250. if (obj is int)
  251. return (float)(int)obj;
  252. if (obj is long)
  253. return (float)(long)obj;
  254. if (obj is short)
  255. return (float)(short)obj;
  256. if (obj is double)
  257. return (float)(double)obj;
  258. if (obj is byte)
  259. return (float)(byte)obj;
  260. if (obj is uint)
  261. return (float)(uint)obj;
  262. if (obj is ushort)
  263. return (float)(ushort)obj;
  264. if (obj is sbyte)
  265. return (float)(sbyte)obj;
  266. throw new InvalidCastException();
  267. }
  268. public static double ToDouble(this object obj)
  269. {
  270. if (obj is double)
  271. return (double)obj;
  272. if (obj is float)
  273. return (float)obj;
  274. if (obj is int)
  275. return (double)(int)obj;
  276. if (obj is long)
  277. return (double)(long)obj;
  278. if (obj is short)
  279. return (double)(short)obj;
  280. if (obj is byte)
  281. return (double)(byte)obj;
  282. if (obj is uint)
  283. return (double)(uint)obj;
  284. if (obj is ushort)
  285. return (double)(ushort)obj;
  286. if (obj is sbyte)
  287. return (double)(sbyte)obj;
  288. throw new InvalidCastException();
  289. }
  290. public static Type GetActualType(this object value)
  291. {
  292. if (value is ILRuntime.Runtime.Enviorment.CrossBindingAdaptorType)
  293. return ((ILRuntime.Runtime.Enviorment.CrossBindingAdaptorType)value).ILInstance.Type.ReflectionType;
  294. if (value is ILRuntime.Runtime.Intepreter.ILTypeInstance)
  295. return ((ILRuntime.Runtime.Intepreter.ILTypeInstance)value).Type.ReflectionType;
  296. else
  297. return value.GetType();
  298. }
  299. public static bool MatchGenericParameters(this System.Reflection.MethodInfo m, Type[] genericArguments, Type returnType, params Type[] parameters)
  300. {
  301. var param = m.GetParameters();
  302. if (param.Length == parameters.Length)
  303. {
  304. var args = m.GetGenericArguments();
  305. if (args.Length != genericArguments.Length)
  306. {
  307. return false;
  308. }
  309. if (args.MatchGenericParameters(m.ReturnType, returnType, genericArguments))
  310. {
  311. for (int i = 0; i < param.Length; i++)
  312. {
  313. if (!args.MatchGenericParameters(param[i].ParameterType, parameters[i], genericArguments))
  314. return false;
  315. }
  316. return true;
  317. }
  318. else
  319. return false;
  320. }
  321. else
  322. return false;
  323. }
  324. public static bool MatchGenericParameters(this Type[] args, Type type, Type q, Type[] genericArguments)
  325. {
  326. if (type.IsGenericParameter)
  327. {
  328. for (int i = 0; i < args.Length; i++)
  329. {
  330. if (args[i] == type)
  331. {
  332. return q == genericArguments[i];
  333. }
  334. }
  335. throw new NotSupportedException();
  336. }
  337. else
  338. {
  339. if (type.IsArray)
  340. {
  341. if (q.IsArray)
  342. {
  343. return MatchGenericParameters(args, type.GetElementType(), q.GetElementType(), genericArguments);
  344. }
  345. else
  346. return false;
  347. }
  348. else if (type.IsByRef)
  349. {
  350. if (q.IsByRef)
  351. {
  352. return MatchGenericParameters(args, type.GetElementType(), q.GetElementType(), genericArguments);
  353. }
  354. else
  355. return false;
  356. }
  357. else if (type.IsGenericType)
  358. {
  359. if (q.IsGenericType)
  360. {
  361. var t1 = type.GetGenericTypeDefinition();
  362. var t2 = type.GetGenericTypeDefinition();
  363. if (t1 == t2)
  364. {
  365. var argA = type.GetGenericArguments();
  366. var argB = q.GetGenericArguments();
  367. if (argA.Length == argB.Length)
  368. {
  369. for (int i = 0; i < argA.Length; i++)
  370. {
  371. if (!MatchGenericParameters(args, argA[i], argB[i], genericArguments))
  372. return false;
  373. }
  374. return true;
  375. }
  376. else
  377. return false;
  378. }
  379. else
  380. return false;
  381. }
  382. else
  383. return false;
  384. }
  385. else
  386. return type == q;
  387. }
  388. }
  389. }
  390. }