X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FSystem.Reflection.Emit%2FDynamicMethod.cs;h=931573d5449459c3860e103b5dab2811d820ee2c;hb=e2b2d181084848f3c5dde2788370db1b79893c69;hp=30154cd77f73b692ddfb1db46d7122ee7424d047;hpb=f8ffff9e76a888548b9e0094490e08e9793cd182;p=mono.git diff --git a/mcs/class/corlib/System.Reflection.Emit/DynamicMethod.cs b/mcs/class/corlib/System.Reflection.Emit/DynamicMethod.cs index 30154cd77f7..931573d5449 100644 --- a/mcs/class/corlib/System.Reflection.Emit/DynamicMethod.cs +++ b/mcs/class/corlib/System.Reflection.Emit/DynamicMethod.cs @@ -1,5 +1,5 @@ // -// System.Reflection.Emit/DynamicMethod.cs +// System.Reflection.Emit.DynamicMethod.cs // // Author: // Paolo Molaro (lupus@ximian.com) @@ -31,7 +31,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#if NET_2_0 || BOOTSTRAP_NET_2_0 +#if !FULL_AOT_RUNTIME using System; using System.Reflection; @@ -42,10 +42,11 @@ using System.Runtime.InteropServices; namespace System.Reflection.Emit { -#if NET_2_0 [ComVisible (true)] -#endif + [StructLayout (LayoutKind.Sequential)] public sealed class DynamicMethod : MethodInfo { + +#pragma warning disable 169, 414, 649 #region Sync with reflection.h private RuntimeMethodHandle mhandle; private string name; @@ -60,11 +61,15 @@ namespace System.Reflection.Emit { private int nrefs; private object[] refs; private IntPtr referenced_by; + private Type owner; #endregion +#pragma warning restore 169, 414, 649 + private Delegate deleg; private MonoMethod method; private ParameterBuilder[] pinfo; internal bool creating; + private DynamicILInfo il_info; public DynamicMethod (string name, Type returnType, Type[] parameterTypes, Module m) : this (name, returnType, parameterTypes, m, false) { } @@ -78,15 +83,28 @@ namespace System.Reflection.Emit { public DynamicMethod (string name, Type returnType, Type[] parameterTypes, Type owner, bool skipVisibility) : this (name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, owner, skipVisibility) { } - 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) { + public DynamicMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type owner, bool skipVisibility) : this (name, attributes, callingConvention, returnType, parameterTypes, owner, owner.Module, skipVisibility, false) { + } + + public DynamicMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Module m, bool skipVisibility) : this (name, attributes, callingConvention, returnType, parameterTypes, null, m, skipVisibility, false) { + } + + public DynamicMethod (string name, Type returnType, Type[] parameterTypes) : this (name, returnType, parameterTypes, false) { + } + + [MonoTODO ("Visibility is not restricted")] + public DynamicMethod (string name, Type returnType, Type[] parameterTypes, bool restrictedSkipVisibility) + : this (name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, null, null, restrictedSkipVisibility, true) + { } - public DynamicMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Module m, bool skipVisibility) { + DynamicMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type [] parameterTypes, Type owner, Module m, bool skipVisibility, bool anonHosted) + { if (name == null) throw new ArgumentNullException ("name"); if (returnType == null) returnType = typeof (void); - if (m == null) + if ((m == null) && !anonHosted) throw new ArgumentNullException ("m"); if (returnType.IsByRef) throw new ArgumentException ("Return type can't be a byref type", "returnType"); @@ -95,12 +113,19 @@ namespace System.Reflection.Emit { if (parameterTypes [i] == null) throw new ArgumentException ("Parameter " + i + " is null", "parameterTypes"); } + if (owner != null && (owner.IsArray || owner.IsInterface)) { + throw new ArgumentException ("Owner can't be an array or an interface."); + } + + if (m == null) + m = AnonHostModuleHolder.AnonHostModule; this.name = name; this.attributes = attributes | MethodAttributes.Static; this.callingConvention = callingConvention; this.returnType = returnType; this.parameters = parameterTypes; + this.owner = owner; this.module = m; this.skipVisibility = skipVisibility; } @@ -108,12 +133,9 @@ namespace System.Reflection.Emit { [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void create_dynamic_method (DynamicMethod m); - [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern void destroy_dynamic_method (DynamicMethod m); - private void CreateDynMethod () { if (mhandle.Value == IntPtr.Zero) { - if (ilgen == null || (ILGenerator.Mono_GetCurrentOffset (ilgen) == 0)) + if (ilgen == null || ilgen.ILOffset == 0) throw new InvalidOperationException ("Method '" + name + "' does not have a method body."); ilgen.label_fixup (); @@ -139,11 +161,6 @@ namespace System.Reflection.Emit { } } - ~DynamicMethod () - { - destroy_dynamic_method (this); - } - [ComVisible (true)] public Delegate CreateDelegate (Type delegateType) { @@ -170,7 +187,7 @@ namespace System.Reflection.Emit { return Delegate.CreateDelegate (delegateType, target, this); } - public ParameterBuilder DefineParameter (int position, ParameterAttributes attributes, string strParamName) + public ParameterBuilder DefineParameter (int position, ParameterAttributes attributes, string parameterName) { // // Extension: Mono allows position == 0 for the return attribute @@ -180,7 +197,7 @@ namespace System.Reflection.Emit { RejectIfCreated (); - ParameterBuilder pb = new ParameterBuilder (this, position, attributes, strParamName); + ParameterBuilder pb = new ParameterBuilder (this, position, attributes, parameterName); if (pinfo == null) pinfo = new ParameterBuilder [parameters.Length + 1]; pinfo [position] = pb; @@ -202,11 +219,17 @@ namespace System.Reflection.Emit { throw new NotImplementedException (); } + public DynamicILInfo GetDynamicILInfo () { + if (il_info == null) + il_info = new DynamicILInfo (this); + return il_info; + } + public ILGenerator GetILGenerator () { return GetILGenerator (64); } - public ILGenerator GetILGenerator (int size) { + public ILGenerator GetILGenerator (int streamSize) { if (((GetMethodImplementationFlags () & MethodImplAttributes.CodeTypeMask) != MethodImplAttributes.IL) || ((GetMethodImplementationFlags () & MethodImplAttributes.ManagedMask) != @@ -214,7 +237,7 @@ namespace System.Reflection.Emit { throw new InvalidOperationException ("Method body should not exist."); if (ilgen != null) return ilgen; - ilgen = new ILGenerator (Module, new DynamicMethodTokenGenerator (this), size); + ilgen = new ILGenerator (Module, new DynamicMethodTokenGenerator (this), streamSize); return ilgen; } @@ -232,6 +255,15 @@ namespace System.Reflection.Emit { } return retval; } + + internal override int GetParameterCount () + { + return parameters == null ? 0 : parameters.Length; + } + + internal override Type GetParameterType (int pos) { + return parameters [pos]; + } /* public override object Invoke (object obj, object[] parameters) { @@ -244,11 +276,18 @@ namespace System.Reflection.Emit { public override object Invoke (object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, - CultureInfo culture) { - CreateDynMethod (); - if (method == null) - method = new MonoMethod (mhandle); - return method.Invoke (obj, parameters); + CultureInfo culture) + { + try { + CreateDynMethod (); + if (method == null) + method = new MonoMethod (mhandle); + + return method.Invoke (obj, parameters); + } + catch (MethodAccessException mae) { + throw new TargetInvocationException ("Method cannot be invoked.", mae); + } } [MonoTODO("Not implemented")] @@ -338,21 +377,19 @@ namespace System.Reflection.Emit { } } +/* public override int MetadataToken { get { return 0; } } +*/ private void RejectIfCreated () { if (mhandle.Value != IntPtr.Zero) throw new InvalidOperationException ("Type definition of the method is complete."); } - private Exception NotSupported () { - return new NotSupportedException ("The invoked member is not supported on a dynamic method."); - } - internal int AddRef (object reference) { if (refs == null) refs = new object [4]; @@ -367,6 +404,25 @@ namespace System.Reflection.Emit { nrefs += 2; return nrefs - 1; } + + // This class takes care of constructing the module in a thread safe manner + class AnonHostModuleHolder { + public static Module anon_host_module; + + static AnonHostModuleHolder () { + AssemblyName aname = new AssemblyName (); + aname.Name = "Anonymously Hosted DynamicMethods Assembly"; + AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly (aname, AssemblyBuilderAccess.Run); + + anon_host_module = ab.GetManifestModule (); + } + + public static Module AnonHostModule { + get { + return anon_host_module; + } + } + } } internal class DynamicMethodTokenGenerator : TokenGenerator { @@ -385,7 +441,7 @@ namespace System.Reflection.Emit { throw new InvalidOperationException (); } - public int GetToken (MemberInfo member) { + public int GetToken (MemberInfo member, bool create_open_instance) { return m.AddRef (member); }