static TypeBuilder DefineDelegate () { TypeBuilder typeBuilder = module.DefineType( "MyDelegate", TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Sealed, typeof (object) ); args = typeBuilder.DefineGenericParameters ("TIn", "TOut"); delegate_ctor = typeBuilder.DefineConstructor( MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName, CallingConventions.Standard, new Type[] { typeof(Object), typeof (IntPtr) } ); delegate_ctor.SetImplementationFlags( MethodImplAttributes.Runtime | MethodImplAttributes.Managed ); invoke_mb = typeBuilder.DefineMethod( "Invoke", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, args [1], new Type[] { args [0] } ); invoke_mb.SetImplementationFlags( MethodImplAttributes.Runtime | MethodImplAttributes.Managed ); MethodBuilder mb = typeBuilder.DefineMethod( "BeginInvoke", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, typeof (IAsyncResult), new Type[] { args [0], typeof (AsyncCallback), typeof (object) } ); mb.SetImplementationFlags( MethodImplAttributes.Runtime | MethodImplAttributes.Managed ); mb = typeBuilder.DefineMethod( "EndInvoke", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, args [1], new Type[] { typeof (IAsyncResult) } ); mb.SetImplementationFlags( MethodImplAttributes.Runtime | MethodImplAttributes.Managed ); return typeBuilder; }
public void SetImplementationFlags(MethodImplAttributes attributes) { m_methodBuilder.SetImplementationFlags(attributes); }
public override bool Define () { if (IsGeneric) { foreach (TypeParameter type_param in TypeParameters) { if (!type_param.Resolve (this)) return false; } foreach (TypeParameter type_param in TypeParameters) { if (!type_param.DefineType (this)) return false; } } member_cache = new MemberCache (TypeManager.multicast_delegate_type, this); // FIXME: POSSIBLY make this static, as it is always constant // Type [] const_arg_types = new Type [2]; const_arg_types [0] = TypeManager.object_type; const_arg_types [1] = TypeManager.intptr_type; const MethodAttributes ctor_mattr = MethodAttributes.RTSpecialName | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Public; ConstructorBuilder = TypeBuilder.DefineConstructor (ctor_mattr, CallingConventions.Standard, const_arg_types); ConstructorBuilder.DefineParameter (1, ParameterAttributes.None, "object"); ConstructorBuilder.DefineParameter (2, ParameterAttributes.None, "method"); // // HACK because System.Reflection.Emit is lame // IParameterData [] fixed_pars = new IParameterData [] { new ParameterData ("object", Parameter.Modifier.NONE), new ParameterData ("method", Parameter.Modifier.NONE) }; AParametersCollection const_parameters = new ParametersImported ( fixed_pars, new Type[] { TypeManager.object_type, TypeManager.intptr_type }); TypeManager.RegisterMethod (ConstructorBuilder, const_parameters); member_cache.AddMember (ConstructorBuilder, this); ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.Runtime); // // Here the various methods like Invoke, BeginInvoke etc are defined // // First, call the `out of band' special method for // defining recursively any types we need: if (!Parameters.Resolve (this)) return false; // // Invoke method // // Check accessibility foreach (Type partype in Parameters.Types){ if (!IsAccessibleAs (partype)) { Report.SymbolRelatedToPreviousError (partype); Report.Error (59, Location, "Inconsistent accessibility: parameter type `{0}' is less accessible than delegate `{1}'", TypeManager.CSharpName (partype), GetSignatureForError ()); return false; } } ReturnType = ReturnType.ResolveAsTypeTerminal (this, false); if (ReturnType == null) return false; ret_type = ReturnType.Type; if (!IsAccessibleAs (ret_type)) { Report.SymbolRelatedToPreviousError (ret_type); Report.Error (58, Location, "Inconsistent accessibility: return type `" + TypeManager.CSharpName (ret_type) + "' is less " + "accessible than delegate `" + GetSignatureForError () + "'"); return false; } CheckProtectedModifier (); if (RootContext.StdLib && TypeManager.IsSpecialType (ret_type)) { Method.Error1599 (Location, ret_type, Report); return false; } TypeManager.CheckTypeVariance (ret_type, Variance.Covariant, this); // // We don't have to check any others because they are all // guaranteed to be accessible - they are standard types. // CallingConventions cc = Parameters.CallingConvention; InvokeBuilder = TypeBuilder.DefineMethod ("Invoke", mattr, cc, ret_type, Parameters.GetEmitTypes ()); InvokeBuilder.SetImplementationFlags (MethodImplAttributes.Runtime); TypeManager.RegisterMethod (InvokeBuilder, Parameters); member_cache.AddMember (InvokeBuilder, this); // // Don't emit async method for compiler generated delegates (e.g. dynamic site containers) // if (TypeManager.iasyncresult_type != null && TypeManager.asynccallback_type != null && !IsCompilerGenerated) { DefineAsyncMethods (cc); } return true; }
void DefineAsyncMethods (CallingConventions cc) { // // BeginInvoke // ParametersCompiled async_parameters = ParametersCompiled.MergeGenerated (Parameters, false, new Parameter [] { new Parameter (null, "callback", Parameter.Modifier.NONE, null, Location), new Parameter (null, "object", Parameter.Modifier.NONE, null, Location) }, new Type [] { TypeManager.asynccallback_type, TypeManager.object_type } ); BeginInvokeBuilder = TypeBuilder.DefineMethod ("BeginInvoke", mattr, cc, TypeManager.iasyncresult_type, async_parameters.GetEmitTypes ()); BeginInvokeBuilder.SetImplementationFlags (MethodImplAttributes.Runtime); TypeManager.RegisterMethod (BeginInvokeBuilder, async_parameters); member_cache.AddMember (BeginInvokeBuilder, this); // // EndInvoke is a bit more interesting, all the parameters labeled as // out or ref have to be duplicated here. // // // Define parameters, and count out/ref parameters // ParametersCompiled end_parameters; int out_params = 0; foreach (Parameter p in Parameters.FixedParameters) { if ((p.ModFlags & Parameter.Modifier.ISBYREF) != 0) ++out_params; } if (out_params > 0) { Type [] end_param_types = new Type [out_params]; Parameter[] end_params = new Parameter [out_params]; int param = 0; for (int i = 0; i < Parameters.FixedParameters.Length; ++i) { Parameter p = Parameters [i]; if ((p.ModFlags & Parameter.Modifier.ISBYREF) == 0) continue; end_param_types [param] = Parameters.Types [i]; end_params [param] = p; ++param; } end_parameters = ParametersCompiled.CreateFullyResolved (end_params, end_param_types); } else { end_parameters = ParametersCompiled.EmptyReadOnlyParameters; } end_parameters = ParametersCompiled.MergeGenerated (end_parameters, false, new Parameter (null, "result", Parameter.Modifier.NONE, null, Location), TypeManager.iasyncresult_type); // // Create method, define parameters, register parameters with type system // EndInvokeBuilder = TypeBuilder.DefineMethod ("EndInvoke", mattr, cc, ret_type, end_parameters.GetEmitTypes ()); EndInvokeBuilder.SetImplementationFlags (MethodImplAttributes.Runtime); end_parameters.ApplyAttributes (EndInvokeBuilder); TypeManager.RegisterMethod (EndInvokeBuilder, end_parameters); member_cache.AddMember (EndInvokeBuilder, this); }