X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FSystem.Reflection.Emit%2FMethodBuilder.cs;h=63b9477decb8630a3472a6c90135cdd30b5d86be;hb=a9f00ccce0974f283b6145600fcf1ae753ba0b85;hp=9d884f2e2ddde1575a4a8ac4e5e7583b7d32fa2e;hpb=84d5f63138dfe0196657ba50126748c950f217f2;p=mono.git diff --git a/mcs/class/corlib/System.Reflection.Emit/MethodBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/MethodBuilder.cs index 9d884f2e2dd..63b9477decb 100755 --- a/mcs/class/corlib/System.Reflection.Emit/MethodBuilder.cs +++ b/mcs/class/corlib/System.Reflection.Emit/MethodBuilder.cs @@ -12,10 +12,13 @@ using System; using System.Reflection; using System.Reflection.Emit; using System.Globalization; +using System.Security; +using System.Security.Permissions; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace System.Reflection.Emit { + public sealed class MethodBuilder : MethodInfo { private RuntimeMethodHandle mhandle; private Type rtype; @@ -36,25 +39,39 @@ namespace System.Reflection.Emit { private CallingConvention native_cc; private CallingConventions call_conv; private bool init_locals = true; + private MonoGenericParam[] generic_params; + private Type[] returnModReq; + private Type[] returnModOpt; + private Type[][] paramModReq; + private Type[][] paramModOpt; + private RefEmitPermissionSet[] permissions; - internal MethodBuilder (TypeBuilder tb, string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) { + internal MethodBuilder (TypeBuilder tb, string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnModReq, Type[] returnModOpt, Type[] parameterTypes, Type[][] paramModReq, Type[][] paramModOpt) { this.name = name; this.attrs = attributes; this.call_conv = callingConvention; this.rtype = returnType; + this.returnModReq = returnModReq; + this.returnModOpt = returnModOpt; + this.paramModReq = paramModReq; + this.paramModOpt = paramModOpt; + // The MSDN docs does not specify this, but the MS MethodBuilder + // appends a HasThis flag if the method is not static + if ((attributes & MethodAttributes.Static) == 0) + this.call_conv |= CallingConventions.HasThis; if (parameterTypes != null) { this.parameters = new Type [parameterTypes.Length]; System.Array.Copy (parameterTypes, this.parameters, parameterTypes.Length); } type = tb; - table_idx = get_next_table_index (0x06, true); + table_idx = get_next_table_index (this, 0x06, true); //Console.WriteLine ("index for "+name+" set to "+table_idx.ToString()); } internal MethodBuilder (TypeBuilder tb, string name, MethodAttributes attributes, - CallingConventions callingConvention, Type returnType, Type[] parameterTypes, + CallingConventions callingConvention, Type returnType, Type[] returnModReq, Type[] returnModOpt, Type[] parameterTypes, Type[][] paramModReq, Type[][] paramModOpt, String dllName, String entryName, CallingConvention nativeCConv, CharSet nativeCharset) - : this (tb, name, attributes, callingConvention, returnType, parameterTypes) { + : this (tb, name, attributes, callingConvention, returnType, returnModReq, returnModOpt, parameterTypes, paramModReq, paramModOpt) { pi_dll = dllName; pi_entry = entryName; native_cc = nativeCConv; @@ -69,59 +86,120 @@ namespace System.Reflection.Emit { internal TypeBuilder TypeBuilder { get {return type;} } - + + public override RuntimeMethodHandle MethodHandle { + get { + throw NotSupported (); + } + } + public override Type ReturnType {get {return rtype;}} public override Type ReflectedType {get {return type;}} public override Type DeclaringType {get {return type;}} public override string Name {get {return name;}} - public override RuntimeMethodHandle MethodHandle {get {return mhandle;}} public override MethodAttributes Attributes {get {return attrs;}} public override ICustomAttributeProvider ReturnTypeCustomAttributes { get {return null;} } + + public override CallingConventions CallingConvention { + get { return call_conv; } + } + + [MonoTODO] + public string Signature { + get { + throw new NotImplementedException (); + } + } + public MethodToken GetToken() { return new MethodToken(0x06000000 | table_idx); } public override MethodInfo GetBaseDefinition() { - return null; + return this; } public override MethodImplAttributes GetMethodImplementationFlags() { return iattrs; } public override ParameterInfo[] GetParameters() { - return null; + if (parameters == null) + return null; + + ParameterInfo[] retval = new ParameterInfo [parameters.Length]; + for (int i = 0; i < parameters.Length; i++) { + retval [i] = new ParameterInfo (pinfo == null ? null : pinfo [i + 1], parameters [i], this, i + 1); + } + return retval; } + internal override int GetParameterCount () + { + if (parameters == null) + return 0; + + return parameters.Length; + } + + public Module GetModule () { + return type.Module; + } + public void CreateMethodBody( byte[] il, int count) { - code = new byte [count]; - System.Array.Copy(il, code, count); + if ((il != null) && ((count < 0) || (count > il.Length))) + throw new ArgumentException ("Index was out of range. Must be non-negative and less than the size of the collection."); + + if ((code != null) || type.is_created) + throw new InvalidOperationException ("Type definition of the method is complete."); + + if (il == null) + code = null; + else { + code = new byte [count]; + System.Array.Copy(il, code, count); + } } + public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) { - return null; + throw NotSupported (); } public override bool IsDefined (Type attribute_type, bool inherit) { - return false; + throw NotSupported (); } public override object[] GetCustomAttributes( bool inherit) { - return null; + throw NotSupported (); } public override object[] GetCustomAttributes( Type attributeType, bool inherit) { - return null; + throw NotSupported (); } public ILGenerator GetILGenerator () { - return GetILGenerator (256); + return GetILGenerator (64); } - internal ILGenerator GetILGenerator (int size) { - ilgen = new ILGenerator (this, size); + + public ILGenerator GetILGenerator (int size) { + if (((iattrs & MethodImplAttributes.CodeTypeMask) != + MethodImplAttributes.IL) || + ((iattrs & MethodImplAttributes.ManagedMask) != + MethodImplAttributes.Managed)) + throw new InvalidOperationException ("Method body should not exist."); + if (ilgen != null) + return ilgen; + ilgen = new ILGenerator (type.Module, ((ModuleBuilder)type.Module).GetTokenGenerator (), size); return ilgen; } - [MonoTODO] public ParameterBuilder DefineParameter (int position, ParameterAttributes attributes, string strParamName) { + // + // Extension: Mono allows position == 0 for the return attribute + // + if ((position < 0) || (position > parameters.Length)) + throw new ArgumentOutOfRangeException ("position"); + + RejectIfCreated (); + ParameterBuilder pb = new ParameterBuilder (this, position, attributes, strParamName); - // check position if (pinfo == null) pinfo = new ParameterBuilder [parameters.Length + 1]; pinfo [position] = pb; @@ -134,6 +212,17 @@ namespace System.Reflection.Emit { } public void SetCustomAttribute( CustomAttributeBuilder customBuilder) { + if (customBuilder == null) + throw new ArgumentNullException ("customBuilder"); + string attrname = customBuilder.Ctor.ReflectedType.FullName; + if (attrname == "System.Runtime.CompilerServices.MethodImplAttribute") { + byte[] data = customBuilder.Data; + int impla; // the (stupid) ctor takes a short or an int ... + impla = (int)data [2]; + impla |= ((int)data [3]) << 8; + SetImplementationFlags ((MethodImplAttributes)impla); + return; + } if (cattrs != null) { CustomAttributeBuilder[] new_array = new CustomAttributeBuilder [cattrs.Length + 1]; cattrs.CopyTo (new_array, 0); @@ -145,18 +234,127 @@ namespace System.Reflection.Emit { } } public void SetCustomAttribute( ConstructorInfo con, byte[] binaryAttribute) { + if (con == null) + throw new ArgumentNullException ("con"); + if (binaryAttribute == null) + throw new ArgumentNullException ("binaryAttribute"); SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute)); } public void SetImplementationFlags( MethodImplAttributes attributes) { + RejectIfCreated (); iattrs = attributes; } - internal override int get_next_table_index (int table, bool inc) { - return type.get_next_table_index (table, inc); + + public void AddDeclarativeSecurity( SecurityAction action, PermissionSet pset) { + if (pset == null) + throw new ArgumentNullException ("pset"); + if ((action == SecurityAction.RequestMinimum) || + (action == SecurityAction.RequestOptional) || + (action == SecurityAction.RequestRefuse)) + throw new ArgumentException ("Request* values are not permitted", "action"); + + RejectIfCreated (); + + if (permissions != null) { + /* Check duplicate actions */ + foreach (RefEmitPermissionSet set in permissions) + if (set.action == action) + throw new InvalidOperationException ("Multiple permission sets specified with the same SecurityAction."); + + RefEmitPermissionSet[] new_array = new RefEmitPermissionSet [permissions.Length + 1]; + permissions.CopyTo (new_array, 0); + permissions = new_array; + } + else + permissions = new RefEmitPermissionSet [1]; + + permissions [permissions.Length - 1] = new RefEmitPermissionSet (action, pset.ToXml ().ToString ()); + attrs |= MethodAttributes.HasSecurity; + } + + [MonoTODO] + public void SetMarshal (UnmanagedMarshal unmanagedMarshal) + { + RejectIfCreated (); + throw new NotImplementedException (); + } + + [MonoTODO] + public void SetSymCustomAttribute (string name, byte[] data) + { + RejectIfCreated (); + throw new NotImplementedException (); + } + + internal override int get_next_table_index (object obj, int table, bool inc) { + return type.get_next_table_index (obj, table, inc); } internal void set_override (MethodInfo mdecl) { override_method = mdecl; } + + private void RejectIfCreated () { + if (type.is_created) + throw new InvalidOperationException ("Type definition of the method is complete."); + } + + private Exception NotSupported () { + return new NotSupportedException ("The invoked member is not supported in a dynamic module."); + } + +#if NET_1_2 + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private extern MonoGenericParam define_generic_parameter (string name, int index); + + public Type DefineGenericParameter (string name) + { + int index; + if (generic_params != null) { + MonoGenericParam[] new_generic_params = new MonoGenericParam [generic_params.Length+1]; + System.Array.Copy (generic_params, new_generic_params, generic_params.Length); + index = generic_params.Length; + generic_params = new_generic_params; + } else { + generic_params = new MonoGenericParam [1]; + index = 0; + } + + generic_params [index] = define_generic_parameter (name, index); + return generic_params [index]; + } + + public void SetGenericParameterConstraints (int index, Type[] constraints) + { + generic_params [index].SetConstraints (constraints); + } + + public override Type[] GetGenericArguments () + { + if (generic_params == null) + return new Type [0]; + + Type[] result = new Type [generic_params.Length]; + for (int i = 0; i < generic_params.Length; i++) + result [i] = generic_params [i]; + + return result; + } + + public void SetGenericMethodSignature (MethodAttributes attributes, CallingConventions callingConvention, Type return_type, Type[] parameter_types) + { + RejectIfCreated (); + + this.attrs = attributes; + this.call_conv = callingConvention; + if ((attributes & MethodAttributes.Static) == 0) + this.call_conv |= CallingConventions.HasThis; + + this.rtype = return_type; + this.parameters = new Type [parameter_types.Length]; + System.Array.Copy (parameter_types, this.parameters, parameter_types.Length); + } +#endif } }