2 // System.Reflection.Emit/DynamicMethod.cs
5 // Paolo Molaro (lupus@ximian.com)
6 // Zoltan Varga (vargaz@freemail.hu)
8 // (C) 2003 Ximian, Inc. http://www.ximian.com
14 using System.Reflection;
15 using System.Reflection.Emit;
16 using System.Globalization;
17 using System.Runtime.CompilerServices;
18 using System.Runtime.InteropServices;
20 namespace System.Reflection.Emit {
22 public sealed class DynamicMethod : MethodInfo {
23 #region Sync with reflection.h
24 private RuntimeMethodHandle mhandle;
26 private Type returnType;
27 private Type[] parameters;
28 private MethodAttributes attributes;
29 private CallingConventions callingConvention;
30 private Module module;
31 private bool skipVisibility;
32 private bool init_locals = true;
33 private ILGenerator ilgen;
35 private object[] refs;
37 private Delegate deleg;
38 private MonoMethod method;
39 private ParameterBuilder[] pinfo;
41 public DynamicMethod (string name, Type returnType, Type[] parameterTypes, Module m) : this (name, returnType, parameterTypes, m, false) {
44 public DynamicMethod (string name, Type returnType, Type[] parameterTypes, Type owner) : this (name, returnType, parameterTypes, owner, false) {
47 public DynamicMethod (string name, Type returnType, Type[] parameterTypes, Module m, bool skipVisibility) : this (name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, m, skipVisibility) {
50 public DynamicMethod (string name, Type returnType, Type[] parameterTypes, Type owner, bool skipVisibility) : this (name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, owner, skipVisibility) {
53 public DynamicMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type owner, bool skipVisibility) : this (name, attributes, callingConvention, returnType, parameterTypes, owner.Module, skipVisibility) {
56 public DynamicMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Module m, bool skipVisibility) {
58 throw new ArgumentNullException ("name");
59 if (name == String.Empty)
60 throw new ArgumentException ("Name can't be empty", "name");
61 if (returnType == null)
62 throw new ArgumentNullException ("returnType");
64 throw new ArgumentNullException ("m");
65 if (returnType.IsByRef)
66 throw new ArgumentException ("Return type can't be a byref type", "returnType");
67 if (parameterTypes != null) {
68 for (int i = 0; i < parameterTypes.Length; ++i)
69 if (parameterTypes [i] == null)
70 throw new ArgumentException ("Parameter " + i + " is null", "parameterTypes");
74 this.attributes = attributes | MethodAttributes.Static;
75 this.callingConvention = callingConvention;
76 this.returnType = returnType;
77 this.parameters = parameterTypes;
79 this.skipVisibility = skipVisibility;
82 [MethodImplAttribute(MethodImplOptions.InternalCall)]
83 private extern void create_dynamic_method (DynamicMethod m);
85 private void CreateDynMethod () {
86 if (mhandle.Value == IntPtr.Zero)
87 create_dynamic_method (this);
90 public Delegate CreateDelegate (Type delegateType) {
91 if (delegateType == null)
92 throw new ArgumentNullException ("delegateType");
98 deleg = Delegate.CreateDelegate (delegateType, this);
103 public ParameterBuilder DefineParameter (int position, ParameterAttributes attributes, string strParamName)
106 // Extension: Mono allows position == 0 for the return attribute
108 if ((position < 0) || (position > parameters.Length))
109 throw new ArgumentOutOfRangeException ("position");
113 throw new NotImplementedException ();
116 public override MethodInfo GetBaseDefinition () {
121 public override object[] GetCustomAttributes (bool inherit) {
122 throw new NotImplementedException ();
126 public override object[] GetCustomAttributes (Type attributeType,
128 throw new NotImplementedException ();
131 public ILGenerator GetILGenerator () {
132 return GetILGenerator (64);
135 public ILGenerator GetILGenerator (int size) {
136 if (((GetMethodImplementationFlags () & MethodImplAttributes.CodeTypeMask) !=
137 MethodImplAttributes.IL) ||
138 ((GetMethodImplementationFlags () & MethodImplAttributes.ManagedMask) !=
139 MethodImplAttributes.Managed))
140 throw new InvalidOperationException ("Method body should not exist.");
143 ilgen = new ILGenerator (Module, new DynamicMethodTokenGenerator (this), size);
147 public override MethodImplAttributes GetMethodImplementationFlags () {
148 return MethodImplAttributes.IL | MethodImplAttributes.Managed;
151 public override ParameterInfo[] GetParameters () {
152 if (parameters == null)
153 return new ParameterInfo [0];
155 ParameterInfo[] retval = new ParameterInfo [parameters.Length];
156 for (int i = 0; i < parameters.Length; i++) {
157 retval [i] = new ParameterInfo (pinfo == null ? null : pinfo [i + 1], parameters [i], this, i + 1);
162 public override object Invoke (object obj, object[] parameters) {
165 method = new MonoMethod (mhandle);
166 return method.Invoke (obj, parameters);
169 public override object Invoke (object obj, BindingFlags invokeAttr,
170 Binder binder, object[] parameters,
171 CultureInfo culture) {
174 method = new MonoMethod (mhandle);
175 return method.Invoke (obj, parameters);
179 public override bool IsDefined (Type attributeType, bool inherit) {
180 throw new NotImplementedException ();
183 public override string ToString () {
185 ParameterInfo[] p = GetParameters ();
186 for (int i = 0; i < p.Length; ++i) {
188 parms = parms + ", ";
189 parms = parms + p [i].ParameterType.Name;
191 return ReturnType.Name+" "+Name+"("+parms+")";
194 public override MethodAttributes Attributes {
200 public override CallingConventions CallingConvention {
202 return callingConvention;
206 public override Type DeclaringType {
212 public bool InitLocals {
221 public override RuntimeMethodHandle MethodHandle {
227 public Module Module {
233 public override string Name {
239 public override Type ReflectedType {
246 public ParameterInfo ReturnParameter {
248 throw new NotImplementedException ();
252 public override Type ReturnType {
259 public override ICustomAttributeProvider ReturnTypeCustomAttributes {
261 throw new NotImplementedException ();
265 private void RejectIfCreated () {
266 if (mhandle.Value != IntPtr.Zero)
267 throw new InvalidOperationException ("Type definition of the method is complete.");
270 private Exception NotSupported () {
271 return new NotSupportedException ("The invoked member is not supported on a dynamic method.");
274 internal int AddRef (object reference) {
276 refs = new object [4];
277 if (nrefs >= refs.Length) {
278 object [] new_refs = new object [refs.Length * 2];
279 System.Array.Copy (refs, new_refs, refs.Length);
282 refs [nrefs] = reference;
288 internal class DynamicMethodTokenGenerator : TokenGenerator {
290 private DynamicMethod m;
292 public DynamicMethodTokenGenerator (DynamicMethod m) {
296 public int GetToken (string str) {
297 return m.AddRef (str);
300 public int GetToken (MemberInfo member) {
301 return m.AddRef (member);
304 public int GetToken (SignatureHelper helper) {
305 return m.AddRef (helper);