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
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 #if NET_2_0 || BOOTSTRAP_NET_2_0
37 using System.Reflection;
38 using System.Reflection.Emit;
39 using System.Globalization;
40 using System.Runtime.CompilerServices;
41 using System.Runtime.InteropServices;
43 namespace System.Reflection.Emit {
48 public sealed class DynamicMethod : MethodInfo {
49 #region Sync with reflection.h
50 private RuntimeMethodHandle mhandle;
52 private Type returnType;
53 private Type[] parameters;
54 private MethodAttributes attributes;
55 private CallingConventions callingConvention;
56 private Module module;
57 private bool skipVisibility;
58 private bool init_locals = true;
59 private ILGenerator ilgen;
61 private object[] refs;
63 private Delegate deleg;
64 private MonoMethod method;
65 private ParameterBuilder[] pinfo;
67 public DynamicMethod (string name, Type returnType, Type[] parameterTypes, Module m) : this (name, returnType, parameterTypes, m, false) {
70 public DynamicMethod (string name, Type returnType, Type[] parameterTypes, Type owner) : this (name, returnType, parameterTypes, owner, false) {
73 public DynamicMethod (string name, Type returnType, Type[] parameterTypes, Module m, bool skipVisibility) : this (name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, m, skipVisibility) {
76 public DynamicMethod (string name, Type returnType, Type[] parameterTypes, Type owner, bool skipVisibility) : this (name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, owner, skipVisibility) {
79 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) {
82 public DynamicMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Module m, bool skipVisibility) {
84 throw new ArgumentNullException ("name");
85 if (name == String.Empty)
86 throw new ArgumentException ("Name can't be empty", "name");
87 if (returnType == null)
88 throw new ArgumentNullException ("returnType");
90 throw new ArgumentNullException ("m");
91 if (returnType.IsByRef)
92 throw new ArgumentException ("Return type can't be a byref type", "returnType");
93 if (parameterTypes != null) {
94 for (int i = 0; i < parameterTypes.Length; ++i)
95 if (parameterTypes [i] == null)
96 throw new ArgumentException ("Parameter " + i + " is null", "parameterTypes");
100 this.attributes = attributes | MethodAttributes.Static;
101 this.callingConvention = callingConvention;
102 this.returnType = returnType;
103 this.parameters = parameterTypes;
105 this.skipVisibility = skipVisibility;
108 [MethodImplAttribute(MethodImplOptions.InternalCall)]
109 private extern void create_dynamic_method (DynamicMethod m);
111 private void CreateDynMethod () {
112 if (mhandle.Value == IntPtr.Zero) {
114 ilgen.label_fixup ();
115 create_dynamic_method (this);
120 public Delegate CreateDelegate (Type delegateType)
122 if (delegateType == null)
123 throw new ArgumentNullException ("delegateType");
129 deleg = Delegate.CreateDelegate (delegateType, this);
134 public Delegate CreateDelegate (Type delegateType, object target)
136 if (delegateType == null)
137 throw new ArgumentNullException ("delegateType");
141 /* Can't cache the delegate since it is different for each target */
142 return Delegate.CreateDelegate (delegateType, target, this);
146 public ParameterBuilder DefineParameter (int position, ParameterAttributes attributes, string strParamName)
149 // Extension: Mono allows position == 0 for the return attribute
151 if ((position < 0) || (position > parameters.Length))
152 throw new ArgumentOutOfRangeException ("position");
156 throw new NotImplementedException ();
159 public override MethodInfo GetBaseDefinition () {
164 public override object[] GetCustomAttributes (bool inherit) {
165 throw new NotImplementedException ();
169 public override object[] GetCustomAttributes (Type attributeType,
171 throw new NotImplementedException ();
174 public ILGenerator GetILGenerator () {
175 return GetILGenerator (64);
178 public ILGenerator GetILGenerator (int size) {
179 if (((GetMethodImplementationFlags () & MethodImplAttributes.CodeTypeMask) !=
180 MethodImplAttributes.IL) ||
181 ((GetMethodImplementationFlags () & MethodImplAttributes.ManagedMask) !=
182 MethodImplAttributes.Managed))
183 throw new InvalidOperationException ("Method body should not exist.");
186 ilgen = new ILGenerator (Module, new DynamicMethodTokenGenerator (this), size);
190 public override MethodImplAttributes GetMethodImplementationFlags () {
191 return MethodImplAttributes.IL | MethodImplAttributes.Managed;
194 public override ParameterInfo[] GetParameters () {
195 if (parameters == null)
196 return new ParameterInfo [0];
198 ParameterInfo[] retval = new ParameterInfo [parameters.Length];
199 for (int i = 0; i < parameters.Length; i++) {
200 retval [i] = new ParameterInfo (pinfo == null ? null : pinfo [i + 1], parameters [i], this, i + 1);
205 public override object Invoke (object obj, object[] parameters) {
208 method = new MonoMethod (mhandle);
209 return method.Invoke (obj, parameters);
212 public override object Invoke (object obj, BindingFlags invokeAttr,
213 Binder binder, object[] parameters,
214 CultureInfo culture) {
217 method = new MonoMethod (mhandle);
218 return method.Invoke (obj, parameters);
222 public override bool IsDefined (Type attributeType, bool inherit) {
223 throw new NotImplementedException ();
226 public override string ToString () {
228 ParameterInfo[] p = GetParameters ();
229 for (int i = 0; i < p.Length; ++i) {
231 parms = parms + ", ";
232 parms = parms + p [i].ParameterType.Name;
234 return ReturnType.Name+" "+Name+"("+parms+")";
237 public override MethodAttributes Attributes {
243 public override CallingConventions CallingConvention {
245 return callingConvention;
249 public override Type DeclaringType {
255 public bool InitLocals {
264 public override RuntimeMethodHandle MethodHandle {
270 public override Module Module {
276 public override string Name {
282 public override Type ReflectedType {
289 public ParameterInfo ReturnParameter {
291 throw new NotImplementedException ();
295 public override Type ReturnType {
302 public override ICustomAttributeProvider ReturnTypeCustomAttributes {
304 throw new NotImplementedException ();
308 public override int MetadataToken {
314 private void RejectIfCreated () {
315 if (mhandle.Value != IntPtr.Zero)
316 throw new InvalidOperationException ("Type definition of the method is complete.");
319 private Exception NotSupported () {
320 return new NotSupportedException ("The invoked member is not supported on a dynamic method.");
323 internal int AddRef (object reference) {
325 refs = new object [4];
326 if (nrefs >= refs.Length - 1) {
327 object [] new_refs = new object [refs.Length * 2];
328 System.Array.Copy (refs, new_refs, refs.Length);
331 refs [nrefs] = reference;
332 /* Reserved by the runtime */
333 refs [nrefs + 1] = null;
339 internal class DynamicMethodTokenGenerator : TokenGenerator {
341 private DynamicMethod m;
343 public DynamicMethodTokenGenerator (DynamicMethod m) {
347 public int GetToken (string str) {
348 return m.AddRef (str);
351 public int GetToken (MethodInfo method, Type[] opt_param_types) {
352 throw new InvalidOperationException ();
355 public int GetToken (MemberInfo member) {
356 return m.AddRef (member);
359 public int GetToken (SignatureHelper helper) {
360 return m.AddRef (helper);