protected void CheckReservedNameConflict (string prefix, MethodSpec accessor) { string name; AParametersCollection parameters; if (accessor != null) { name = accessor.Name; parameters = accessor.Parameters; } else { name = prefix + ShortName; if (IsExplicitImpl) name = MemberName.Left + "." + name; if (this is Indexer) { parameters = ((Indexer) this).ParameterInfo; if (prefix[0] == 's') { var data = new IParameterData[parameters.Count + 1]; Array.Copy (parameters.FixedParameters, data, data.Length - 1); data[data.Length - 1] = new ParameterData ("value", Parameter.Modifier.NONE); var types = new TypeSpec[data.Length]; Array.Copy (parameters.Types, types, data.Length - 1); types[data.Length - 1] = member_type; parameters = new ParametersImported (data, types, false); } } else { if (prefix[0] == 's') parameters = ParametersCompiled.CreateFullyResolved (new[] { member_type }); else parameters = ParametersCompiled.EmptyReadOnlyParameters; } } var conflict = MemberCache.FindMember (Parent.Definition, new MemberFilter (name, 0, MemberKind.Method, parameters, null), BindingRestriction.DeclaredOnly | BindingRestriction.NoAccessors); if (conflict != null) { Report.SymbolRelatedToPreviousError (conflict); Report.Error (82, Location, "A member `{0}' is already reserved", conflict.GetSignatureForError ()); } }
public override bool Resolve(BlockContext ec) { TypeExpression storey_type_expr = new TypeExpression(host.Definition, loc); List <Expression> init = null; if (host.hoisted_this != null) { init = new List <Expression> (host.hoisted_params == null ? 1 : host.HoistedParameters.Count + 1); HoistedThis ht = host.hoisted_this; FieldExpr from = new FieldExpr(ht.Field, loc); from.InstanceExpression = CompilerGeneratedThis.Instance; init.Add(new ElementInitializer(ht.Field.Name, from, loc)); } if (host.hoisted_params != null) { if (init == null) { init = new List <Expression> (host.HoistedParameters.Count); } for (int i = 0; i < host.hoisted_params.Count; ++i) { HoistedParameter hp = (HoistedParameter)host.hoisted_params [i]; HoistedParameter hp_cp = (HoistedParameter)host.hoisted_params_copy [i]; FieldExpr from = new FieldExpr(hp_cp.Field, loc); from.InstanceExpression = CompilerGeneratedThis.Instance; init.Add(new ElementInitializer(hp.Field.Name, from, loc)); } } if (init != null) { new_storey = new NewInitialize(storey_type_expr, null, new CollectionOrObjectInitializers(init, loc), loc); } else { new_storey = new New(storey_type_expr, null, loc); } new_storey = new_storey.Resolve(ec); if (new_storey != null) { new_storey = Convert.ImplicitConversionRequired(ec, new_storey, host_method.MemberType, loc); } var t = ec.Module.PredefinedTypes.Interlocked.Resolve(loc); if (t != null) { var p = new ParametersImported( new[] { new ParameterData(null, Parameter.Modifier.REF), new ParameterData(null, Parameter.Modifier.NONE), new ParameterData(null, Parameter.Modifier.NONE) }, new[] { TypeManager.int32_type, TypeManager.int32_type, TypeManager.int32_type }, false); var f = new MemberFilter("CompareExchange", 0, MemberKind.Method, p, TypeManager.int32_type); TypeManager.int_interlocked_compare_exchange = TypeManager.GetPredefinedMethod(t, f, loc); } ec.CurrentBranching.CurrentUsageVector.Goto(); return(true); }
// // Returns null when the property is not valid C# property // public PropertySpec CreateProperty (PropertyInfo pi, TypeSpec declaringType, MethodSpec get, MethodSpec set) { Modifiers mod = 0; AParametersCollection param = null; TypeSpec type = null; if (get != null) { mod = get.Modifiers; param = get.Parameters; type = get.ReturnType; } bool is_valid_property = true; if (set != null) { if (set.ReturnType.Kind != MemberKind.Void) is_valid_property = false; var set_param_count = set.Parameters.Count - 1; if (set_param_count < 0) { set_param_count = 0; is_valid_property = false; } var set_type = set.Parameters.Types[set_param_count]; if (mod == 0) { AParametersCollection set_based_param; if (set_param_count == 0) { set_based_param = ParametersCompiled.EmptyReadOnlyParameters; } else { // // Create indexer parameters based on setter method parameters (the last parameter has to be removed) // var data = new IParameterData[set_param_count]; var types = new TypeSpec[set_param_count]; Array.Copy (set.Parameters.FixedParameters, data, set_param_count); Array.Copy (set.Parameters.Types, types, set_param_count); set_based_param = new ParametersImported (data, types, set.Parameters.HasParams); } mod = set.Modifiers; param = set_based_param; type = set_type; } else { if (set_param_count != get.Parameters.Count) is_valid_property = false; if (get.ReturnType != set_type) is_valid_property = false; // Possible custom accessor modifiers if ((mod & Modifiers.AccessibilityMask) != (set.Modifiers & Modifiers.AccessibilityMask)) { var get_acc = mod & Modifiers.AccessibilityMask; if (get_acc != Modifiers.PUBLIC) { var set_acc = set.Modifiers & Modifiers.AccessibilityMask; // If the accessor modifiers are not same, do extra restriction checks if (get_acc != set_acc) { var get_restr = ModifiersExtensions.IsRestrictedModifier (get_acc, set_acc); var set_restr = ModifiersExtensions.IsRestrictedModifier (set_acc, get_acc); if (get_restr && set_restr) { is_valid_property = false; // Neither is more restrictive } if (get_restr) { mod &= ~Modifiers.AccessibilityMask; mod |= set_acc; } } } } } } PropertySpec spec = null; if (!param.IsEmpty) { var index_name = declaringType.MemberDefinition.GetAttributeDefaultMember (); if (index_name == null) { is_valid_property = false; } else { if (get != null) { if (get.IsStatic) is_valid_property = false; if (get.Name.IndexOf (index_name, StringComparison.Ordinal) != 4) is_valid_property = false; } if (set != null) { if (set.IsStatic) is_valid_property = false; if (set.Name.IndexOf (index_name, StringComparison.Ordinal) != 4) is_valid_property = false; } } if (is_valid_property) spec = new IndexerSpec (declaringType, new ImportedParameterMemberDefinition (pi, type, param, this), type, param, pi, mod); } if (spec == null) spec = new PropertySpec (MemberKind.Property, declaringType, new ImportedMemberDefinition (pi, type, this), type, pi, mod); if (!is_valid_property) { spec.IsNotCSharpCompatible = true; return spec; } if (set != null) spec.Set = set; if (get != null) spec.Get = get; return spec; }
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); }
public override bool Resolve (BlockContext ec) { TypeExpression storey_type_expr = new TypeExpression (host.Definition, loc); List<Expression> init = null; if (host.hoisted_this != null) { init = new List<Expression> (host.hoisted_params == null ? 1 : host.HoistedParameters.Count + 1); HoistedThis ht = host.hoisted_this; FieldExpr from = new FieldExpr (ht.Field, loc); from.InstanceExpression = CompilerGeneratedThis.Instance; init.Add (new ElementInitializer (ht.Field.Name, from, loc)); } if (host.hoisted_params != null) { if (init == null) init = new List<Expression> (host.HoistedParameters.Count); for (int i = 0; i < host.hoisted_params.Count; ++i) { HoistedParameter hp = (HoistedParameter) host.hoisted_params [i]; HoistedParameter hp_cp = (HoistedParameter) host.hoisted_params_copy [i]; FieldExpr from = new FieldExpr (hp_cp.Field, loc); from.InstanceExpression = CompilerGeneratedThis.Instance; init.Add (new ElementInitializer (hp.Field.Name, from, loc)); } } if (init != null) { new_storey = new NewInitialize (storey_type_expr, null, new CollectionOrObjectInitializers (init, loc), loc); } else { new_storey = new New (storey_type_expr, null, loc); } new_storey = new_storey.Resolve (ec); if (new_storey != null) new_storey = Convert.ImplicitConversionRequired (ec, new_storey, host_method.MemberType, loc); if (TypeManager.int_interlocked_compare_exchange == null) { TypeSpec t = TypeManager.CoreLookupType (ec.Compiler, "System.Threading", "Interlocked", MemberKind.Class, true); if (t != null) { var p = new ParametersImported ( new[] { new ParameterData (null, Parameter.Modifier.REF), new ParameterData (null, Parameter.Modifier.NONE), new ParameterData (null, Parameter.Modifier.NONE) }, new[] { TypeManager.int32_type, TypeManager.int32_type, TypeManager.int32_type }, false); var f = new MemberFilter ("CompareExchange", 0, MemberKind.Method, p, TypeManager.int32_type); TypeManager.int_interlocked_compare_exchange = TypeManager.GetPredefinedMethod (t, f, loc); } } ec.CurrentBranching.CurrentUsageVector.Goto (); return true; }
void FabricateBodyStatement() { var cas = TypeManager.gen_interlocked_compare_exchange; if (cas == null) { var t = Module.PredefinedTypes.Interlocked.Resolve (Location); if (t == null) return; var p = new ParametersImported ( new[] { new ParameterData (null, Parameter.Modifier.REF), new ParameterData (null, Parameter.Modifier.NONE), new ParameterData (null, Parameter.Modifier.NONE) }, new[] { new TypeParameterSpec (0, null, SpecialConstraint.None, Variance.None, null), new TypeParameterSpec (0, null, SpecialConstraint.None, Variance.None, null), new TypeParameterSpec (0, null, SpecialConstraint.None, Variance.None, null), }, false); var filter = new MemberFilter ("CompareExchange", 1, MemberKind.Method, p, null); cas = TypeManager.gen_interlocked_compare_exchange = TypeManager.GetPredefinedMethod (t, filter, Location); } // // Delegate obj1 = backing_field // do { // Delegate obj2 = obj1; // obj1 = Interlocked.CompareExchange (ref backing_field, Delegate.Combine|Remove(obj2, value), obj1); // } while (obj1 != obj2) // var field_info = ((EventField) method).backing_field; FieldExpr f_expr = new FieldExpr (field_info, Location); if (!IsStatic) f_expr.InstanceExpression = new CompilerGeneratedThis (Parent.CurrentType, Location); var obj1 = LocalVariable.CreateCompilerGenerated (field_info.MemberType, block, Location); var obj2 = LocalVariable.CreateCompilerGenerated (field_info.MemberType, block, Location); block.AddStatement (new StatementExpression (new SimpleAssign (new LocalVariableReference (obj1, Location), f_expr))); var cond = new BooleanExpression (new Binary (Binary.Operator.Inequality, new LocalVariableReference (obj1, Location), new LocalVariableReference (obj2, Location), Location)); var body = new ExplicitBlock (block, Location, Location); block.AddStatement (new Do (body, cond, Location)); body.AddStatement (new StatementExpression ( new SimpleAssign (new LocalVariableReference (obj2, Location), new LocalVariableReference (obj1, Location)))); var args_oper = new Arguments (2); args_oper.Add (new Argument (new LocalVariableReference (obj2, Location))); args_oper.Add (new Argument (block.GetParameterReference (0, Location))); var args = new Arguments (3); args.Add (new Argument (f_expr, Argument.AType.Ref)); args.Add (new Argument (new Cast ( new TypeExpression (field_info.MemberType, Location), new Invocation (MethodGroupExpr.CreatePredefined (Operation, Operation.DeclaringType, Location), args_oper), Location))); args.Add (new Argument (new LocalVariableReference (obj1, Location))); body.AddStatement (new StatementExpression (new SimpleAssign ( new LocalVariableReference (obj1, Location), new Invocation (MethodGroupExpr.CreatePredefined (cas, cas.DeclaringType, Location), args)))); }
void EmitOnCompleted(EmitContext ec, Expression awaiter, bool unsafeVersion) { var pm = Module.PredefinedMembers; PredefinedMember <MethodSpec> predefined; bool has_task_return_type = false; if (return_type.Kind == MemberKind.Void) { predefined = unsafeVersion ? pm.AsyncVoidMethodBuilderOnCompletedUnsafe : pm.AsyncVoidMethodBuilderOnCompleted; } else if (return_type == Module.PredefinedTypes.Task.TypeSpec) { predefined = unsafeVersion ? pm.AsyncTaskMethodBuilderOnCompletedUnsafe : pm.AsyncTaskMethodBuilderOnCompleted; } else if (return_type.IsGenericTask) { predefined = unsafeVersion ? pm.AsyncTaskMethodBuilderGenericOnCompletedUnsafe : pm.AsyncTaskMethodBuilderGenericOnCompleted; has_task_return_type = true; } else { var parameters = new ParametersImported( new [] { new ParameterData(null, Parameter.Modifier.REF), new ParameterData(null, Parameter.Modifier.REF) }, new [] { new TypeParameterSpec(0, null, SpecialConstraint.None, Variance.None, null), new TypeParameterSpec(1, null, SpecialConstraint.None, Variance.None, null) }, false); var on_completed_sign = unsafeVersion ? MemberFilter.Method("AwaitUnsafeOnCompleted", 2, parameters, Compiler.BuiltinTypes.Void) : MemberFilter.Method("AwaitOnCompleted", 2, parameters, Compiler.BuiltinTypes.Void); predefined = new PredefinedMember <MethodSpec> (Module, return_type.MemberDefinition.GetAsyncMethodBuilder(), on_completed_sign); has_task_return_type = return_type.IsGeneric; } var on_completed = predefined.Resolve(Location); if (on_completed == null) { return; } if (has_task_return_type) { on_completed = MemberCache.GetMember <MethodSpec> (set_result.DeclaringType, on_completed); } on_completed = on_completed.MakeGenericMethod(this, awaiter.Type, ec.CurrentType); var mg = MethodGroupExpr.CreatePredefined(on_completed, on_completed.DeclaringType, Location); mg.InstanceExpression = new FieldExpr(builder, Location) { InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, Location) }; var args = new Arguments(2); args.Add(new Argument(awaiter, Argument.AType.Ref)); args.Add(new Argument(new CompilerGeneratedThis(CurrentType, Location), Argument.AType.Ref)); using (ec.With(BuilderContext.Options.OmitDebugInfo, true)) { mg.EmitCall(ec, args, true); } }
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; }