2
0

MethSigClass.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /*
  2. * PERWAPI - An API for Reading and Writing PE Files
  3. *
  4. * Copyright (c) Diane Corney, Queensland University of Technology, 2004.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the PERWAPI Copyright as included with this
  8. * distribution in the file PERWAPIcopyright.rtf.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY as is explained in the copyright notice.
  12. *
  13. * The author may be contacted at d.corney@qut.edu.au
  14. *
  15. * Version Date: 26/01/07
  16. */
  17. using System;
  18. using System.IO;
  19. using System.Collections;
  20. namespace QUT.PERWAPI
  21. {
  22. /**************************************************************************/
  23. public class MethSig
  24. {
  25. internal string name;
  26. internal CallConv callConv = CallConv.Default;
  27. internal Type retType;
  28. internal Type[] parTypes, optParTypes;
  29. internal uint numPars = 0, numOptPars = 0, numGenPars = 0;
  30. //uint sigIx;
  31. /*-------------------- Constructors ---------------------------------*/
  32. internal MethSig(string nam)
  33. {
  34. name = nam;
  35. }
  36. internal MethSig InstantiateGenTypes(Class classType, Type[] genTypes)
  37. {
  38. MethSig newSig = new MethSig(name);
  39. newSig.callConv = callConv;
  40. newSig.numPars = numPars;
  41. newSig.numOptPars = numOptPars;
  42. newSig.numGenPars = numGenPars;
  43. newSig.parTypes = ReplaceGenPars(parTypes, classType, genTypes);
  44. newSig.optParTypes = ReplaceGenPars(optParTypes, classType, genTypes);
  45. newSig.retType = SubstituteType(retType, classType, genTypes);
  46. return newSig;
  47. }
  48. private Type[] ReplaceGenPars(Type[] typeList, MetaDataElement paren, Type[] genTypes)
  49. {
  50. if (typeList == null) return null;
  51. Type[] newList = new Type[typeList.Length];
  52. for (int i = 0; i < typeList.Length; i++)
  53. {
  54. newList[i] = SubstituteType(typeList[i], paren, genTypes);
  55. }
  56. return newList;
  57. }
  58. private Type SubstituteType(Type origType, MetaDataElement paren, Type[] genTypes)
  59. {
  60. if ((origType is GenericParam) && (((GenericParam)origType).GetParent() == paren))
  61. return genTypes[((GenericParam)origType).Index];
  62. return origType;
  63. }
  64. internal void SetParTypes(Param[] parList)
  65. {
  66. if (parList == null) { numPars = 0; return; }
  67. numPars = (uint)parList.Length;
  68. parTypes = new Type[numPars];
  69. for (int i = 0; i < numPars; i++)
  70. {
  71. parTypes[i] = parList[i].GetParType();
  72. }
  73. }
  74. internal void ChangeParTypes(ClassDef newType, ClassDef[] oldTypes)
  75. {
  76. System.Diagnostics.Debug.Assert(newType != null);
  77. for (int i = 0; i < oldTypes.Length; i++)
  78. {
  79. if (retType == oldTypes[i]) retType = newType;
  80. for (int j = 0; j < numPars; j++)
  81. {
  82. if (parTypes[j] == oldTypes[i])
  83. parTypes[j] = newType;
  84. }
  85. for (int j = 0; j < numOptPars; j++)
  86. {
  87. if (optParTypes[j] == oldTypes[i])
  88. optParTypes[j] = newType;
  89. }
  90. }
  91. }
  92. internal Type MakeRefRetType()
  93. {
  94. if (retType is ClassDef)
  95. {
  96. return ((ClassDef)retType).MakeRefOf();
  97. }
  98. else
  99. {
  100. return retType;
  101. }
  102. }
  103. internal Type[] MakeRefParTypes()
  104. {
  105. Type[] pTypes = new Type[numPars];
  106. for (int i = 0; i < numPars; i++)
  107. {
  108. if (parTypes[i] is ClassDef)
  109. {
  110. pTypes[i] = ((ClassDef)parTypes[i]).MakeRefOf();
  111. }
  112. else
  113. {
  114. pTypes[i] = parTypes[i];
  115. }
  116. }
  117. return pTypes;
  118. }
  119. /*
  120. * internal bool HasNameAndSig(string name, Type[] sigTypes) {
  121. if (this.name.CompareTo(name) != 0) return false;
  122. return HasSig(sigTypes);
  123. }
  124. internal bool HasNameAndSig(string name, Type[] sigTypes, Type[] optTypes) {
  125. if (this.name.CompareTo(name) != 0) return false;
  126. return HasSig(sigTypes,optTypes);
  127. }
  128. */
  129. internal bool HasSig(Type[] sigTypes)
  130. {
  131. if (sigTypes == null) return (numPars == 0);
  132. if (sigTypes.Length != numPars) return false;
  133. for (int i = 0; i < numPars; i++)
  134. {
  135. if (!sigTypes[i].SameType(parTypes[i]))
  136. return false;
  137. }
  138. return (optParTypes == null) || (optParTypes.Length == 0);
  139. }
  140. internal bool HasSig(Type[] sigTypes, Type[] optTypes)
  141. {
  142. if (sigTypes == null)
  143. {
  144. if (numPars > 0) return false;
  145. if (optTypes == null) return (numOptPars == 0);
  146. }
  147. if (sigTypes.Length != numPars) return false;
  148. for (int i = 0; i < numPars; i++)
  149. {
  150. if (!sigTypes[i].SameType(parTypes[i]))
  151. return false;
  152. }
  153. if (optTypes == null) return numOptPars == 0;
  154. if (optTypes.Length != numOptPars) return false;
  155. for (int i = 0; i < optTypes.Length; i++)
  156. {
  157. if (!optTypes[i].SameType(optParTypes[i]))
  158. return false;
  159. }
  160. return true;
  161. }
  162. /*
  163. internal void CheckParTypes(Param[] parList) {
  164. //numGenPars = 0;
  165. for (int i=0; i < numPars; i++) {
  166. if (parTypes[i] is GenericParam)
  167. numGenPars++;
  168. }
  169. if (numGenPars > 0)
  170. callConv |= CallConv.Generic;
  171. else if ((callConv & CallConv.Generic) > 0)
  172. callConv ^= CallConv.Generic;
  173. }
  174. */
  175. internal void TypeSig(MemoryStream sig)
  176. {
  177. sig.WriteByte((byte)callConv);
  178. if (numGenPars > 0)
  179. MetaDataOut.CompressNum(BlobUtil.CompressUInt(numGenPars), sig);
  180. MetaDataOut.CompressNum(BlobUtil.CompressUInt(numPars + numOptPars), sig);
  181. retType.TypeSig(sig);
  182. for (int i = 0; i < numPars; i++)
  183. {
  184. parTypes[i].TypeSig(sig);
  185. }
  186. if (numOptPars > 0)
  187. {
  188. sig.WriteByte((byte)ElementType.Sentinel);
  189. for (int i = 0; i < numOptPars; i++)
  190. {
  191. optParTypes[i].TypeSig(sig);
  192. }
  193. }
  194. }
  195. /// <summary>
  196. /// Check to see if the method signature has a particular calling convention.
  197. /// </summary>
  198. /// <param name="callCon">The convention to check to see if the method has.</param>
  199. /// <returns>Ture if the calling convention exists on the method.</returns>
  200. internal bool HasCallConv(CallConv callCon)
  201. {
  202. return ((callConv & callCon) == callCon);
  203. }
  204. internal void WriteCallConv(CILWriter output)
  205. {
  206. if ((callConv & CallConv.Instance) != 0)
  207. {
  208. output.Write("instance ");
  209. if ((callConv & CallConv.InstanceExplicit) == CallConv.InstanceExplicit)
  210. {
  211. output.Write("explicit ");
  212. }
  213. }
  214. uint callKind = (uint)callConv & 0x07;
  215. switch (callKind)
  216. {
  217. case 0: break;
  218. case 1: output.Write("unmanaged cdecl "); break;
  219. case 2: output.Write("unmanaged stdcall "); break;
  220. case 3: output.Write("unmanaged thiscall "); break;
  221. case 4: output.Write("unmanaged fastcall "); break;
  222. case 5: output.Write("vararg "); break;
  223. }
  224. }
  225. internal void Write(CILWriter output)
  226. {
  227. WriteCallConv(output);
  228. retType.WriteType(output);
  229. }
  230. internal void WriteParTypes(CILWriter output)
  231. {
  232. output.Write("(");
  233. for (int i = 0; i < numPars; i++)
  234. {
  235. parTypes[i].WriteType(output);
  236. if ((i < numPars - 1) || (numOptPars > 0))
  237. output.Write(", ");
  238. }
  239. for (int i = 0; i < numOptPars; i++)
  240. {
  241. optParTypes[i].WriteType(output);
  242. if (i < numPars - 1)
  243. output.Write(", ");
  244. }
  245. output.Write(")");
  246. }
  247. internal string NameString()
  248. {
  249. string parString = "(";
  250. if (numPars > 0)
  251. {
  252. parString += parTypes[0].NameString();
  253. for (int i = 1; i < numPars; i++)
  254. {
  255. parString += "," + parTypes[i].NameString();
  256. }
  257. }
  258. if (numOptPars > 0)
  259. {
  260. if (numPars > 0) parString += ",";
  261. parString += optParTypes[0].NameString();
  262. for (int i = 1; i < numOptPars; i++)
  263. {
  264. parString += "," + optParTypes[i].NameString();
  265. }
  266. }
  267. return name + parString + ")";
  268. }
  269. internal void BuildTables(MetaDataOut md)
  270. {
  271. if (!retType.isDef())
  272. retType.BuildMDTables(md);
  273. for (int i = 0; i < numPars; i++)
  274. {
  275. if (!parTypes[i].isDef())
  276. parTypes[i].BuildMDTables(md);
  277. }
  278. for (int i = 0; i < numOptPars; i++)
  279. {
  280. if (!optParTypes[i].isDef())
  281. optParTypes[i].BuildMDTables(md);
  282. }
  283. }
  284. internal void BuildCILInfo(CILWriter output)
  285. {
  286. if (!retType.isDef())
  287. retType.BuildCILInfo(output);
  288. for (int i = 0; i < numPars; i++)
  289. {
  290. if (!parTypes[i].isDef())
  291. parTypes[i].BuildCILInfo(output);
  292. }
  293. for (int i = 0; i < numOptPars; i++)
  294. {
  295. if (!optParTypes[i].isDef())
  296. optParTypes[i].BuildCILInfo(output);
  297. }
  298. }
  299. internal void BuildSignatures(MetaDataOut md)
  300. {
  301. if (!retType.isDef())
  302. retType.BuildSignatures(md);
  303. for (int i = 0; i < numPars; i++)
  304. {
  305. if (!parTypes[i].isDef())
  306. parTypes[i].BuildSignatures(md);
  307. }
  308. for (int i = 0; i < numOptPars; i++)
  309. {
  310. if (!optParTypes[i].isDef())
  311. optParTypes[i].BuildSignatures(md);
  312. }
  313. }
  314. }
  315. }