X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fanonymous.cs;h=ce83e7674c14d88cc1b6c60145409209a83def58;hb=009d937c1df7d8949b7671c89426e33a11c6d284;hp=86658f897f0f170f860077a6c88ee50950c3d0d1;hpb=9b2e52a86a4191314a3dc690e046d74cf766927e;p=mono.git diff --git a/mcs/mcs/anonymous.cs b/mcs/mcs/anonymous.cs index 86658f897f0..ce83e7674c1 100644 --- a/mcs/mcs/anonymous.cs +++ b/mcs/mcs/anonymous.cs @@ -191,15 +191,27 @@ namespace Mono.CSharp { sealed class ThisInitializer : Statement { readonly HoistedThis hoisted_this; + readonly AnonymousMethodStorey parent; - public ThisInitializer (HoistedThis hoisted_this) + public ThisInitializer (HoistedThis hoisted_this, AnonymousMethodStorey parent) { this.hoisted_this = hoisted_this; + this.parent = parent; } protected override void DoEmit (EmitContext ec) { - hoisted_this.EmitAssign (ec, new CompilerGeneratedThis (ec.CurrentType, loc), false, false); + Expression source; + + if (parent == null) + source = new CompilerGeneratedThis (ec.CurrentType, loc); + else { + source = new FieldExpr (parent.HoistedThis.Field, Location.Null) { + InstanceExpression = new CompilerGeneratedThis (ec.CurrentType, Location.Null) + }; + } + + hoisted_this.EmitAssign (ec, source, false, false); } protected override void CloneTo (CloneContext clonectx, Statement target) @@ -229,6 +241,7 @@ namespace Mono.CSharp { public Expression Instance; bool initialize_hoisted_this; + AnonymousMethodStorey hoisted_this_parent; public AnonymousMethodStorey (ExplicitBlock block, TypeDefinition parent, MemberBase host, TypeParameters tparams, string name, MemberKind kind) : base (parent, MakeMemberName (host, name, parent.Module.CounterAnonymousContainers, tparams, block.StartLocation), @@ -238,13 +251,14 @@ namespace Mono.CSharp { ID = parent.Module.CounterAnonymousContainers++; } - public void AddCapturedThisField (EmitContext ec) + public void AddCapturedThisField (EmitContext ec, AnonymousMethodStorey parent) { TypeExpr type_expr = new TypeExpression (ec.CurrentType, Location); Field f = AddCompilerGeneratedField ("$this", type_expr); hoisted_this = new HoistedThis (this, f); initialize_hoisted_this = true; + hoisted_this_parent = parent; } public Field AddCapturedVariable (string name, TypeSpec type) @@ -315,8 +329,11 @@ namespace Mono.CSharp { var hoisted = localVariable.HoistedVariant; if (hoisted != null && hoisted.Storey != this && hoisted.Storey is StateMachine) { - // TODO: It's too late the field is defined in HoistedLocalVariable ctor + // + // Variable is already hoisted but we need it in storey which can be shared + // hoisted.Storey.hoisted_locals.Remove (hoisted); + hoisted.Storey.Members.Remove (hoisted.Field); hoisted = null; } @@ -550,7 +567,7 @@ namespace Mono.CSharp { // referenced indirectly // if (initialize_hoisted_this) { - rc.CurrentBlock.AddScopeStatement (new ThisInitializer (hoisted_this)); + rc.CurrentBlock.AddScopeStatement (new ThisInitializer (hoisted_this, hoisted_this_parent)); } // @@ -728,6 +745,12 @@ namespace Mono.CSharp { this.field = field; } + public Field Field { + get { + return field; + } + } + public AnonymousMethodStorey Storey { get { return storey; @@ -848,12 +871,6 @@ namespace Mono.CSharp { #region Properties - public Field Field { - get { - return field; - } - } - public bool IsAssigned { get; set; } public ParameterReference Parameter { @@ -893,12 +910,6 @@ namespace Mono.CSharp { : base (storey, field) { } - - public Field Field { - get { - return field; - } - } } // @@ -959,6 +970,12 @@ namespace Mono.CSharp { } } + public override bool IsSideEffectFree { + get { + return true; + } + } + public ParametersCompiled Parameters { get { return Block.Parameters; @@ -1010,9 +1027,9 @@ namespace Mono.CSharp { return null; } - protected bool VerifyExplicitParameters (ResolveContext ec, TypeSpec delegate_type, AParametersCollection parameters) + protected bool VerifyExplicitParameters (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegate_type, AParametersCollection parameters) { - if (VerifyParameterCompatibility (ec, delegate_type, parameters, ec.IsInProbingMode)) + if (VerifyParameterCompatibility (ec, tic, delegate_type, parameters, ec.IsInProbingMode)) return true; if (!ec.IsInProbingMode) @@ -1023,7 +1040,7 @@ namespace Mono.CSharp { return false; } - protected bool VerifyParameterCompatibility (ResolveContext ec, TypeSpec delegate_type, AParametersCollection invoke_pd, bool ignore_errors) + protected bool VerifyParameterCompatibility (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegate_type, AParametersCollection invoke_pd, bool ignore_errors) { if (Parameters.Count != invoke_pd.Count) { if (ignore_errors) @@ -1056,14 +1073,11 @@ namespace Mono.CSharp { continue; TypeSpec type = invoke_pd.Types [i]; + + if (tic != null) + type = tic.InflateGenericArgument (ec, type); - // - // Assumes that generic mvar parameters are always inflated - // - if (ImplicitDelegateCreation.ContainsMethodTypeParameter (type)) - continue; - - if (!TypeSpecComparer.IsEqual (invoke_pd.Types [i], Parameters.Types [i])) { + if (!TypeSpecComparer.IsEqual (type, Parameters.Types [i])) { if (ignore_errors) return false; @@ -1081,7 +1095,7 @@ namespace Mono.CSharp { // // Infers type arguments based on explicit arguments // - public bool ExplicitTypeInference (ResolveContext ec, TypeInferenceContext type_inference, TypeSpec delegate_type) + public bool ExplicitTypeInference (TypeInferenceContext type_inference, TypeSpec delegate_type) { if (!HasExplicitParameters) return false; @@ -1295,7 +1309,7 @@ namespace Mono.CSharp { return ParametersCompiled.CreateFullyResolved (fixedpars, delegate_parameters.Types); } - if (!VerifyExplicitParameters (ec, delegate_type, delegate_parameters)) { + if (!VerifyExplicitParameters (ec, tic, delegate_type, delegate_parameters)) { return null; } @@ -1663,7 +1677,7 @@ namespace Mono.CSharp { // enough. No hoisted variables only 'this' and don't need to // propagate this to value type state machine. // - StateMachine sm_parent = null; + StateMachine sm_parent; var pb = src_block.ParametersBlock; do { sm_parent = pb.StateMachine; @@ -1675,18 +1689,17 @@ namespace Mono.CSharp { } else if (sm_parent.Kind == MemberKind.Struct) { // // Special case where parent class is used to emit instance method - // because currect storey is of value type (async host). We cannot + // because currect storey is of value type (async host) and we cannot // use ldftn on non-boxed instances either to share mutated state // parent = sm_parent.Parent.PartialContainer; + } else if (sm is IteratorStorey) { + // + // For iterators we can host everything in one class + // + parent = storey = sm; } } - - // - // For iterators we can host everything in one class - // - if (sm is IteratorStorey) - parent = storey = sm; } modifiers = storey != null ? Modifiers.INTERNAL : Modifiers.PRIVATE; @@ -1809,12 +1822,8 @@ namespace Mono.CSharp { // Special case for value type storey where this is not lifted but // droped off to parent class // - for (var b = Block.Parent; b != null; b = b.Parent) { - if (b.ParametersBlock.StateMachine != null) { - ec.Emit (OpCodes.Ldfld, b.ParametersBlock.StateMachine.HoistedThis.Field.Spec); - break; - } - } + if (ec.CurrentAnonymousMethod != null && ec.AsyncTaskStorey != null) + ec.Emit (OpCodes.Ldfld, ec.AsyncTaskStorey.HoistedThis.Field.Spec); } var delegate_method = method.Spec; @@ -1993,7 +2002,7 @@ namespace Mono.CSharp { Method tostring = new Method (this, new TypeExpression (Compiler.BuiltinTypes.String, loc), Modifiers.PUBLIC | Modifiers.OVERRIDE | Modifiers.DEBUGGER_HIDDEN, new MemberName ("ToString", loc), - Mono.CSharp.ParametersCompiled.EmptyReadOnlyParameters, null); + ParametersCompiled.EmptyReadOnlyParameters, null); ToplevelBlock equals_block = new ToplevelBlock (Compiler, equals.ParameterInfo, loc); @@ -2102,7 +2111,7 @@ namespace Mono.CSharp { Method hashcode = new Method (this, new TypeExpression (Compiler.BuiltinTypes.Int, loc), Modifiers.PUBLIC | Modifiers.OVERRIDE | Modifiers.DEBUGGER_HIDDEN, new MemberName ("GetHashCode", loc), - Mono.CSharp.ParametersCompiled.EmptyReadOnlyParameters, null); + ParametersCompiled.EmptyReadOnlyParameters, null); // // Modified FNV with good avalanche behavior and uniform