MethodBuilder.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. //
  2. // System.Reflection.Emit/MethodBuilder.cs
  3. //
  4. // Author:
  5. // Paolo Molaro ([email protected])
  6. //
  7. // (C) 2001 Ximian, Inc. http://www.ximian.com
  8. //
  9. using System;
  10. using System.Reflection;
  11. using System.Reflection.Emit;
  12. using System.Globalization;
  13. using System.Security;
  14. using System.Security.Permissions;
  15. using System.Runtime.CompilerServices;
  16. using System.Runtime.InteropServices;
  17. namespace System.Reflection.Emit {
  18. public sealed class MethodBuilder : MethodInfo {
  19. private RuntimeMethodHandle mhandle;
  20. private Type rtype;
  21. private Type[] parameters;
  22. private MethodAttributes attrs;
  23. private MethodImplAttributes iattrs;
  24. private string name;
  25. private int table_idx;
  26. private byte[] code;
  27. private ILGenerator ilgen;
  28. private TypeBuilder type;
  29. private ParameterBuilder[] pinfo;
  30. private CustomAttributeBuilder[] cattrs;
  31. private MethodInfo override_method;
  32. private string pi_dll;
  33. private string pi_entry;
  34. private CharSet ncharset;
  35. private CallingConvention native_cc;
  36. private CallingConventions call_conv;
  37. private bool init_locals = true;
  38. private MonoGenericParam[] generic_params;
  39. private Type[] returnModReq;
  40. private Type[] returnModOpt;
  41. private Type[][] paramModReq;
  42. private Type[][] paramModOpt;
  43. private RefEmitPermissionSet[] permissions;
  44. internal MethodBuilder (TypeBuilder tb, string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnModReq, Type[] returnModOpt, Type[] parameterTypes, Type[][] paramModReq, Type[][] paramModOpt) {
  45. this.name = name;
  46. this.attrs = attributes;
  47. this.call_conv = callingConvention;
  48. this.rtype = returnType;
  49. this.returnModReq = returnModReq;
  50. this.returnModOpt = returnModOpt;
  51. this.paramModReq = paramModReq;
  52. this.paramModOpt = paramModOpt;
  53. // The MSDN docs does not specify this, but the MS MethodBuilder
  54. // appends a HasThis flag if the method is not static
  55. if ((attributes & MethodAttributes.Static) == 0)
  56. this.call_conv |= CallingConventions.HasThis;
  57. if (parameterTypes != null) {
  58. this.parameters = new Type [parameterTypes.Length];
  59. System.Array.Copy (parameterTypes, this.parameters, parameterTypes.Length);
  60. }
  61. type = tb;
  62. table_idx = get_next_table_index (this, 0x06, true);
  63. //Console.WriteLine ("index for "+name+" set to "+table_idx.ToString());
  64. }
  65. internal MethodBuilder (TypeBuilder tb, string name, MethodAttributes attributes,
  66. CallingConventions callingConvention, Type returnType, Type[] returnModReq, Type[] returnModOpt, Type[] parameterTypes, Type[][] paramModReq, Type[][] paramModOpt,
  67. String dllName, String entryName, CallingConvention nativeCConv, CharSet nativeCharset)
  68. : this (tb, name, attributes, callingConvention, returnType, returnModReq, returnModOpt, parameterTypes, paramModReq, paramModOpt) {
  69. pi_dll = dllName;
  70. pi_entry = entryName;
  71. native_cc = nativeCConv;
  72. ncharset = nativeCharset;
  73. }
  74. public bool InitLocals {
  75. get {return init_locals;}
  76. set {init_locals = value;}
  77. }
  78. internal TypeBuilder TypeBuilder {
  79. get {return type;}
  80. }
  81. public override RuntimeMethodHandle MethodHandle {
  82. get {
  83. throw NotSupported ();
  84. }
  85. }
  86. public override Type ReturnType {get {return rtype;}}
  87. public override Type ReflectedType {get {return type;}}
  88. public override Type DeclaringType {get {return type;}}
  89. public override string Name {get {return name;}}
  90. public override MethodAttributes Attributes {get {return attrs;}}
  91. public override ICustomAttributeProvider ReturnTypeCustomAttributes {
  92. get {return null;}
  93. }
  94. public override CallingConventions CallingConvention {
  95. get { return call_conv; }
  96. }
  97. [MonoTODO]
  98. public string Signature {
  99. get {
  100. throw new NotImplementedException ();
  101. }
  102. }
  103. public MethodToken GetToken() {
  104. return new MethodToken(0x06000000 | table_idx);
  105. }
  106. public override MethodInfo GetBaseDefinition() {
  107. return this;
  108. }
  109. public override MethodImplAttributes GetMethodImplementationFlags() {
  110. return iattrs;
  111. }
  112. public override ParameterInfo[] GetParameters() {
  113. if (parameters == null)
  114. return null;
  115. ParameterInfo[] retval = new ParameterInfo [parameters.Length];
  116. for (int i = 0; i < parameters.Length; i++) {
  117. retval [i] = new ParameterInfo (pinfo == null ? null : pinfo [i + 1], parameters [i], this, i + 1);
  118. }
  119. return retval;
  120. }
  121. internal override int GetParameterCount ()
  122. {
  123. if (parameters == null)
  124. return 0;
  125. return parameters.Length;
  126. }
  127. public Module GetModule () {
  128. return type.Module;
  129. }
  130. public void CreateMethodBody( byte[] il, int count) {
  131. if ((il != null) && ((count < 0) || (count > il.Length)))
  132. throw new ArgumentException ("Index was out of range. Must be non-negative and less than the size of the collection.");
  133. if ((code != null) || type.is_created)
  134. throw new InvalidOperationException ("Type definition of the method is complete.");
  135. if (il == null)
  136. code = null;
  137. else {
  138. code = new byte [count];
  139. System.Array.Copy(il, code, count);
  140. }
  141. }
  142. public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) {
  143. throw NotSupported ();
  144. }
  145. public override bool IsDefined (Type attribute_type, bool inherit) {
  146. throw NotSupported ();
  147. }
  148. public override object[] GetCustomAttributes( bool inherit) {
  149. throw NotSupported ();
  150. }
  151. public override object[] GetCustomAttributes( Type attributeType, bool inherit) {
  152. throw NotSupported ();
  153. }
  154. public ILGenerator GetILGenerator () {
  155. return GetILGenerator (64);
  156. }
  157. public ILGenerator GetILGenerator (int size) {
  158. if (((iattrs & MethodImplAttributes.CodeTypeMask) !=
  159. MethodImplAttributes.IL) ||
  160. ((iattrs & MethodImplAttributes.ManagedMask) !=
  161. MethodImplAttributes.Managed))
  162. throw new InvalidOperationException ("Method body should not exist.");
  163. if (ilgen != null)
  164. return ilgen;
  165. ilgen = new ILGenerator (type.Module, ((ModuleBuilder)type.Module).GetTokenGenerator (), size);
  166. return ilgen;
  167. }
  168. public ParameterBuilder DefineParameter (int position, ParameterAttributes attributes, string strParamName)
  169. {
  170. //
  171. // Extension: Mono allows position == 0 for the return attribute
  172. //
  173. if ((position < 0) || (position > parameters.Length))
  174. throw new ArgumentOutOfRangeException ("position");
  175. RejectIfCreated ();
  176. ParameterBuilder pb = new ParameterBuilder (this, position, attributes, strParamName);
  177. if (pinfo == null)
  178. pinfo = new ParameterBuilder [parameters.Length + 1];
  179. pinfo [position] = pb;
  180. return pb;
  181. }
  182. internal void fixup () {
  183. if (ilgen != null)
  184. ilgen.label_fixup ();
  185. }
  186. public void SetCustomAttribute( CustomAttributeBuilder customBuilder) {
  187. if (customBuilder == null)
  188. throw new ArgumentNullException ("customBuilder");
  189. string attrname = customBuilder.Ctor.ReflectedType.FullName;
  190. if (attrname == "System.Runtime.CompilerServices.MethodImplAttribute") {
  191. byte[] data = customBuilder.Data;
  192. int impla; // the (stupid) ctor takes a short or an int ...
  193. impla = (int)data [2];
  194. impla |= ((int)data [3]) << 8;
  195. SetImplementationFlags ((MethodImplAttributes)impla);
  196. return;
  197. }
  198. if (cattrs != null) {
  199. CustomAttributeBuilder[] new_array = new CustomAttributeBuilder [cattrs.Length + 1];
  200. cattrs.CopyTo (new_array, 0);
  201. new_array [cattrs.Length] = customBuilder;
  202. cattrs = new_array;
  203. } else {
  204. cattrs = new CustomAttributeBuilder [1];
  205. cattrs [0] = customBuilder;
  206. }
  207. }
  208. public void SetCustomAttribute( ConstructorInfo con, byte[] binaryAttribute) {
  209. if (con == null)
  210. throw new ArgumentNullException ("con");
  211. if (binaryAttribute == null)
  212. throw new ArgumentNullException ("binaryAttribute");
  213. SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute));
  214. }
  215. public void SetImplementationFlags( MethodImplAttributes attributes) {
  216. RejectIfCreated ();
  217. iattrs = attributes;
  218. }
  219. public void AddDeclarativeSecurity( SecurityAction action, PermissionSet pset) {
  220. if (pset == null)
  221. throw new ArgumentNullException ("pset");
  222. if ((action == SecurityAction.RequestMinimum) ||
  223. (action == SecurityAction.RequestOptional) ||
  224. (action == SecurityAction.RequestRefuse))
  225. throw new ArgumentException ("Request* values are not permitted", "action");
  226. RejectIfCreated ();
  227. if (permissions != null) {
  228. /* Check duplicate actions */
  229. foreach (RefEmitPermissionSet set in permissions)
  230. if (set.action == action)
  231. throw new InvalidOperationException ("Multiple permission sets specified with the same SecurityAction.");
  232. RefEmitPermissionSet[] new_array = new RefEmitPermissionSet [permissions.Length + 1];
  233. permissions.CopyTo (new_array, 0);
  234. permissions = new_array;
  235. }
  236. else
  237. permissions = new RefEmitPermissionSet [1];
  238. permissions [permissions.Length - 1] = new RefEmitPermissionSet (action, pset.ToXml ().ToString ());
  239. attrs |= MethodAttributes.HasSecurity;
  240. }
  241. [MonoTODO]
  242. public void SetMarshal (UnmanagedMarshal unmanagedMarshal)
  243. {
  244. RejectIfCreated ();
  245. throw new NotImplementedException ();
  246. }
  247. [MonoTODO]
  248. public void SetSymCustomAttribute (string name, byte[] data)
  249. {
  250. RejectIfCreated ();
  251. throw new NotImplementedException ();
  252. }
  253. internal override int get_next_table_index (object obj, int table, bool inc) {
  254. return type.get_next_table_index (obj, table, inc);
  255. }
  256. internal void set_override (MethodInfo mdecl) {
  257. override_method = mdecl;
  258. }
  259. private void RejectIfCreated () {
  260. if (type.is_created)
  261. throw new InvalidOperationException ("Type definition of the method is complete.");
  262. }
  263. private Exception NotSupported () {
  264. return new NotSupportedException ("The invoked member is not supported in a dynamic module.");
  265. }
  266. #if NET_1_2
  267. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  268. private extern MonoGenericParam define_generic_parameter (string name, int index);
  269. public Type DefineGenericParameter (string name)
  270. {
  271. int index;
  272. if (generic_params != null) {
  273. MonoGenericParam[] new_generic_params = new MonoGenericParam [generic_params.Length+1];
  274. System.Array.Copy (generic_params, new_generic_params, generic_params.Length);
  275. index = generic_params.Length;
  276. generic_params = new_generic_params;
  277. } else {
  278. generic_params = new MonoGenericParam [1];
  279. index = 0;
  280. }
  281. generic_params [index] = define_generic_parameter (name, index);
  282. return generic_params [index];
  283. }
  284. public void SetGenericParameterConstraints (int index, Type[] constraints)
  285. {
  286. generic_params [index].SetConstraints (constraints);
  287. }
  288. public override Type[] GetGenericArguments ()
  289. {
  290. if (generic_params == null)
  291. return new Type [0];
  292. Type[] result = new Type [generic_params.Length];
  293. for (int i = 0; i < generic_params.Length; i++)
  294. result [i] = generic_params [i];
  295. return result;
  296. }
  297. public void SetGenericMethodSignature (Type return_type, Type[] parameter_types)
  298. {
  299. RejectIfCreated ();
  300. this.rtype = return_type;
  301. this.parameters = new Type [parameter_types.Length];
  302. System.Array.Copy (parameter_types, this.parameters, parameter_types.Length);
  303. }
  304. #endif
  305. }
  306. }