AppDomain.cs 66 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6. using ILRuntime.Mono.Cecil;
  7. using System.Reflection;
  8. using ILRuntime.Mono.Cecil.Cil;
  9. using ILRuntime.CLR.TypeSystem;
  10. using ILRuntime.CLR.Method;
  11. using ILRuntime.CLR.Utils;
  12. using ILRuntime.Runtime.Intepreter;
  13. using ILRuntime.Runtime.Debugger;
  14. using ILRuntime.Runtime.Stack;
  15. using ILRuntime.Other;
  16. using ILRuntime.Runtime.Intepreter.RegisterVM;
  17. using System.Threading;
  18. namespace ILRuntime.Runtime.Enviorment
  19. {
  20. public unsafe delegate StackObject* CLRRedirectionDelegate(ILIntepreter intp, StackObject* esp, IList<object> mStack, CLRMethod method, bool isNewObj);
  21. public delegate object CLRFieldGetterDelegate(ref object target);
  22. public unsafe delegate StackObject* CLRFieldBindingDelegate(ref object target, ILIntepreter __intp, StackObject* __esp, IList<object> __mStack);
  23. public delegate void CLRFieldSetterDelegate(ref object target, object value);
  24. public delegate object CLRMemberwiseCloneDelegate(ref object target);
  25. public delegate object CLRCreateDefaultInstanceDelegate();
  26. public delegate object CLRCreateArrayInstanceDelegate(int size);
  27. public struct TypeSizeInfo
  28. {
  29. public ILType Type;
  30. public int StaticFieldSize;
  31. public int MethodBodySize;
  32. public int TotalSize;
  33. }
  34. public struct PrewarmInfo
  35. {
  36. public string TypeName;
  37. public string[] MethodNames;
  38. }
  39. public class AppDomain
  40. {
  41. Queue<ILIntepreter> freeIntepreters = new Queue<ILIntepreter>();
  42. Dictionary<int, ILIntepreter> intepreters = new Dictionary<int, ILIntepreter>();
  43. Dictionary<Type, CrossBindingAdaptor> crossAdaptors = new Dictionary<Type, CrossBindingAdaptor>(new ByReferenceKeyComparer<Type>());
  44. Dictionary<Type, ValueTypeBinder> valueTypeBinders = new Dictionary<Type, ValueTypeBinder>();
  45. ThreadSafeDictionary<string, IType> mapType = new ThreadSafeDictionary<string, IType>();
  46. Dictionary<Type, IType> clrTypeMapping = new Dictionary<Type, IType>(new ByReferenceKeyComparer<Type>());
  47. List<IType> typesByIndex = new List<IType>();
  48. ThreadSafeDictionary<int, IType> mapTypeToken = new ThreadSafeDictionary<int, IType>();
  49. ThreadSafeDictionary<int, IMethod> mapMethod = new ThreadSafeDictionary<int, IMethod>();
  50. ThreadSafeDictionary<long, string> mapString = new ThreadSafeDictionary<long, string>();
  51. Dictionary<System.Reflection.MethodBase, CLRRedirectionDelegate> redirectMap = new Dictionary<System.Reflection.MethodBase, CLRRedirectionDelegate>();
  52. Dictionary<System.Reflection.FieldInfo, CLRFieldGetterDelegate> fieldGetterMap = new Dictionary<System.Reflection.FieldInfo, CLRFieldGetterDelegate>();
  53. Dictionary<System.Reflection.FieldInfo, CLRFieldSetterDelegate> fieldSetterMap = new Dictionary<System.Reflection.FieldInfo, CLRFieldSetterDelegate>();
  54. Dictionary<System.Reflection.FieldInfo, KeyValuePair<CLRFieldBindingDelegate, CLRFieldBindingDelegate>> fieldBindingMap = new Dictionary<FieldInfo, KeyValuePair<CLRFieldBindingDelegate, CLRFieldBindingDelegate>>();
  55. Dictionary<Type, CLRMemberwiseCloneDelegate> memberwiseCloneMap = new Dictionary<Type, CLRMemberwiseCloneDelegate>(new ByReferenceKeyComparer<Type>());
  56. Dictionary<Type, CLRCreateDefaultInstanceDelegate> createDefaultInstanceMap = new Dictionary<Type, CLRCreateDefaultInstanceDelegate>(new ByReferenceKeyComparer<Type>());
  57. Dictionary<Type, CLRCreateArrayInstanceDelegate> createArrayInstanceMap = new Dictionary<Type, CLRCreateArrayInstanceDelegate>(new ByReferenceKeyComparer<Type>());
  58. IType voidType, intType, longType, boolType, floatType, doubleType, objectType, jitAttributeType;
  59. DelegateManager dMgr;
  60. Assembly[] loadedAssemblies;
  61. Dictionary<string, byte[]> references = new Dictionary<string, byte[]>();
  62. DebugService debugService;
  63. AsyncJITCompileWorker jitWorker = new AsyncJITCompileWorker();
  64. int defaultJITFlags;
  65. /// <summary>
  66. /// Determine if invoking unbinded CLR method(using reflection) is allowed
  67. /// </summary>
  68. public bool AllowUnboundCLRMethod { get; set; }
  69. #if DEBUG && !NO_PROFILER
  70. public int UnityMainThreadID { get; set; }
  71. public bool IsNotUnityMainThread()
  72. {
  73. return UnityMainThreadID != 0 && (UnityMainThreadID != System.Threading.Thread.CurrentThread.ManagedThreadId);
  74. }
  75. #endif
  76. internal bool SuppressStaticConstructor { get; set; }
  77. public int DefaultJITFlags { get { return defaultJITFlags; } }
  78. public unsafe AppDomain(int defaultJITFlags = ILRuntimeJITFlags.None)
  79. {
  80. AllowUnboundCLRMethod = true;
  81. InvocationContext.InitializeDefaultConverters();
  82. loadedAssemblies = System.AppDomain.CurrentDomain.GetAssemblies();
  83. var mi = typeof(System.Runtime.CompilerServices.RuntimeHelpers).GetMethod("InitializeArray");
  84. RegisterCLRMethodRedirection(mi, CLRRedirections.InitializeArray);
  85. mi = typeof(AppDomain).GetMethod("GetCurrentStackTrace");
  86. RegisterCLRMethodRedirection(mi, CLRRedirections.GetCurrentStackTrace);
  87. foreach (var i in typeof(System.Activator).GetMethods())
  88. {
  89. if (i.Name == "CreateInstance" && i.IsGenericMethodDefinition)
  90. {
  91. RegisterCLRMethodRedirection(i, CLRRedirections.CreateInstance);
  92. }
  93. else if (i.Name == "CreateInstance" && i.GetParameters().Length == 1)
  94. {
  95. RegisterCLRMethodRedirection(i, CLRRedirections.CreateInstance2);
  96. }
  97. else if (i.Name == "CreateInstance" && i.GetParameters().Length == 2)
  98. {
  99. RegisterCLRMethodRedirection(i, CLRRedirections.CreateInstance3);
  100. }
  101. }
  102. foreach (var i in typeof(System.Type).GetMethods())
  103. {
  104. if (i.Name == "GetType" && i.IsStatic)
  105. {
  106. RegisterCLRMethodRedirection(i, CLRRedirections.GetType);
  107. }
  108. if (i.Name == "Equals" && i.GetParameters()[0].ParameterType == typeof(Type))
  109. {
  110. RegisterCLRMethodRedirection(i, CLRRedirections.TypeEquals);
  111. }
  112. if (i.Name == "IsAssignableFrom" && i.GetParameters()[0].ParameterType == typeof(Type))
  113. {
  114. RegisterCLRMethodRedirection(i, CLRRedirections.IsAssignableFrom);
  115. }
  116. }
  117. foreach (var i in typeof(System.Delegate).GetMethods())
  118. {
  119. if (i.Name == "Combine" && i.GetParameters().Length == 2)
  120. {
  121. RegisterCLRMethodRedirection(i, CLRRedirections.DelegateCombine);
  122. }
  123. if (i.Name == "Remove")
  124. {
  125. RegisterCLRMethodRedirection(i, CLRRedirections.DelegateRemove);
  126. }
  127. if (i.Name == "op_Equality")
  128. {
  129. RegisterCLRMethodRedirection(i, CLRRedirections.DelegateEqulity);
  130. }
  131. if (i.Name == "op_Inequality")
  132. {
  133. RegisterCLRMethodRedirection(i, CLRRedirections.DelegateInequlity);
  134. }
  135. }
  136. foreach (var i in typeof(MethodBase).GetMethods())
  137. {
  138. if (i.Name == "Invoke" && i.GetParameters().Length == 2)
  139. {
  140. RegisterCLRMethodRedirection(i, CLRRedirections.MethodInfoInvoke);
  141. }
  142. }
  143. foreach (var i in typeof(Enum).GetMethods())
  144. {
  145. if (i.Name == "Parse" && i.GetParameters().Length == 2)
  146. {
  147. RegisterCLRMethodRedirection(i, CLRRedirections.EnumParse);
  148. }
  149. if (i.Name == "GetValues" && i.GetParameters().Length == 1)
  150. {
  151. RegisterCLRMethodRedirection(i, CLRRedirections.EnumGetValues);
  152. }
  153. if (i.Name == "GetNames" && i.GetParameters().Length == 1)
  154. {
  155. RegisterCLRMethodRedirection(i, CLRRedirections.EnumGetNames);
  156. }
  157. if (i.Name == "GetName")
  158. {
  159. RegisterCLRMethodRedirection(i, CLRRedirections.EnumGetName);
  160. }
  161. #if NET_4_6 || NET_STANDARD_2_0
  162. if (i.Name == "HasFlag")
  163. {
  164. RegisterCLRMethodRedirection(i, CLRRedirections.EnumHasFlag);
  165. }
  166. if (i.Name == "CompareTo")
  167. {
  168. RegisterCLRMethodRedirection(i, CLRRedirections.EnumCompareTo);
  169. }
  170. #endif
  171. if (i.Name == "ToObject" && i.GetParameters()[1].ParameterType == typeof(int))
  172. {
  173. RegisterCLRMethodRedirection(i, CLRRedirections.EnumToObject);
  174. }
  175. }
  176. mi = typeof(System.Type).GetMethod("GetTypeFromHandle");
  177. RegisterCLRMethodRedirection(mi, CLRRedirections.GetTypeFromHandle);
  178. mi = typeof(object).GetMethod("GetType");
  179. RegisterCLRMethodRedirection(mi, CLRRedirections.ObjectGetType);
  180. mi = typeof(Delegate).GetMethod("CreateDelegate", new Type[] { typeof(Type), typeof(MethodInfo) });
  181. RegisterCLRMethodRedirection(mi, CLRRedirections.DelegateCreateDelegate);
  182. mi = typeof(Delegate).GetMethod("CreateDelegate", new Type[] { typeof(Type), typeof(object), typeof(string) });
  183. RegisterCLRMethodRedirection(mi, CLRRedirections.DelegateCreateDelegate2);
  184. mi = typeof(Delegate).GetMethod("CreateDelegate", new Type[] { typeof(Type), typeof(object), typeof(MethodInfo) });
  185. RegisterCLRMethodRedirection(mi, CLRRedirections.DelegateCreateDelegate3);
  186. dMgr = new DelegateManager(this);
  187. dMgr.RegisterDelegateConvertor<Action>((dele) =>
  188. {
  189. return dele;
  190. });
  191. RegisterCrossBindingAdaptor(new Adapters.AttributeAdapter());
  192. debugService = new Debugger.DebugService(this);
  193. this.defaultJITFlags = defaultJITFlags & (ILRuntimeJITFlags.JITImmediately | ILRuntimeJITFlags.JITOnDemand);
  194. }
  195. public void Dispose()
  196. {
  197. debugService.StopDebugService();
  198. jitWorker.Dispose();
  199. }
  200. public IType VoidType { get { return voidType; } }
  201. public IType IntType { get { return intType; } }
  202. public IType LongType { get { return longType; } }
  203. public IType BoolType { get { return boolType; } }
  204. public IType FloatType { get { return floatType; } }
  205. public IType DoubleType { get { return doubleType; } }
  206. public IType ObjectType { get { return objectType; } }
  207. public IType JITAttributeType { get { return jitAttributeType; } }
  208. /// <summary>
  209. /// Attention, this property isn't thread safe
  210. /// </summary>
  211. public Dictionary<string, IType> LoadedTypes { get { return mapType.InnerDictionary; } }
  212. bool IsThreadBinding = false;
  213. bool IsBindingDone = false;
  214. static object bindingLockObject = new object();
  215. internal Dictionary<MethodBase, CLRRedirectionDelegate> RedirectMap
  216. {
  217. get
  218. {
  219. if (!IsThreadBinding && IsBindingDone)
  220. {
  221. return redirectMap;
  222. }
  223. else
  224. {
  225. lock(bindingLockObject)
  226. {
  227. return redirectMap;
  228. }
  229. }
  230. }
  231. }
  232. internal Dictionary<FieldInfo, CLRFieldGetterDelegate> FieldGetterMap
  233. {
  234. get
  235. {
  236. if (!IsThreadBinding && IsBindingDone)
  237. {
  238. return fieldGetterMap;
  239. }
  240. else
  241. {
  242. lock (bindingLockObject)
  243. {
  244. return fieldGetterMap;
  245. }
  246. }
  247. }
  248. }
  249. internal Dictionary<FieldInfo, CLRFieldSetterDelegate> FieldSetterMap
  250. {
  251. get
  252. {
  253. if (!IsThreadBinding && IsBindingDone)
  254. {
  255. return fieldSetterMap;
  256. }
  257. else
  258. {
  259. lock (bindingLockObject)
  260. {
  261. return fieldSetterMap;
  262. }
  263. }
  264. }
  265. }
  266. internal Dictionary<FieldInfo, KeyValuePair<CLRFieldBindingDelegate, CLRFieldBindingDelegate>> FieldBindingMap
  267. {
  268. get
  269. {
  270. if (!IsThreadBinding && IsBindingDone)
  271. {
  272. return fieldBindingMap;
  273. }
  274. else
  275. {
  276. lock (bindingLockObject)
  277. {
  278. return fieldBindingMap;
  279. }
  280. }
  281. }
  282. }
  283. internal Dictionary<Type, CLRMemberwiseCloneDelegate> MemberwiseCloneMap
  284. {
  285. get
  286. {
  287. if (!IsThreadBinding && IsBindingDone)
  288. {
  289. return memberwiseCloneMap;
  290. }
  291. else
  292. {
  293. lock (bindingLockObject)
  294. {
  295. return memberwiseCloneMap;
  296. }
  297. }
  298. }
  299. }
  300. internal Dictionary<Type, CLRCreateDefaultInstanceDelegate> CreateDefaultInstanceMap
  301. {
  302. get
  303. {
  304. if (!IsThreadBinding && IsBindingDone)
  305. {
  306. return createDefaultInstanceMap;
  307. }
  308. else
  309. {
  310. lock (bindingLockObject)
  311. {
  312. return createDefaultInstanceMap;
  313. }
  314. }
  315. }
  316. }
  317. internal Dictionary<Type, CLRCreateArrayInstanceDelegate> CreateArrayInstanceMap
  318. {
  319. get
  320. {
  321. if (!IsThreadBinding && IsBindingDone)
  322. {
  323. return createArrayInstanceMap;
  324. }
  325. else
  326. {
  327. lock (bindingLockObject)
  328. {
  329. return createArrayInstanceMap;
  330. }
  331. }
  332. }
  333. }
  334. internal Dictionary<Type, CrossBindingAdaptor> CrossBindingAdaptors { get { return crossAdaptors; } }
  335. internal Dictionary<Type, ValueTypeBinder> ValueTypeBinders
  336. {
  337. get
  338. {
  339. if (!IsThreadBinding && IsBindingDone)
  340. {
  341. return valueTypeBinders;
  342. }
  343. else
  344. {
  345. lock (bindingLockObject)
  346. {
  347. return valueTypeBinders;
  348. }
  349. }
  350. }
  351. }
  352. public DebugService DebugService { get { return debugService; } }
  353. internal Dictionary<int, ILIntepreter> Intepreters { get { return intepreters; } }
  354. internal Queue<ILIntepreter> FreeIntepreters { get { return freeIntepreters; } }
  355. public DelegateManager DelegateManager { get { return dMgr; } }
  356. internal void EnqueueJITCompileJob(ILMethod method)
  357. {
  358. jitWorker.QueueCompileJob(method);
  359. }
  360. /// <summary>
  361. /// 加载Assembly 文件,从指定的路径
  362. /// </summary>
  363. /// <param name="path">路径</param>
  364. public void LoadAssemblyFile(string path)
  365. {
  366. FileInfo file = new FileInfo(path);
  367. if (!file.Exists)
  368. {
  369. throw new FileNotFoundException(string.Format("Assembly File not find!:\r\n{0}", path));
  370. }
  371. else
  372. {
  373. using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
  374. {
  375. LoadAssembly(fs);
  376. fs.Dispose();
  377. }
  378. }
  379. }
  380. public string GetCurrentStackTrace()
  381. {
  382. throw new NotSupportedException("Cannot call this method from CLR side");
  383. }
  384. #if USE_MDB || USE_PDB
  385. /// <summary>
  386. /// 加载Assembly 文件和PDB文件或MDB文件,从指定的路径(PDB和MDB文件按默认命名方式,并且和Assembly文件处于同一目录中
  387. /// </summary>
  388. /// <param name="path">路径</param>
  389. public void LoadAssemblyFileAndSymbol(string path)
  390. {
  391. FileInfo file = new FileInfo(path);
  392. if (!file.Exists)
  393. {
  394. throw new FileNotFoundException(string.Format("Assembly File not find!:\r\n{0}", path));
  395. }
  396. else
  397. {
  398. var dlldir = file.DirectoryName;
  399. var assname = Path.GetFileNameWithoutExtension(file.Name);
  400. var pdbpath = string.Format("{0}/{1}.pdb",dlldir,assname);
  401. var mdbpath = string.Format("{0}/{1}.mdb", dlldir, assname);
  402. string symbolPath = "";
  403. bool isPDB = true;
  404. if (File.Exists(pdbpath))
  405. {
  406. symbolPath = pdbpath;
  407. }
  408. else if (File.Exists(mdbpath))
  409. {
  410. symbolPath = mdbpath;
  411. isPDB = false;
  412. }
  413. if (string.IsNullOrEmpty(symbolPath))
  414. {
  415. throw new FileNotFoundException(string.Format("symbol file not find!:\r\ncheck:\r\n{0}\r\n{1}\r\n", pdbpath,mdbpath));
  416. }
  417. using (FileStream fs = new FileStream(file.FullName, FileMode.Open, FileAccess.Read))
  418. {
  419. using (var pdbfs = new System.IO.FileStream(symbolPath, FileMode.Open))
  420. {
  421. if (isPDB)
  422. {
  423. LoadAssemblyPDB(fs, pdbfs);
  424. }
  425. else
  426. {
  427. LoadAssemblyMDB(fs, pdbfs);
  428. }
  429. }
  430. }
  431. }
  432. }
  433. #endif
  434. #if USE_PDB
  435. /// <summary>
  436. /// 加载Assembly 文件和PDB文件,两者都从指定的路径
  437. /// </summary>
  438. /// <param name="assemblyFilePath">Assembly 文件路径</param>
  439. /// <param name="symbolFilePath">symbol文件路径</param>
  440. public void LoadAssemblyFileAndPDB(string assemblyFilePath,string symbolFilePath)
  441. {
  442. FileInfo assfile = new FileInfo(assemblyFilePath);
  443. FileInfo pdbfile = new FileInfo(symbolFilePath);
  444. if (!assfile.Exists)
  445. {
  446. throw new FileNotFoundException(string.Format("Assembly File not find!:\r\n{0}", assemblyFilePath));
  447. }
  448. if (!pdbfile.Exists)
  449. {
  450. throw new FileNotFoundException(string.Format("symbol file not find!:\r\n{0}", symbolFilePath));
  451. }
  452. using (FileStream fs = new FileStream(assfile.FullName, FileMode.Open, FileAccess.Read))
  453. {
  454. using (var pdbfs = new System.IO.FileStream(pdbfile.FullName, FileMode.Open))
  455. {
  456. LoadAssemblyPDB(fs, pdbfs);
  457. }
  458. }
  459. }
  460. /// <summary>
  461. /// 从流加载Assembly,以及symbol符号文件(pdb)
  462. /// </summary>
  463. /// <param name="stream">Assembly Stream</param>
  464. /// <param name="symbol">PDB Stream</param>
  465. public void LoadAssemblyPDB(System.IO.Stream stream, System.IO.Stream symbol)
  466. {
  467. LoadAssembly(stream, symbol, new Mono.Cecil.Pdb.PdbReaderProvider());
  468. }
  469. #endif
  470. #if USE_MDB
  471. /// <summary>
  472. /// 加载Assembly 文件和MDB文件,两者都从指定的路径
  473. /// </summary>
  474. /// <param name="assemblyFilePath">Assembly 文件路径</param>
  475. /// <param name="symbolFilePath">symbol文件路径</param>
  476. public void LoadAssemblyFileAndMDB(string assemblyFilePath, string symbolFilePath)
  477. {
  478. FileInfo assfile = new FileInfo(assemblyFilePath);
  479. FileInfo pdbfile = new FileInfo(symbolFilePath);
  480. if (!assfile.Exists)
  481. {
  482. throw new FileNotFoundException(string.Format("Assembly File not find!:\r\n{0}", assemblyFilePath));
  483. }
  484. if (!pdbfile.Exists)
  485. {
  486. throw new FileNotFoundException(string.Format("symbol file not find!:\r\n{0}", symbolFilePath));
  487. }
  488. using (FileStream fs = new FileStream(assfile.FullName, FileMode.Open, FileAccess.Read))
  489. {
  490. using (var pdbfs = new System.IO.FileStream(pdbfile.FullName, FileMode.Open))
  491. {
  492. LoadAssemblyMDB(fs, pdbfs);
  493. }
  494. }
  495. }
  496. /// <summary>
  497. /// 从流加载Assembly,以及symbol符号文件(Mdb)
  498. /// </summary>
  499. /// <param name="stream">Assembly Stream</param>
  500. /// <param name="symbol">PDB Stream</param>
  501. public void LoadAssemblyMDB(System.IO.Stream stream, System.IO.Stream symbol)
  502. {
  503. LoadAssembly(stream, symbol, new Mono.Cecil.Mdb.MdbReaderProvider());
  504. }
  505. #endif
  506. /// <summary>
  507. /// 从流加载Assembly 不加载symbol符号文件
  508. /// </summary>
  509. /// <param name="stream">Dll数据流</param>
  510. public void LoadAssembly(System.IO.Stream stream)
  511. {
  512. LoadAssembly(stream, null, null);
  513. }
  514. /// <summary>
  515. /// 从流加载Assembly,以及symbol符号文件(pdb)
  516. /// </summary>
  517. /// <param name="stream">Assembly Stream</param>
  518. /// <param name="symbol">symbol Stream</param>
  519. /// <param name="symbolReader">symbol 读取器</param>
  520. /// <param name="inMemory">是否完整读入内存</param>
  521. public void LoadAssembly(System.IO.Stream stream, System.IO.Stream symbol, ISymbolReaderProvider symbolReader)
  522. {
  523. var module = ModuleDefinition.ReadModule(stream); //从MONO中加载模块
  524. if (symbolReader != null && symbol != null)
  525. {
  526. module.ReadSymbols(symbolReader.GetSymbolReader(module, symbol)); //加载符号表
  527. }
  528. if (module.HasAssemblyReferences) //如果此模块引用了其他模块
  529. {
  530. /*foreach (var ar in module.AssemblyReferences)
  531. {
  532. if (moduleref.Contains(ar.Name) == false)
  533. moduleref.Add(ar.Name);
  534. if (moduleref.Contains(ar.FullName) == false)
  535. moduleref.Add(ar.FullName);
  536. }
  537. */
  538. }
  539. if (module.HasTypes)
  540. {
  541. List<ILType> types = new List<ILType>();
  542. foreach (var t in module.GetTypes()) //获取所有此模块定义的类型
  543. {
  544. ILType type = new ILType(t, this);
  545. mapType[t.FullName] = type;
  546. mapTypeToken[type.GetHashCode()] = type;
  547. types.Add(type);
  548. }
  549. }
  550. if (voidType == null)
  551. {
  552. voidType = GetType("System.Void");
  553. intType = GetType("System.Int32");
  554. longType = GetType("System.Int64");
  555. boolType = GetType("System.Boolean");
  556. floatType = GetType("System.Single");
  557. doubleType = GetType("System.Double");
  558. objectType = GetType("System.Object");
  559. jitAttributeType = GetType("ILRuntime.Runtime.ILRuntimeJITAttribute");
  560. }
  561. #if DEBUG && !DISABLE_ILRUNTIME_DEBUG
  562. debugService.NotifyModuleLoaded(module.Name);
  563. #endif
  564. }
  565. /// <summary>
  566. /// External reference should be added to the AppDomain by the method
  567. /// </summary>
  568. /// <param name="name">Assembly name, without .dll</param>
  569. /// <param name="content">file content</param>
  570. public void AddReferenceBytes(string name, byte[] content)
  571. {
  572. references[name] = content;
  573. }
  574. public void RegisterCLRMethodRedirection(MethodBase mi, CLRRedirectionDelegate func)
  575. {
  576. if (mi == null)
  577. return;
  578. if (!IsThreadBinding)
  579. {
  580. if (!redirectMap.ContainsKey(mi))
  581. redirectMap[mi] = func;
  582. }
  583. else
  584. {
  585. lock (bindingLockObject)
  586. {
  587. if (!redirectMap.ContainsKey(mi))
  588. redirectMap[mi] = func;
  589. }
  590. }
  591. }
  592. public void RegisterCLRFieldGetter(FieldInfo f, CLRFieldGetterDelegate getter)
  593. {
  594. if (!IsThreadBinding)
  595. {
  596. if (!fieldGetterMap.ContainsKey(f))
  597. fieldGetterMap[f] = getter;
  598. }
  599. else
  600. {
  601. lock (bindingLockObject)
  602. {
  603. if (!fieldGetterMap.ContainsKey(f))
  604. fieldGetterMap[f] = getter;
  605. }
  606. }
  607. }
  608. public void RegisterCLRFieldSetter(FieldInfo f, CLRFieldSetterDelegate setter)
  609. {
  610. if (!IsThreadBinding)
  611. {
  612. if (!fieldSetterMap.ContainsKey(f))
  613. fieldSetterMap[f] = setter;
  614. }
  615. else
  616. {
  617. lock (bindingLockObject)
  618. {
  619. if (!fieldSetterMap.ContainsKey(f))
  620. fieldSetterMap[f] = setter;
  621. }
  622. }
  623. }
  624. public void RegisterCLRFieldBinding(FieldInfo f, CLRFieldBindingDelegate copyToStack, CLRFieldBindingDelegate assignFromStack)
  625. {
  626. if (!IsThreadBinding)
  627. {
  628. if (!fieldBindingMap.ContainsKey(f))
  629. fieldBindingMap[f] = new KeyValuePair<CLRFieldBindingDelegate, CLRFieldBindingDelegate>(copyToStack, assignFromStack);
  630. }
  631. else
  632. {
  633. lock (bindingLockObject)
  634. {
  635. if (!fieldBindingMap.ContainsKey(f))
  636. fieldBindingMap[f] = new KeyValuePair<CLRFieldBindingDelegate, CLRFieldBindingDelegate>(copyToStack, assignFromStack);
  637. }
  638. }
  639. }
  640. public void RegisterCLRMemberwiseClone(Type t, CLRMemberwiseCloneDelegate memberwiseClone)
  641. {
  642. if (!IsThreadBinding)
  643. {
  644. if (!memberwiseCloneMap.ContainsKey(t))
  645. memberwiseCloneMap[t] = memberwiseClone;
  646. }
  647. else
  648. {
  649. lock (bindingLockObject)
  650. {
  651. if (!memberwiseCloneMap.ContainsKey(t))
  652. memberwiseCloneMap[t] = memberwiseClone;
  653. }
  654. }
  655. }
  656. public void RegisterCLRCreateDefaultInstance(Type t, CLRCreateDefaultInstanceDelegate createDefaultInstance)
  657. {
  658. if (!IsThreadBinding)
  659. {
  660. if (!createDefaultInstanceMap.ContainsKey(t))
  661. createDefaultInstanceMap[t] = createDefaultInstance;
  662. }
  663. else
  664. {
  665. lock (bindingLockObject)
  666. {
  667. if (!createDefaultInstanceMap.ContainsKey(t))
  668. createDefaultInstanceMap[t] = createDefaultInstance;
  669. }
  670. }
  671. }
  672. public void RegisterCLRCreateArrayInstance(Type t, CLRCreateArrayInstanceDelegate createArray)
  673. {
  674. if (!IsThreadBinding)
  675. {
  676. if (!createArrayInstanceMap.ContainsKey(t))
  677. createArrayInstanceMap[t] = createArray;
  678. }
  679. else
  680. {
  681. lock (bindingLockObject)
  682. {
  683. if (!createArrayInstanceMap.ContainsKey(t))
  684. createArrayInstanceMap[t] = createArray;
  685. }
  686. }
  687. }
  688. public void RegisterValueTypeBinder(Type t, ValueTypeBinder binder)
  689. {
  690. if (!IsThreadBinding)
  691. {
  692. if (!valueTypeBinders.ContainsKey(t))
  693. {
  694. valueTypeBinders[t] = binder;
  695. binder.RegisterCLRRedirection(this);
  696. var ct = GetType(t) as CLRType;
  697. binder.CLRType = ct;
  698. }
  699. }
  700. else
  701. {
  702. lock (bindingLockObject)
  703. {
  704. if (!valueTypeBinders.ContainsKey(t))
  705. {
  706. valueTypeBinders[t] = binder;
  707. binder.RegisterCLRRedirection(this);
  708. var ct = GetType(t) as CLRType;
  709. binder.CLRType = ct;
  710. }
  711. }
  712. }
  713. }
  714. /// <summary>
  715. /// 初始化注册Bindings(开启线程做binding没完成时,获取CLR重定向方法会有些消耗)
  716. /// </summary>
  717. /// <param name="isThread"></param>
  718. public void InitializeBindings(bool isThread = false)
  719. {
  720. if (IsBindingDone)
  721. return;
  722. IsThreadBinding = isThread;
  723. if (isThread)
  724. {
  725. Thread thread = new Thread(() =>
  726. {
  727. CLRBinding.CLRBindingUtils.Initialize(this);
  728. IsBindingDone = true; //这里线程没有竞争写
  729. #if DEBUG && !NO_PROFILER
  730. UnityEngine.Debug.Log("CLRBindingUtils.Initialize Done in thread..");
  731. #endif
  732. });
  733. thread.Name = string.Format("CLRBindings-Thread #{0}",thread.ManagedThreadId);
  734. thread.Start();
  735. }
  736. else
  737. {
  738. CLRBinding.CLRBindingUtils.Initialize(this);
  739. IsBindingDone = true;
  740. }
  741. }
  742. /// <summary>
  743. /// 更近类型名称返回类型
  744. /// </summary>
  745. /// <param name="fullname">类型全名 命名空间.类型名</param>
  746. /// <returns></returns>
  747. public IType GetType(string fullname)
  748. {
  749. IType res;
  750. if (fullname == null)
  751. {
  752. return null;
  753. }
  754. if (mapType.TryGetValue(fullname, out res))
  755. return res;
  756. string baseType;
  757. List<string> genericParams;
  758. bool isArray;
  759. byte rank;
  760. ParseGenericType(fullname, out baseType, out genericParams, out isArray, out rank);
  761. bool isByRef = !string.IsNullOrEmpty(baseType) && baseType[baseType.Length - 1] == '&';
  762. if (isByRef)
  763. baseType = baseType.Substring(0, baseType.Length - 1);
  764. if (genericParams != null || isArray || isByRef)
  765. {
  766. IType bt = GetType(baseType);
  767. if (bt == null)
  768. {
  769. bt = GetType(baseType.Replace("/", "+"));
  770. }
  771. if (bt == null)
  772. return null;
  773. if (genericParams != null)
  774. {
  775. KeyValuePair<string, IType>[] genericArguments = new KeyValuePair<string, IType>[genericParams.Count];
  776. for (int i = 0; i < genericArguments.Length; i++)
  777. {
  778. string key = null;
  779. if (bt is ILType)
  780. {
  781. ILType ilt = (ILType)bt;
  782. key = ilt.TypeDefinition.GenericParameters[i].FullName;
  783. }
  784. else
  785. key = "!" + i;
  786. IType val = GetType(genericParams[i]);
  787. if (val == null)
  788. return null;
  789. genericArguments[i] = new KeyValuePair<string, IType>(key, val);
  790. }
  791. bt = bt.MakeGenericInstance(genericArguments);
  792. mapType[bt.FullName] = bt;
  793. mapTypeToken[bt.GetHashCode()] = bt;
  794. if (bt is CLRType)
  795. {
  796. clrTypeMapping[bt.TypeForCLR] = bt;
  797. //It still make sense for CLRType, since CLR uses [T] for generics instead of <T>
  798. StringBuilder sb = new StringBuilder();
  799. sb.Append(baseType);
  800. sb.Append('<');
  801. for (int i = 0; i < genericParams.Count; i++)
  802. {
  803. if (i > 0)
  804. sb.Append(",");
  805. /*if (genericParams[i].Contains(","))
  806. sb.Append(genericParams[i].Substring(0, genericParams[i].IndexOf(',')));
  807. else*/
  808. sb.Append(genericParams[i]);
  809. }
  810. sb.Append('>');
  811. var asmName = sb.ToString();
  812. if (bt.FullName != asmName)
  813. mapType[asmName] = bt;
  814. }
  815. }
  816. if (isArray)
  817. {
  818. bt = bt.MakeArrayType(rank);
  819. if (bt is CLRType)
  820. clrTypeMapping[bt.TypeForCLR] = bt;
  821. mapType[bt.FullName] = bt;
  822. mapTypeToken[bt.GetHashCode()] = bt;
  823. if (!isByRef)
  824. {
  825. mapType[fullname] = bt;
  826. return bt;
  827. }
  828. }
  829. if (isByRef)
  830. {
  831. res = bt.MakeByRefType();
  832. if (bt is CLRType)
  833. clrTypeMapping[bt.TypeForCLR] = bt;
  834. mapType[fullname] = res;
  835. mapType[res.FullName] = res;
  836. mapTypeToken[res.GetHashCode()] = res;
  837. return res;
  838. }
  839. else
  840. {
  841. mapType[fullname] = bt;
  842. return bt;
  843. }
  844. }
  845. else
  846. {
  847. Type t = Type.GetType(fullname);
  848. if (t != null)
  849. {
  850. if (!clrTypeMapping.TryGetValue(t, out res))
  851. {
  852. res = new CLRType(t, this);
  853. clrTypeMapping[t] = res;
  854. }
  855. mapType[fullname] = res;
  856. mapType[res.FullName] = res;
  857. mapType[t.AssemblyQualifiedName] = res;
  858. mapTypeToken[res.GetHashCode()] = res;
  859. return res;
  860. }
  861. }
  862. return null;
  863. }
  864. internal static void ParseGenericType(string fullname, out string baseType, out List<string> genericParams, out bool isArray, out byte rank)
  865. {
  866. StringBuilder sb = new StringBuilder();
  867. int depth = 0;
  868. rank = 0;
  869. baseType = "";
  870. genericParams = null;
  871. if (fullname.Length > 2 && fullname[fullname.Length - 2] == '[' && fullname[fullname.Length - 1] == ']')
  872. {
  873. fullname = fullname.Substring(0, fullname.Length - 2);
  874. rank = 1;
  875. isArray = true;
  876. }
  877. else
  878. isArray = false;
  879. if (fullname.Length > 2 && fullname[fullname.Length - 2] == '[' && fullname[fullname.Length - 1] == ']')
  880. {
  881. baseType = fullname;
  882. return;
  883. }
  884. bool isGenericType = false;
  885. foreach (var i in fullname)
  886. {
  887. if (i == '<' || i == '[')
  888. {
  889. isGenericType = true;
  890. break;
  891. }
  892. }
  893. if (isGenericType)
  894. {
  895. foreach (var i in fullname)
  896. {
  897. if (i == '<' || i == '[')
  898. {
  899. depth++;
  900. if (depth == 1)
  901. {
  902. if (isArray && sb.Length == 0)
  903. {
  904. continue;
  905. }
  906. else
  907. {
  908. baseType = sb.ToString();
  909. sb.Length = 0;
  910. genericParams = new List<string>();
  911. continue;
  912. }
  913. }
  914. }
  915. if (i == ',' && depth == 1)
  916. {
  917. string name = sb.ToString();
  918. if (name.StartsWith("["))
  919. name = name.Substring(1, name.Length - 2);
  920. if (!string.IsNullOrEmpty(name))
  921. genericParams.Add(name);
  922. else
  923. ++rank;
  924. sb.Length = 0;
  925. continue;
  926. }
  927. if (i == '>' || i == ']')
  928. {
  929. depth--;
  930. if (depth == 0)
  931. {
  932. string name = sb.ToString();
  933. if (name.StartsWith("["))
  934. name = name.Substring(1, name.Length - 2);
  935. if (!string.IsNullOrEmpty(name))
  936. genericParams.Add(name);
  937. else if (!string.IsNullOrEmpty(baseType))
  938. {
  939. if (!isArray)
  940. {
  941. isArray = true;
  942. ++rank;
  943. }
  944. else
  945. {
  946. baseType += "[]";
  947. }
  948. }
  949. else
  950. {
  951. sb.Append("<>");
  952. continue;
  953. }
  954. sb.Length = 0;
  955. continue;
  956. }
  957. }
  958. sb.Append(i);
  959. }
  960. if (sb.Length > 0)
  961. {
  962. baseType += sb.ToString();
  963. }
  964. if (genericParams != null && genericParams.Count == 0)
  965. genericParams = null;
  966. }
  967. else
  968. baseType = fullname;
  969. }
  970. string GetAssemblyName(IMetadataScope scope)
  971. {
  972. return scope is AssemblyNameReference ? ((AssemblyNameReference)scope).FullName : null;
  973. }
  974. internal int AllocTypeIndex(IType type)
  975. {
  976. lock (typesByIndex)
  977. {
  978. int index = typesByIndex.Count;
  979. typesByIndex.Add(type);
  980. return index;
  981. }
  982. }
  983. internal IType GetTypeByIndex(int index)
  984. {
  985. return typesByIndex[index];
  986. }
  987. internal IType GetType(object token, IType contextType, IMethod contextMethod)
  988. {
  989. int hash = token.GetHashCode();
  990. IType res;
  991. if (mapTypeToken.TryGetValue(hash, out res))
  992. return res;
  993. Mono.Cecil.ModuleDefinition module = null;
  994. KeyValuePair<string, IType>[] genericArguments = null;
  995. string typename = null;
  996. string scope = null;
  997. bool dummyGenericInstance = false;
  998. if (token is Mono.Cecil.TypeDefinition)
  999. {
  1000. Mono.Cecil.TypeDefinition _def = (token as Mono.Cecil.TypeDefinition);
  1001. module = _def.Module;
  1002. typename = _def.FullName;
  1003. scope = GetAssemblyName(_def.Scope);
  1004. }
  1005. else if (token is Mono.Cecil.TypeReference)
  1006. {
  1007. Mono.Cecil.TypeReference _ref = (token as Mono.Cecil.TypeReference);
  1008. if (_ref.IsGenericParameter)
  1009. {
  1010. IType t = null;
  1011. if (contextType != null)
  1012. {
  1013. t = contextType.FindGenericArgument(_ref.Name);
  1014. }
  1015. if (t == null && contextMethod != null && contextMethod is ILMethod)
  1016. {
  1017. t = ((ILMethod)contextMethod).FindGenericArgument(_ref.Name);
  1018. }
  1019. if (t != null)
  1020. {
  1021. mapTypeToken[t.GetHashCode()] = t;
  1022. mapType[t.FullName] = t;
  1023. }
  1024. return t;
  1025. }
  1026. if (_ref.IsByReference)
  1027. {
  1028. var et = ((ByReferenceType)_ref).ElementType;
  1029. bool valid = !et.ContainsGenericParameter;
  1030. var t = GetType(et, contextType, contextMethod);
  1031. if (t != null)
  1032. {
  1033. res = t.MakeByRefType();
  1034. if (res is ILType && valid)
  1035. {
  1036. ///Unify the TypeReference
  1037. ((ILType)res).TypeReference = _ref;
  1038. }
  1039. if (valid)
  1040. {
  1041. mapTypeToken[hash] = res;
  1042. mapTypeToken[res.GetHashCode()] = res;
  1043. if (!string.IsNullOrEmpty(res.FullName))
  1044. mapType[res.FullName] = res;
  1045. }
  1046. return res;
  1047. }
  1048. return null;
  1049. }
  1050. if (_ref.IsArray)
  1051. {
  1052. ArrayType at = (ArrayType)_ref;
  1053. var t = GetType(at.ElementType, contextType, contextMethod);
  1054. if (t != null)
  1055. {
  1056. res = t.MakeArrayType(at.Rank);
  1057. if (!_ref.ContainsGenericParameter)
  1058. {
  1059. if (res is ILType)
  1060. {
  1061. ///Unify the TypeReference
  1062. ((ILType)res).TypeReference = _ref;
  1063. }
  1064. mapTypeToken[hash] = res;
  1065. }
  1066. mapTypeToken[res.GetHashCode()] = res;
  1067. if (!string.IsNullOrEmpty(res.FullName))
  1068. mapType[res.FullName] = res;
  1069. return res;
  1070. }
  1071. return t;
  1072. }
  1073. module = _ref.Module;
  1074. if (_ref.IsGenericInstance)
  1075. {
  1076. GenericInstanceType gType = (GenericInstanceType)_ref;
  1077. typename = gType.ElementType.FullName;
  1078. scope = GetAssemblyName(gType.ElementType.Scope);
  1079. TypeReference tr = gType.ElementType;
  1080. genericArguments = new KeyValuePair<string, IType>[gType.GenericArguments.Count];
  1081. for (int i = 0; i < genericArguments.Length; i++)
  1082. {
  1083. string key = tr.GenericParameters[i].Name;
  1084. IType val;
  1085. if (gType.GenericArguments[i].IsGenericParameter)
  1086. {
  1087. val = contextType.FindGenericArgument(gType.GenericArguments[i].Name);
  1088. dummyGenericInstance = true;
  1089. if (val == null)
  1090. {
  1091. if (contextMethod != null && contextMethod is ILMethod)
  1092. {
  1093. val = ((ILMethod)contextMethod).FindGenericArgument(gType.GenericArguments[i].Name);
  1094. }
  1095. else
  1096. return null;
  1097. }
  1098. }
  1099. else
  1100. val = GetType(gType.GenericArguments[i], contextType, contextMethod);
  1101. if (gType.GenericArguments[i].ContainsGenericParameter)
  1102. dummyGenericInstance = true;
  1103. if (val != null)
  1104. genericArguments[i] = new KeyValuePair<string, IType>(key, val);
  1105. else
  1106. {
  1107. if (!dummyGenericInstance)
  1108. return null;
  1109. genericArguments = null;
  1110. break;
  1111. }
  1112. }
  1113. }
  1114. else
  1115. {
  1116. typename = _ref.FullName;
  1117. scope = GetAssemblyName(_ref.Scope);
  1118. }
  1119. }
  1120. else
  1121. {
  1122. throw new NotImplementedException();
  1123. }
  1124. res = GetType(typename);
  1125. if (res == null)
  1126. {
  1127. typename = typename.Replace("/", "+");
  1128. res = GetType(typename);
  1129. }
  1130. if (res == null && scope != null)
  1131. res = GetType(typename + ", " + scope);
  1132. if (res == null)
  1133. {
  1134. if (scope != null)
  1135. {
  1136. string aname = scope.Split(',')[0];
  1137. foreach (var i in loadedAssemblies)
  1138. {
  1139. if (aname == i.GetName().Name)
  1140. {
  1141. res = GetType(typename + ", " + i.FullName);
  1142. if (res != null)
  1143. break;
  1144. }
  1145. }
  1146. }
  1147. if (res == null)
  1148. {
  1149. foreach (var j in loadedAssemblies)
  1150. {
  1151. res = GetType(typename + ", " + j.FullName);
  1152. if (res != null)
  1153. break;
  1154. }
  1155. }
  1156. if (res != null && scope != null)
  1157. {
  1158. mapType[typename + ", " + scope] = res;
  1159. }
  1160. }
  1161. if (res == null)
  1162. throw new KeyNotFoundException("Cannot find Type:" + typename);
  1163. if (genericArguments != null)
  1164. {
  1165. res = res.MakeGenericInstance(genericArguments);
  1166. if (!dummyGenericInstance && res is ILType)
  1167. {
  1168. ((ILType)res).TypeReference = (TypeReference)token;
  1169. }
  1170. if (!string.IsNullOrEmpty(res.FullName))
  1171. {
  1172. if (res is CLRType || !((ILType)res).TypeReference.HasGenericParameters)
  1173. mapType[res.FullName] = res;
  1174. }
  1175. }
  1176. mapTypeToken[res.GetHashCode()] = res;
  1177. if (!dummyGenericInstance)
  1178. mapTypeToken[hash] = res;
  1179. return res;
  1180. }
  1181. public IType GetType(int hash)
  1182. {
  1183. IType res;
  1184. if (mapTypeToken.TryGetValue(hash, out res))
  1185. return res;
  1186. else
  1187. return null;
  1188. }
  1189. /// <summary>
  1190. /// 根据CLR类型获取 IL类型
  1191. /// </summary>
  1192. /// <param name="t"></param>
  1193. /// <returns></returns>
  1194. public IType GetType(Type t)
  1195. {
  1196. IType res;
  1197. if (clrTypeMapping.TryGetValue(t, out res))
  1198. return res;
  1199. else
  1200. return GetType(t.AssemblyQualifiedName);
  1201. }
  1202. /// <summary>
  1203. /// Create a instance of the specified type, which is inherited from a CLR Type
  1204. /// </summary>
  1205. /// <typeparam name="T">CLR Type</typeparam>
  1206. /// <param name="type">Full Name of the type</param>
  1207. /// <param name="args">Arguments for the constructor</param>
  1208. /// <returns></returns>
  1209. public T Instantiate<T>(string type, object[] args = null)
  1210. {
  1211. ILTypeInstance ins = Instantiate(type, args);
  1212. return (T)ins.CLRInstance;
  1213. }
  1214. /// <summary>
  1215. /// Create a instance of the specified type
  1216. /// </summary>
  1217. /// <param name="type">Full Name of the type</param>
  1218. /// <param name="args">Arguments for the constructor</param>
  1219. /// <returns></returns>
  1220. public ILTypeInstance Instantiate(string type, object[] args = null)
  1221. {
  1222. IType t;
  1223. if (mapType.TryGetValue(type, out t))
  1224. {
  1225. ILType ilType = t as ILType;
  1226. if (ilType != null)
  1227. {
  1228. bool hasConstructor = args != null && args.Length != 0;
  1229. var res = ilType.Instantiate(!hasConstructor);
  1230. if (hasConstructor)
  1231. {
  1232. var ilm = ilType.GetConstructor(args.Length);
  1233. Invoke(ilm, res, args);
  1234. }
  1235. return res;
  1236. }
  1237. }
  1238. return null;
  1239. }
  1240. /// <summary>
  1241. /// Prewarm all methods of the specified type
  1242. /// </summary>
  1243. /// <param name="type"></param>
  1244. /// <param name="recursive"></param>
  1245. public void Prewarm(string type, bool recursive = true)
  1246. {
  1247. IType t = GetType(type);
  1248. if (t == null || t is CLRType)
  1249. return;
  1250. var methods = t.GetMethods();
  1251. foreach (var i in methods)
  1252. {
  1253. ((ILMethod)i).Prewarm(recursive);
  1254. }
  1255. }
  1256. /// <summary>
  1257. /// Prewarm all methods specified by the parameter
  1258. /// </summary>
  1259. /// <param name="info"></param>
  1260. /// <param name="recursive"></param>
  1261. public void Prewarm(PrewarmInfo[] info, bool recursive = true)
  1262. {
  1263. foreach(var i in info)
  1264. {
  1265. IType t = GetType(i.TypeName);
  1266. if (t == null || t is CLRType || i.MethodNames == null)
  1267. continue;
  1268. var methods = t.GetMethods();
  1269. foreach (var mn in i.MethodNames)
  1270. {
  1271. foreach(var j in methods)
  1272. {
  1273. ILMethod m = (ILMethod)j;
  1274. if(m.Name == mn && m.GenericParameterCount == 0)
  1275. {
  1276. m.Prewarm(recursive);
  1277. }
  1278. }
  1279. }
  1280. }
  1281. }
  1282. /// <summary>
  1283. /// Invoke a method
  1284. /// </summary>
  1285. /// <param name="type">Type's fullname</param>
  1286. /// <param name="method">Method name</param>
  1287. /// <param name="p">Parameters</param>
  1288. /// <returns></returns>
  1289. public object Invoke(string type, string method, object instance, params object[] p)
  1290. {
  1291. IType t = GetType(type);
  1292. if (t == null)
  1293. return null;
  1294. var m = t.GetMethod(method, p != null ? p.Length : 0);
  1295. if (m != null)
  1296. {
  1297. for (int i = 0; i < m.ParameterCount; i++)
  1298. {
  1299. if (p[i] == null)
  1300. continue;
  1301. if (!m.Parameters[i].TypeForCLR.IsAssignableFrom(p[i].GetType()))
  1302. {
  1303. throw new ArgumentException("Parameter type mismatch");
  1304. }
  1305. }
  1306. return Invoke(m, instance, p);
  1307. }
  1308. return null;
  1309. }
  1310. /// <summary>
  1311. /// Invoke a generic method
  1312. /// </summary>
  1313. /// <param name="type">Type's fullname</param>
  1314. /// <param name="method">Method name</param>
  1315. /// <param name="genericArguments">Generic Arguments</param>
  1316. /// <param name="instance">Object Instance of the method</param>
  1317. /// <param name="p">Parameters</param>
  1318. /// <returns></returns>
  1319. public object InvokeGenericMethod(string type, string method, IType[] genericArguments, object instance, params object[] p)
  1320. {
  1321. IType t = GetType(type);
  1322. if (t == null)
  1323. return null;
  1324. var m = t.GetMethod(method, p.Length);
  1325. if (m != null)
  1326. {
  1327. m = m.MakeGenericMethod(genericArguments);
  1328. return Invoke(m, instance, p);
  1329. }
  1330. return null;
  1331. }
  1332. internal ILIntepreter RequestILIntepreter()
  1333. {
  1334. ILIntepreter inteptreter = null;
  1335. lock (freeIntepreters)
  1336. {
  1337. if (freeIntepreters.Count > 0)
  1338. {
  1339. inteptreter = freeIntepreters.Dequeue();
  1340. //Clear debug state, because it may be in ShouldBreak State
  1341. inteptreter.ClearDebugState();
  1342. }
  1343. else
  1344. {
  1345. inteptreter = new ILIntepreter(this);
  1346. #if DEBUG && !DISABLE_ILRUNTIME_DEBUG
  1347. intepreters[inteptreter.GetHashCode()] = inteptreter;
  1348. debugService.ThreadStarted(inteptreter);
  1349. #endif
  1350. }
  1351. }
  1352. return inteptreter;
  1353. }
  1354. internal void FreeILIntepreter(ILIntepreter inteptreter)
  1355. {
  1356. lock (freeIntepreters)
  1357. {
  1358. #if DEBUG && !DISABLE_ILRUNTIME_DEBUG
  1359. if (inteptreter.CurrentStepType != StepTypes.None)
  1360. {
  1361. //We should resume all other threads if we are currently doing stepping operation
  1362. foreach (var i in intepreters)
  1363. {
  1364. if (i.Value != inteptreter)
  1365. {
  1366. i.Value.ClearDebugState();
  1367. i.Value.Resume();
  1368. }
  1369. }
  1370. inteptreter.ClearDebugState();
  1371. }
  1372. #endif
  1373. inteptreter.Stack.ManagedStack.Clear();
  1374. inteptreter.Stack.Frames.Clear();
  1375. inteptreter.Stack.ClearAllocator();
  1376. freeIntepreters.Enqueue(inteptreter);
  1377. #if DEBUG && !DISABLE_ILRUNTIME_DEBUG
  1378. //debugService.ThreadEnded(inteptreter);
  1379. #endif
  1380. }
  1381. }
  1382. /// <summary>
  1383. /// Invokes a specific method
  1384. /// </summary>
  1385. /// <param name="m">Method</param>
  1386. /// <param name="instance">object instance</param>
  1387. /// <param name="p">Parameters</param>
  1388. /// <returns></returns>
  1389. public object Invoke(IMethod m, object instance, params object[] p)
  1390. {
  1391. object res = null;
  1392. if (m is ILMethod)
  1393. {
  1394. ILIntepreter inteptreter = RequestILIntepreter();
  1395. try
  1396. {
  1397. res = inteptreter.Run((ILMethod)m, instance, p);
  1398. }
  1399. finally
  1400. {
  1401. FreeILIntepreter(inteptreter);
  1402. }
  1403. }
  1404. return res;
  1405. }
  1406. public InvocationContext BeginInvoke(IMethod m)
  1407. {
  1408. if (m is ILMethod)
  1409. {
  1410. ILIntepreter inteptreter = RequestILIntepreter();
  1411. return new InvocationContext(inteptreter, (ILMethod)m);
  1412. }
  1413. else
  1414. throw new NotSupportedException("Cannot invoke CLRMethod");
  1415. }
  1416. bool IsInvalidMethodReference(MethodReference _ref)
  1417. {
  1418. if ((_ref.DeclaringType.Name == "Object" || _ref.DeclaringType.Name == "Attribute")
  1419. && _ref.Name == ".ctor"
  1420. && _ref.DeclaringType.Namespace == "System"
  1421. && _ref.ReturnType.Name == "Void"
  1422. && _ref.ReturnType.Namespace == "System")
  1423. {
  1424. return true;
  1425. }
  1426. return false;
  1427. }
  1428. internal IMethod GetMethod(object token, ILType contextType, ILMethod contextMethod, out bool invalidToken)
  1429. {
  1430. string methodname = null;
  1431. string typename = null;
  1432. List<IType> paramList = null;
  1433. int hashCode = token.GetHashCode();
  1434. IMethod method;
  1435. IType[] genericArguments = null;
  1436. IType returnType;
  1437. invalidToken = false;
  1438. bool isConstructor = false;
  1439. if (mapMethod.TryGetValue(hashCode, out method))
  1440. return method;
  1441. IType type = null;
  1442. if (token is Mono.Cecil.MethodReference)
  1443. {
  1444. Mono.Cecil.MethodReference _ref = (token as Mono.Cecil.MethodReference);
  1445. if(IsInvalidMethodReference(_ref))
  1446. {
  1447. mapMethod[hashCode] = null;
  1448. return null;
  1449. }
  1450. methodname = _ref.Name;
  1451. var typeDef = _ref.DeclaringType;
  1452. type = GetType(typeDef, contextType, contextMethod);
  1453. if (type == null)
  1454. throw new KeyNotFoundException("Cannot find type:" + typename);
  1455. if (token is Mono.Cecil.MethodDefinition)
  1456. {
  1457. var def = _ref as MethodDefinition;
  1458. isConstructor = def.IsConstructor;
  1459. }
  1460. else
  1461. isConstructor = methodname == ".ctor";
  1462. if (_ref.IsGenericInstance)
  1463. {
  1464. GenericInstanceMethod gim = (GenericInstanceMethod)_ref;
  1465. genericArguments = new IType[gim.GenericArguments.Count];
  1466. for (int i = 0; i < genericArguments.Length; i++)
  1467. {
  1468. if (gim.GenericArguments[i].ContainsGenericParameter)
  1469. invalidToken = true;
  1470. var gt = GetType(gim.GenericArguments[i], contextType, contextMethod);
  1471. if (gt == null)
  1472. {
  1473. gt = contextMethod.FindGenericArgument(gim.GenericArguments[i].Name);
  1474. if (gt == null)//This means it contains unresolved generic arguments, which means it's not searching the generic instance
  1475. {
  1476. genericArguments = null;
  1477. break;
  1478. }
  1479. else
  1480. genericArguments[i] = gt;
  1481. }
  1482. else
  1483. genericArguments[i] = gt;
  1484. }
  1485. }
  1486. if (!invalidToken && typeDef.IsGenericInstance)
  1487. {
  1488. GenericInstanceType gim = (GenericInstanceType)typeDef;
  1489. for (int i = 0; i < gim.GenericArguments.Count; i++)
  1490. {
  1491. if (gim.GenericArguments[i].ContainsGenericParameter)
  1492. {
  1493. invalidToken = true;
  1494. break;
  1495. }
  1496. }
  1497. }
  1498. paramList = _ref.GetParamList(this, contextType, contextMethod, genericArguments);
  1499. returnType = GetType(_ref.ReturnType, type, null);
  1500. if (returnType == null)
  1501. returnType = GetType(_ref.ReturnType, contextType, null);
  1502. }
  1503. else
  1504. {
  1505. throw new NotImplementedException();
  1506. //Mono.Cecil.GenericInstanceMethod gmethod = _def as Mono.Cecil.GenericInstanceMethod;
  1507. //genlist = new MethodParamList(environment, gmethod);
  1508. }
  1509. if (isConstructor)
  1510. method = type.GetConstructor(paramList);
  1511. else
  1512. {
  1513. method = type.GetMethod(methodname, paramList, genericArguments, returnType, true);
  1514. }
  1515. if (method == null)
  1516. {
  1517. if (isConstructor && contextType.FirstCLRBaseType != null && contextType.FirstCLRBaseType is CrossBindingAdaptor && type.TypeForCLR == ((CrossBindingAdaptor)contextType.FirstCLRBaseType).BaseCLRType)
  1518. {
  1519. method = contextType.BaseType.GetConstructor(paramList);
  1520. if (method == null)
  1521. throw new KeyNotFoundException(string.Format("Cannot find method:{0} in type:{1}, token={2}", methodname, type.FullName, token));
  1522. invalidToken = true;
  1523. mapMethod[method.GetHashCode()] = method;
  1524. }
  1525. else
  1526. throw new KeyNotFoundException(string.Format("Cannot find method:{0} in type:{1}, token={2}", methodname, type.FullName, token));
  1527. }
  1528. if (!invalidToken)
  1529. mapMethod[hashCode] = method;
  1530. else
  1531. mapMethod[method.GetHashCode()] = method;
  1532. return method;
  1533. }
  1534. internal IMethod GetMethod(int tokenHash)
  1535. {
  1536. IMethod res;
  1537. if (mapMethod.TryGetValue(tokenHash, out res))
  1538. return res;
  1539. return null;
  1540. }
  1541. internal long GetStaticFieldIndex(object token, IType contextType, IMethod contextMethod)
  1542. {
  1543. FieldReference f = token as FieldReference;
  1544. var type = GetType(f.DeclaringType, contextType, contextMethod);
  1545. if (type is ILType)
  1546. {
  1547. var it = type as ILType;
  1548. int idx = it.GetFieldIndex(token);
  1549. long res = 0;
  1550. if (it.TypeReference.HasGenericParameters)
  1551. {
  1552. mapTypeToken[type.GetHashCode()] = it;
  1553. }
  1554. res = ((long)type.GetHashCode() << 32) | (uint)idx;
  1555. return res;
  1556. }
  1557. else
  1558. {
  1559. int idx = type.GetFieldIndex(token);
  1560. long res = ((long)type.GetHashCode() << 32) | (uint)idx;
  1561. return res;
  1562. }
  1563. }
  1564. internal long CacheString(object token)
  1565. {
  1566. long oriHash = token.GetHashCode() & 0xFFFFFFFF;
  1567. long hashCode = oriHash;
  1568. string str = (string)token;
  1569. lock (mapString)
  1570. {
  1571. bool isCollision = CheckStringCollision(hashCode, str);
  1572. long cnt = 0;
  1573. while (isCollision)
  1574. {
  1575. cnt++;
  1576. hashCode = cnt << 32 | oriHash;
  1577. isCollision = CheckStringCollision(hashCode, str);
  1578. }
  1579. mapString[hashCode] = (string)token;
  1580. }
  1581. return hashCode;
  1582. }
  1583. bool CheckStringCollision(long hashCode, string newStr)
  1584. {
  1585. string oldVal;
  1586. if (mapString.TryGetValue(hashCode, out oldVal))
  1587. return oldVal != newStr;
  1588. return false;
  1589. }
  1590. internal string GetString(long hashCode)
  1591. {
  1592. string res = null;
  1593. if (mapString.TryGetValue(hashCode, out res))
  1594. return res;
  1595. return res;
  1596. }
  1597. public void RegisterCrossBindingAdaptor(CrossBindingAdaptor adaptor)
  1598. {
  1599. var bType = adaptor.BaseCLRType;
  1600. if (bType != null)
  1601. {
  1602. if (!crossAdaptors.ContainsKey(bType))
  1603. {
  1604. var t = adaptor.AdaptorType;
  1605. var res = GetType(t);
  1606. if (res == null)
  1607. {
  1608. res = new CLRType(t, this);
  1609. mapType[res.FullName] = res;
  1610. mapType[t.AssemblyQualifiedName] = res;
  1611. clrTypeMapping[t] = res;
  1612. }
  1613. adaptor.RuntimeType = res;
  1614. crossAdaptors[bType] = adaptor;
  1615. }
  1616. else
  1617. throw new Exception("Crossbinding Adapter for " + bType.FullName + " is already added.");
  1618. }
  1619. else
  1620. {
  1621. var bTypes = adaptor.BaseCLRTypes;
  1622. var t = adaptor.AdaptorType;
  1623. var res = GetType(t);
  1624. if (res == null)
  1625. {
  1626. res = new CLRType(t, this);
  1627. mapType[res.FullName] = res;
  1628. mapType[t.AssemblyQualifiedName] = res;
  1629. clrTypeMapping[t] = res;
  1630. }
  1631. adaptor.RuntimeType = res;
  1632. foreach (var i in bTypes)
  1633. {
  1634. if (!crossAdaptors.ContainsKey(i))
  1635. {
  1636. crossAdaptors[i] = adaptor;
  1637. }
  1638. else
  1639. throw new Exception("Crossbinding Adapter for " + i.FullName + " is already added.");
  1640. }
  1641. }
  1642. }
  1643. public unsafe int GetSizeInMemory(out List<TypeSizeInfo> detail)
  1644. {
  1645. int size = RuntimeStack.MAXIMAL_STACK_OBJECTS * sizeof(StackObject) * (intepreters.Count);
  1646. detail = new List<TypeSizeInfo>();
  1647. HashSet<object> traversed = new HashSet<object>();
  1648. foreach(var i in LoadedTypes)
  1649. {
  1650. ILType type = i.Value as ILType;
  1651. if(type != null)
  1652. {
  1653. TypeSizeInfo info = new TypeSizeInfo();
  1654. info.Type = type;
  1655. info.StaticFieldSize = type.GetStaticFieldSizeInMemory(traversed);
  1656. info.MethodBodySize = type.GetMethodBodySizeInMemory();
  1657. info.TotalSize = info.StaticFieldSize + info.MethodBodySize;
  1658. size += info.TotalSize;
  1659. detail.Add(info);
  1660. }
  1661. }
  1662. detail.Sort((a, b) => b.TotalSize - a.TotalSize);
  1663. return size;
  1664. }
  1665. }
  1666. }