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); }
protected override bool DoDefineMembers() { 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); }
/// <summary> /// Create the MethodBuilder for the method /// </summary> void DefineMethodBuilder (TypeContainer container, string method_name, ParametersCompiled param) { if (builder == null) { builder = container.TypeBuilder.DefineMethod ( method_name, flags, method.CallingConventions, TypeManager.TypeToReflectionType (method.ReturnType), param.GetEmitTypes ()); return; } #if GMCS_SOURCE // // Generic method has been already defined to resolve method parameters // correctly when they use type parameters // builder.SetParameters (param.GetEmitTypes ()); builder.SetReturnType (method.ReturnType); #endif if (builder.Attributes != flags) { try { if (methodbuilder_attrs_field == null) methodbuilder_attrs_field = typeof (MethodBuilder).GetField ("attrs", BindingFlags.NonPublic | BindingFlags.Instance); methodbuilder_attrs_field.SetValue (builder, flags); } catch { RootContext.ToplevelTypes.Compiler.Report.RuntimeMissingSupport (method.Location, "Generic method MethodAttributes"); } } }