X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fdelegate.cs;h=a73c9f68c75cb81a94973da5046804f9d6c7163e;hb=04403c39d29635436db8fb677ea6a6423cf6c72b;hp=ee60ed07d47bfa89b910a462228882fc1b018a8c;hpb=ee6616c94eaf62d532bcff63cf08eeecd36dfc48;p=mono.git diff --git a/mcs/mcs/delegate.cs b/mcs/mcs/delegate.cs index ee60ed07d47..a73c9f68c75 100644 --- a/mcs/mcs/delegate.cs +++ b/mcs/mcs/delegate.cs @@ -10,19 +10,25 @@ // // Copyright 2001 Ximian, Inc (http://www.ximian.com) // Copyright 2003-2009 Novell, Inc (http://www.novell.com) +// Copyright 2011 Xamarin Inc // using System; + +#if STATIC +using IKVM.Reflection; +using IKVM.Reflection.Emit; +#else using System.Reflection; using System.Reflection.Emit; -using System.Collections.Generic; +#endif namespace Mono.CSharp { // // Delegate container implementation // - public class Delegate : TypeContainer, IParametersMember + public class Delegate : TypeDefinition, IParametersMember { FullNamedExpression ReturnType; readonly ParametersCompiled parameters; @@ -49,10 +55,9 @@ namespace Mono.CSharp { Modifiers.UNSAFE | Modifiers.PRIVATE; - public Delegate (NamespaceEntry ns, DeclSpace parent, FullNamedExpression type, - Modifiers mod_flags, MemberName name, ParametersCompiled param_list, + public Delegate (TypeContainer parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, ParametersCompiled param_list, Attributes attrs) - : base (ns, parent, name, attrs, MemberKind.Delegate) + : base (parent, name, attrs, MemberKind.Delegate) { this.ReturnType = type; @@ -75,8 +80,20 @@ namespace Mono.CSharp { return parameters; } } + + public FullNamedExpression TypExpression { + get { + return ReturnType; + } + } + #endregion + public override void Accept (StructuralVisitor visitor) + { + visitor.Visit (this); + } + public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) { if (a.Target == AttributeTargets.ReturnValue) { @@ -98,19 +115,21 @@ namespace Mono.CSharp { protected override bool DoDefineMembers () { + var builtin_types = Compiler.BuiltinTypes; + var ctor_parameters = ParametersCompiled.CreateFullyResolved ( new [] { - new Parameter (new TypeExpression (TypeManager.object_type, Location), "object", Parameter.Modifier.NONE, null, Location), - new Parameter (new TypeExpression (TypeManager.intptr_type, Location), "method", Parameter.Modifier.NONE, null, Location) + new Parameter (new TypeExpression (builtin_types.Object, Location), "object", Parameter.Modifier.NONE, null, Location), + new Parameter (new TypeExpression (builtin_types.IntPtr, Location), "method", Parameter.Modifier.NONE, null, Location) }, new [] { - TypeManager.object_type, - TypeManager.intptr_type + builtin_types.Object, + builtin_types.IntPtr } ); - Constructor = new Constructor (this, System.Reflection.ConstructorInfo.ConstructorName, - Modifiers.PUBLIC, null, ctor_parameters, null, Location); + Constructor = new Constructor (this, Constructor.ConstructorName, + Modifiers.PUBLIC, null, ctor_parameters, Location); Constructor.Define (); // @@ -138,12 +157,10 @@ namespace Mono.CSharp { } } - ReturnType = ReturnType.ResolveAsTypeTerminal (this, false); - if (ReturnType == null) + var ret_type = ReturnType.ResolveAsType (this); + if (ret_type == null) return false; - var ret_type = ReturnType.Type; - // // We don't have to check any others because they are all // guaranteed to be accessible - they are standard types. @@ -159,28 +176,38 @@ namespace Mono.CSharp { CheckProtectedModifier (); - if (RootContext.StdLib && TypeManager.IsSpecialType (ret_type)) { + if (Compiler.Settings.StdLib && ret_type.IsSpecialRuntimeType) { Method.Error1599 (Location, ret_type, Report); return false; } TypeManager.CheckTypeVariance (ret_type, Variance.Covariant, this); - InvokeBuilder = new Method (this, null, ReturnType, MethodModifiers, new MemberName (InvokeMethodName), p, null); + var resolved_rt = new TypeExpression (ret_type, Location); + InvokeBuilder = new Method (this, resolved_rt, MethodModifiers, new MemberName (InvokeMethodName), p, null); InvokeBuilder.Define (); // // 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 (Parameters.CallingConvention); + if (!IsCompilerGenerated) { + DefineAsyncMethods (Parameters.CallingConvention, resolved_rt); } return true; } - void DefineAsyncMethods (CallingConventions cc) + void DefineAsyncMethods (CallingConventions cc, TypeExpression returnType) { + var iasync_result = Module.PredefinedTypes.IAsyncResult; + var async_callback = Module.PredefinedTypes.AsyncCallback; + + // + // It's ok when async types don't exist, the delegate will have Invoke method only + // + if (!iasync_result.Define () || !async_callback.Define ()) + return; + // // BeginInvoke // @@ -189,28 +216,30 @@ namespace Mono.CSharp { async_parameters = ParametersCompiled.EmptyReadOnlyParameters; } else { var compiled = new Parameter[Parameters.Count]; - for (int i = 0; i < compiled.Length; ++i) - compiled[i] = new Parameter (new TypeExpression (Parameters.Types[i], Location), - Parameters.FixedParameters[i].Name, - Parameters.FixedParameters[i].ModFlags & (Parameter.Modifier.REF | Parameter.Modifier.OUT), - null, Location); + for (int i = 0; i < compiled.Length; ++i) { + var p = parameters[i]; + compiled[i] = new Parameter (new TypeExpression (parameters.Types[i], Location), + p.Name, + p.ModFlags & Parameter.Modifier.RefOutMask, + p.OptAttributes == null ? null : p.OptAttributes.Clone (), Location); + } async_parameters = new ParametersCompiled (compiled); } async_parameters = ParametersCompiled.MergeGenerated (Compiler, async_parameters, false, new Parameter[] { - new Parameter (new TypeExpression (TypeManager.asynccallback_type, Location), "callback", Parameter.Modifier.NONE, null, Location), - new Parameter (new TypeExpression (TypeManager.object_type, Location), "object", Parameter.Modifier.NONE, null, Location) + new Parameter (new TypeExpression (async_callback.TypeSpec, Location), "callback", Parameter.Modifier.NONE, null, Location), + new Parameter (new TypeExpression (Compiler.BuiltinTypes.Object, Location), "object", Parameter.Modifier.NONE, null, Location) }, new [] { - TypeManager.asynccallback_type, - TypeManager.object_type + async_callback.TypeSpec, + Compiler.BuiltinTypes.Object } ); - BeginInvokeBuilder = new Method (this, null, - new TypeExpression (TypeManager.iasyncresult_type, Location), MethodModifiers, + BeginInvokeBuilder = new Method (this, + new TypeExpression (iasync_result.TypeSpec, Location), MethodModifiers, new MemberName ("BeginInvoke"), async_parameters, null); BeginInvokeBuilder.Define (); @@ -226,92 +255,92 @@ namespace Mono.CSharp { int out_params = 0; foreach (Parameter p in Parameters.FixedParameters) { - if ((p.ModFlags & Parameter.Modifier.ISBYREF) != 0) + if ((p.ModFlags & Parameter.Modifier.RefOutMask) != 0) ++out_params; } if (out_params > 0) { - var end_param_types = new TypeSpec [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) + if ((p.ModFlags & Parameter.Modifier.RefOutMask) == 0) continue; - end_param_types[param] = Parameters.Types[i]; - end_params[param] = p; - ++param; + end_params [param++] = new Parameter (new TypeExpression (p.Type, Location), + p.Name, + p.ModFlags & Parameter.Modifier.RefOutMask, + p.OptAttributes == null ? null : p.OptAttributes.Clone (), Location); } - end_parameters = ParametersCompiled.CreateFullyResolved (end_params, end_param_types); + + end_parameters = new ParametersCompiled (end_params); } else { end_parameters = ParametersCompiled.EmptyReadOnlyParameters; } end_parameters = ParametersCompiled.MergeGenerated (Compiler, end_parameters, false, new Parameter ( - new TypeExpression (TypeManager.iasyncresult_type, Location), + new TypeExpression (iasync_result.TypeSpec, Location), "result", Parameter.Modifier.NONE, null, Location), - TypeManager.iasyncresult_type); + iasync_result.TypeSpec); // // Create method, define parameters, register parameters with type system // - EndInvokeBuilder = new Method (this, null, ReturnType, MethodModifiers, new MemberName ("EndInvoke"), end_parameters, null); + EndInvokeBuilder = new Method (this, returnType, MethodModifiers, new MemberName ("EndInvoke"), end_parameters, null); EndInvokeBuilder.Define (); } - public override void DefineConstants () + public override void PrepareEmit () { if (!Parameters.IsEmpty) { parameters.ResolveDefaultValues (this); } } - public override void EmitType () + public override void Emit () { + base.Emit (); + if (ReturnType.Type != null) { - if (ReturnType.Type == InternalType.Dynamic) { + if (ReturnType.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location); - Compiler.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder); + Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder); } else if (ReturnType.Type.HasDynamicElement) { return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location); - Compiler.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType.Type); + Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType.Type, Location); } + + ConstraintChecker.Check (this, ReturnType.Type, ReturnType.Location); } - parameters.ApplyAttributes (this, InvokeBuilder.MethodBuilder); - + Constructor.ParameterInfo.ApplyAttributes (this, Constructor.ConstructorBuilder); Constructor.ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.Runtime); + + parameters.CheckConstraints (this); + parameters.ApplyAttributes (this, InvokeBuilder.MethodBuilder); InvokeBuilder.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Runtime); if (BeginInvokeBuilder != null) { BeginInvokeBuilder.ParameterInfo.ApplyAttributes (this, BeginInvokeBuilder.MethodBuilder); + EndInvokeBuilder.ParameterInfo.ApplyAttributes (this, EndInvokeBuilder.MethodBuilder); BeginInvokeBuilder.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Runtime); EndInvokeBuilder.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Runtime); } - - if (OptAttributes != null) { - OptAttributes.Emit (); - } - - base.Emit (); } - protected override TypeExpr[] ResolveBaseTypes (out TypeExpr base_class) + protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class) { - base_type = TypeManager.multicast_delegate_type; + base_type = Compiler.BuiltinTypes.MulticastDelegate; base_class = null; return null; } protected override TypeAttributes TypeAttr { get { - return ModifiersExtensions.TypeAttr (ModFlags, IsTopLevel) | - TypeAttributes.Class | TypeAttributes.Sealed | - base.TypeAttr; + return base.TypeAttr | TypeAttributes.Class | TypeAttributes.Sealed; } } @@ -330,7 +359,7 @@ namespace Mono.CSharp { parameters.VerifyClsCompliance (this); - if (!ReturnType.Type.IsCLSCompliant ()) { + if (!InvokeBuilder.MemberType.IsCLSCompliant ()) { Report.Warning (3002, 1, Location, "Return type of `{0}' is not CLS-compliant", GetSignatureForError ()); } @@ -338,7 +367,7 @@ namespace Mono.CSharp { } - public static MethodSpec GetConstructor (CompilerContext ctx, TypeSpec container_type, TypeSpec delType) + public static MethodSpec GetConstructor (TypeSpec delType) { var ctor = MemberCache.FindMember (delType, MemberFilter.Constructor (null), BindingRestriction.DeclaredOnly); return (MethodSpec) ctor; @@ -347,7 +376,7 @@ namespace Mono.CSharp { // // Returns the "Invoke" from a delegate type // - public static MethodSpec GetInvokeMethod (CompilerContext ctx, TypeSpec delType) + public static MethodSpec GetInvokeMethod (TypeSpec delType) { var invoke = MemberCache.FindMember (delType, MemberFilter.Method (InvokeMethodName, 0, null, null), @@ -356,28 +385,31 @@ namespace Mono.CSharp { return (MethodSpec) invoke; } - public static AParametersCollection GetParameters (CompilerContext ctx, TypeSpec delType) + public static AParametersCollection GetParameters (TypeSpec delType) { - var invoke_mb = GetInvokeMethod (ctx, delType); + var invoke_mb = GetInvokeMethod (delType); return invoke_mb.Parameters; } // // 15.2 Delegate compatibility // - public static bool IsTypeCovariant (Expression a, TypeSpec b) + public static bool IsTypeCovariant (ResolveContext rc, TypeSpec a, TypeSpec b) { // // For each value parameter (a parameter with no ref or out modifier), an // identity conversion or implicit reference conversion exists from the // parameter type in D to the corresponding parameter type in M // - if (a.Type == b) + if (a == b) return true; - if (RootContext.Version == LanguageVersion.ISO_1) + if (rc.Module.Compiler.Settings.Version == LanguageVersion.ISO_1) return false; + if (a.IsGenericParameter && b.IsGenericParameter) + return a == b; + return Convert.ImplicitReferenceConversionExists (a, b); } @@ -404,7 +436,14 @@ namespace Mono.CSharp { protected MethodSpec constructor_method; protected MethodGroupExpr method_group; - public static Arguments CreateDelegateMethodArguments (AParametersCollection pd, TypeSpec[] types, Location loc) + public bool AllowSpecialMethodsInvocation { get; set; } + + public override bool ContainsEmitWithAwait () + { + return false; + } + + public static Arguments CreateDelegateMethodArguments (ResolveContext rc, AParametersCollection pd, TypeSpec[] types, Location loc) { Arguments delegate_arguments = new Arguments (pd.Count); for (int i = 0; i < pd.Count; ++i) { @@ -421,7 +460,11 @@ namespace Mono.CSharp { break; } - delegate_arguments.Add (new Argument (new TypeExpression (types [i], loc), atype_modifier)); + var ptype = types[i]; + if (ptype.BuiltinType == BuiltinTypeSpec.Type.Dynamic) + ptype = rc.BuiltinTypes.Object; + + delegate_arguments.Add (new Argument (new TypeExpression (ptype, loc), atype_modifier)); } return delegate_arguments; @@ -432,8 +475,13 @@ namespace Mono.CSharp { MemberAccess ma = new MemberAccess (new MemberAccess (new QualifiedAliasMember ("global", "System", loc), "Delegate", loc), "CreateDelegate", loc); Arguments args = new Arguments (3); - args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc))); - args.Add (new Argument (new NullLiteral (loc))); + args.Add (new Argument (new TypeOf (type, loc))); + + if (method_group.InstanceExpression == null) + args.Add (new Argument (new NullLiteral (loc))); + else + args.Add (new Argument (method_group.InstanceExpression)); + args.Add (new Argument (method_group.CreateExpressionTree (ec))); Expression e = new Invocation (ma, args).Resolve (ec); if (e == null) @@ -448,42 +496,46 @@ namespace Mono.CSharp { protected override Expression DoResolve (ResolveContext ec) { - constructor_method = Delegate.GetConstructor (ec.Compiler, ec.CurrentType, type); + constructor_method = Delegate.GetConstructor (type); - var invoke_method = Delegate.GetInvokeMethod (ec.Compiler, type); + var invoke_method = Delegate.GetInvokeMethod (type); - Arguments arguments = CreateDelegateMethodArguments (invoke_method.Parameters, invoke_method.Parameters.Types, loc); + Arguments arguments = CreateDelegateMethodArguments (ec, invoke_method.Parameters, invoke_method.Parameters.Types, loc); method_group = method_group.OverloadResolve (ec, ref arguments, this, OverloadResolver.Restrictions.CovariantDelegate); if (method_group == null) return null; var delegate_method = method_group.BestCandidate; - if (TypeManager.IsNullableType (delegate_method.DeclaringType)) { + if (delegate_method.DeclaringType.IsNullableType) { ec.Report.Error (1728, loc, "Cannot create delegate from method `{0}' because it is a member of System.Nullable type", delegate_method.GetSignatureForError ()); return null; } - Invocation.IsSpecialMethodInvocation (ec, delegate_method, loc); + if (!AllowSpecialMethodsInvocation) + Invocation.IsSpecialMethodInvocation (ec, delegate_method, loc); ExtensionMethodGroupExpr emg = method_group as ExtensionMethodGroupExpr; if (emg != null) { method_group.InstanceExpression = emg.ExtensionExpression; TypeSpec e_type = emg.ExtensionExpression.Type; - if (TypeManager.IsValueType (e_type)) { + if (TypeSpec.IsValueType (e_type)) { ec.Report.Error (1113, loc, "Extension method `{0}' of value type `{1}' cannot be used to create delegates", delegate_method.GetSignatureForError (), TypeManager.CSharpName (e_type)); } } TypeSpec rt = delegate_method.ReturnType; - Expression ret_expr = new TypeExpression (rt, loc); - if (!Delegate.IsTypeCovariant (ret_expr, invoke_method.ReturnType)) { + if (rt.BuiltinType == BuiltinTypeSpec.Type.Dynamic) + rt = ec.BuiltinTypes.Object; + + if (!Delegate.IsTypeCovariant (ec, rt, invoke_method.ReturnType)) { + Expression ret_expr = new TypeExpression (delegate_method.ReturnType, loc); Error_ConversionFailed (ec, delegate_method, ret_expr); } - if (delegate_method.IsConditionallyExcluded (loc)) { + if (delegate_method.IsConditionallyExcluded (ec, loc)) { ec.Report.SymbolRelatedToPreviousError (delegate_method); MethodOrOperator m = delegate_method.MemberDefinition as MethodOrOperator; if (m != null && m.IsPartialDefinition) { @@ -496,8 +548,8 @@ namespace Mono.CSharp { } var expr = method_group.InstanceExpression; - if (expr != null && (expr.Type.IsGenericParameter || !TypeManager.IsReferenceType (expr.Type))) - method_group.InstanceExpression = new BoxedCast (expr, TypeManager.object_type); + if (expr != null && (expr.Type.IsGenericParameter || !TypeSpec.IsReferenceType (expr.Type))) + method_group.InstanceExpression = new BoxedCast (expr, ec.BuiltinTypes.Object); eclass = ExprClass.Value; return this; @@ -506,7 +558,7 @@ namespace Mono.CSharp { public override void Emit (EmitContext ec) { if (method_group.InstanceExpression == null) - ec.Emit (OpCodes.Ldnull); + ec.EmitNull (); else method_group.InstanceExpression.Emit (ec); @@ -525,14 +577,14 @@ namespace Mono.CSharp { void Error_ConversionFailed (ResolveContext ec, MethodSpec method, Expression return_type) { - var invoke_method = Delegate.GetInvokeMethod (ec.Compiler, type); + var invoke_method = Delegate.GetInvokeMethod (type); string member_name = method_group.InstanceExpression != null ? Delegate.FullDelegateDesc (method) : TypeManager.GetFullNameSignature (method); ec.Report.SymbolRelatedToPreviousError (type); ec.Report.SymbolRelatedToPreviousError (method); - if (RootContext.Version == LanguageVersion.ISO_1) { + if (ec.Module.Compiler.Settings.Version == LanguageVersion.ISO_1) { ec.Report.Error (410, loc, "A method or delegate `{0} {1}' parameters and return type must be same as delegate `{2} {3}' parameters and return type", TypeManager.CSharpName (method.ReturnType), member_name, TypeManager.CSharpName (invoke_method.ReturnType), Delegate.FullDelegateDesc (invoke_method)); @@ -552,12 +604,12 @@ namespace Mono.CSharp { public static bool ImplicitStandardConversionExists (ResolveContext ec, MethodGroupExpr mg, TypeSpec target_type) { - if (target_type == TypeManager.delegate_type || target_type == TypeManager.multicast_delegate_type) - return false; +// if (target_type == TypeManager.delegate_type || target_type == TypeManager.multicast_delegate_type) +// return false; - var invoke = Delegate.GetInvokeMethod (ec.Compiler, target_type); + var invoke = Delegate.GetInvokeMethod (target_type); - Arguments arguments = CreateDelegateMethodArguments (invoke.Parameters, invoke.Parameters.Types, mg.Location); + Arguments arguments = CreateDelegateMethodArguments (ec, invoke.Parameters, invoke.Parameters.Types, mg.Location); return mg.OverloadResolve (ec, ref arguments, null, OverloadResolver.Restrictions.CovariantDelegate | OverloadResolver.Restrictions.ProbingOnly) != null; } @@ -593,18 +645,92 @@ namespace Mono.CSharp { // public class ImplicitDelegateCreation : DelegateCreation { - ImplicitDelegateCreation (TypeSpec t, MethodGroupExpr mg, Location l) + Field mg_cache; + + public ImplicitDelegateCreation (TypeSpec delegateType, MethodGroupExpr mg, Location loc) { - type = t; + type = delegateType; this.method_group = mg; - loc = l; + this.loc = loc; } - static public Expression Create (ResolveContext ec, MethodGroupExpr mge, - TypeSpec target_type, Location loc) + // + // Returns true when type is MVAR or has MVAR reference + // + static bool ContainsMethodTypeParameter (TypeSpec type) { - ImplicitDelegateCreation d = new ImplicitDelegateCreation (target_type, mge, loc); - return d.DoResolve (ec); + var tps = type as TypeParameterSpec; + if (tps != null) + return tps.IsMethodOwned; + + var ec = type as ElementTypeSpec; + if (ec != null) + return ContainsMethodTypeParameter (ec.Element); + + foreach (var t in type.TypeArguments) { + if (ContainsMethodTypeParameter (t)) { + return true; + } + } + + return false; + } + + protected override Expression DoResolve (ResolveContext ec) + { + var expr = base.DoResolve (ec); + if (expr == null) + return null; + + if (ec.IsInProbingMode) + return expr; + + // + // Cache any static delegate creation + // + if (method_group.InstanceExpression != null) + return expr; + + // + // Cannot easily cache types with MVAR + // + if (ContainsMethodTypeParameter (type)) + return expr; + + if (ContainsMethodTypeParameter (method_group.BestCandidate.DeclaringType)) + return expr; + + // + // Create type level cache for a delegate instance + // + var parent = ec.CurrentMemberDefinition.Parent.PartialContainer; + int id = parent.MethodGroupsCounter++; + + mg_cache = new Field (parent, new TypeExpression (type, loc), + Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED, + new MemberName (CompilerGeneratedContainer.MakeName (null, "f", "mg$cache", id), loc), null); + mg_cache.Define (); + parent.AddField (mg_cache); + + return expr; + } + + public override void Emit (EmitContext ec) + { + Label l_initialized = ec.DefineLabel (); + + if (mg_cache != null) { + ec.Emit (OpCodes.Ldsfld, mg_cache.Spec); + ec.Emit (OpCodes.Brtrue_S, l_initialized); + } + + base.Emit (ec); + + if (mg_cache != null) { + ec.Emit (OpCodes.Stsfld, mg_cache.Spec); + ec.MarkLabel (l_initialized); + ec.Emit (OpCodes.Ldsfld, mg_cache.Spec); + } } } @@ -639,7 +765,7 @@ namespace Mono.CSharp { Expression e = a.Expr; AnonymousMethodExpression ame = e as AnonymousMethodExpression; - if (ame != null && RootContext.Version != LanguageVersion.ISO_1) { + if (ame != null && ec.Module.Compiler.Settings.Version != LanguageVersion.ISO_1) { e = ame.Compatible (ec, type); if (e == null) return null; @@ -649,7 +775,7 @@ namespace Mono.CSharp { method_group = e as MethodGroupExpr; if (method_group == null) { - if (e.Type == InternalType.Dynamic) { + if (e.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { e = Convert.ImplicitConversionRequired (ec, e, type, loc); } else if (!e.Type.IsDelegate) { e.Error_UnexpectedKind (ec, ResolveFlags.MethodGroup | ResolveFlags.Type, loc); @@ -659,7 +785,7 @@ namespace Mono.CSharp { // // An argument is not a method but another delegate // - method_group = new MethodGroupExpr (Delegate.GetInvokeMethod (ec.Compiler, e.Type), e.Type, loc); + method_group = new MethodGroupExpr (Delegate.GetInvokeMethod (e.Type), e.Type, loc); method_group.InstanceExpression = e; } @@ -682,6 +808,11 @@ namespace Mono.CSharp { this.arguments = args; this.loc = loc; } + + public override bool ContainsEmitWithAwait () + { + return InstanceExpr.ContainsEmitWithAwait () || (arguments != null && arguments.ContainsEmitWithAwait ()); + } public override Expression CreateExpressionTree (ResolveContext ec) { @@ -701,7 +832,7 @@ namespace Mono.CSharp { // Do only core overload resolution the rest of the checks has been // done on primary expression // - method = Delegate.GetInvokeMethod (ec.Compiler, del_type); + method = Delegate.GetInvokeMethod (del_type); var res = new OverloadResolver (new MemberSpec[] { method }, OverloadResolver.Restrictions.DelegateInvoke, loc); var valid = res.ResolveMember (ec, ref arguments); if (valid == null && !res.BestCandidateIsDynamic) @@ -718,7 +849,9 @@ namespace Mono.CSharp { // Invocation on delegates call the virtual Invoke member // so we are always `instance' calls // - Invocation.EmitCall (ec, InstanceExpr, method, arguments, loc); + var call = new CallEmitter (); + call.InstanceExpression = InstanceExpr; + call.EmitPredefined (ec, method, arguments); } public override void EmitStatement (EmitContext ec) @@ -727,7 +860,7 @@ namespace Mono.CSharp { // // Pop the return value if there is one // - if (type != TypeManager.void_type) + if (type.Kind != MemberKind.Void) ec.Emit (OpCodes.Pop); }