X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fiterators.cs;h=ddd316fa14cef277eb578f740bc398dbde7fef4f;hb=2eea853bba93a9f38959fbebc6ead28e2fa318b0;hp=ce2db5b078e222e9222f32262569ea11d5fe9bae;hpb=33028b1a2c0d0345efc3639f3b33d74dc96daf62;p=mono.git diff --git a/mcs/mcs/iterators.cs b/mcs/mcs/iterators.cs index ce2db5b078e..ddd316fa14c 100644 --- a/mcs/mcs/iterators.cs +++ b/mcs/mcs/iterators.cs @@ -139,9 +139,9 @@ namespace Mono.CSharp { class IteratorStatement : Statement { Iterator iterator; - ExplicitBlock original_block; + Block original_block; - public IteratorStatement (Iterator iterator, ExplicitBlock original_block) + public IteratorStatement (Iterator iterator, Block original_block) { this.iterator = iterator; this.original_block = original_block; @@ -183,11 +183,11 @@ namespace Mono.CSharp { public IteratorMethod (IteratorStorey host, FullNamedExpression returnType, int mod, MemberName name) : base (host, null, returnType, mod | Modifiers.DEBUGGER_HIDDEN | Modifiers.COMPILER_GENERATED, - name, Parameters.EmptyReadOnlyParameters, null) + name, ParametersCompiled.EmptyReadOnlyParameters, null) { this.host = host; - Block = new ToplevelBlock (host.Iterator.Container.Toplevel, null, Location); + Block = new ToplevelBlock (host.Iterator.Container.Toplevel, ParametersCompiled.EmptyReadOnlyParameters, Location); } public override EmitContext CreateEmitContext (DeclSpace tc, ILGenerator ig) @@ -205,15 +205,15 @@ namespace Mono.CSharp { sealed class GetEnumeratorStatement : Statement { IteratorStorey host; - Expression type; + IteratorMethod host_method; - Expression cast; + Expression new_storey; - public GetEnumeratorStatement (IteratorStorey host, Expression type) + public GetEnumeratorStatement (IteratorStorey host, IteratorMethod host_method) { this.host = host; - this.type = type; - loc = host.Location; + this.host_method = host_method; + loc = host_method.Location; } protected override void CloneTo (CloneContext clonectx, Statement target) @@ -223,12 +223,7 @@ namespace Mono.CSharp { public override bool Resolve (EmitContext ec) { - type = type.ResolveAsTypeTerminal (ec, false); - if ((type == null) || (type.Type == null)) - return false; - TypeExpression storey_type_expr = new TypeExpression (host.TypeBuilder, loc); - Expression new_storey; ArrayList init = null; if (host.hoisted_this != null) { init = new ArrayList (host.hoisted_params == null ? 1 : host.HoistedParameters.Count + 1); @@ -242,23 +237,27 @@ namespace Mono.CSharp { if (init == null) init = new ArrayList (host.HoistedParameters.Count); - foreach (HoistedParameter hp in host.HoistedParameters) { - FieldExpr from = new FieldExpr (hp.Field.FieldBuilder, loc); + 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.FieldBuilder, loc); from.InstanceExpression = CompilerGeneratedThis.Instance; + init.Add (new ElementInitializer (hp.Field.Name, from, loc)); } } if (init != null) { - new_storey = new NewInitialize (storey_type_expr, new ArrayList (0), + new_storey = new NewInitialize (storey_type_expr, null, new CollectionOrObjectInitializers (init, loc), loc); } else { - new_storey = new New (storey_type_expr, new ArrayList (0), loc); + new_storey = new New (storey_type_expr, null, loc); } new_storey = new_storey.Resolve (ec); if (new_storey != null) - cast = Convert.ImplicitConversionRequired (ec, new_storey, type.Type, loc); + new_storey = Convert.ImplicitConversionRequired (ec, new_storey, host_method.MemberType, loc); if (TypeManager.int_interlocked_compare_exchange == null) { Type t = TypeManager.CoreLookupType ("System.Threading", "Interlocked", Kind.Class, true); @@ -280,19 +279,19 @@ namespace Mono.CSharp { ig.Emit (OpCodes.Ldarg_0); ig.Emit (OpCodes.Ldflda, host.PC.FieldBuilder); - ig.Emit (OpCodes.Ldc_I4, (int) Iterator.State.Start); - ig.Emit (OpCodes.Ldc_I4, (int) Iterator.State.Uninitialized); + IntConstant.EmitInt (ig, (int) Iterator.State.Start); + IntConstant.EmitInt (ig, (int) Iterator.State.Uninitialized); ig.Emit (OpCodes.Call, TypeManager.int_interlocked_compare_exchange); - ig.Emit (OpCodes.Ldc_I4, (int) Iterator.State.Uninitialized); - ig.Emit (OpCodes.Bne_Un, label_init); + IntConstant.EmitInt (ig, (int) Iterator.State.Uninitialized); + ig.Emit (OpCodes.Bne_Un_S, label_init); ig.Emit (OpCodes.Ldarg_0); ig.Emit (OpCodes.Ret); ig.MarkLabel (label_init); - cast.Emit (ec); + new_storey.Emit (ec); ig.Emit (OpCodes.Ret); } @@ -305,7 +304,7 @@ namespace Mono.CSharp { public GetEnumeratorMethod (IteratorStorey host, FullNamedExpression returnType, MemberName name) : base (host, returnType, 0, name) { - Block.AddStatement (new GetEnumeratorStatement (host, type_name)); + Block.AddStatement (new GetEnumeratorStatement (host, this)); } } @@ -347,7 +346,7 @@ namespace Mono.CSharp { { host.AddMethod (this); - Block = new ToplevelBlock (host.Iterator.Container, null, Location); + Block = new ToplevelBlock (host.Iterator.Container, ParametersCompiled.EmptyReadOnlyParameters, Location); Block.AddStatement (new DisposeMethodStatement (host.Iterator)); } } @@ -374,6 +373,25 @@ namespace Mono.CSharp { } } + class DynamicFieldExpr : FieldExpr + { + readonly Field field; + + public DynamicFieldExpr (Field field, Location loc) + : base (loc) + { + this.field = field; + } + + public override Expression DoResolve (EmitContext ec) + { + FieldInfo = field.FieldBuilder; + type = TypeManager.TypeToCoreType (FieldInfo.FieldType); + InstanceExpression = new CompilerGeneratedThis (type, Location); + return base.DoResolve (ec); + } + } + public readonly Iterator Iterator; TypeExpr iterator_type_expr; @@ -382,14 +400,11 @@ namespace Mono.CSharp { TypeExpr enumerator_type; TypeExpr enumerable_type; -#if GMCS_SOURCE TypeArguments generic_args; TypeExpr generic_enumerator_type; TypeExpr generic_enumerable_type; -#else - const TypeArguments generic_args = null; -#endif + ArrayList hoisted_params_copy; int local_name_idx; public IteratorStorey (Iterator iterator) @@ -397,7 +412,6 @@ namespace Mono.CSharp { iterator.OriginalMethod as MemberBase, iterator.GenericMethod, "Iterator") { this.Iterator = iterator; - HasHoistedVariables = true; } public Field PC { @@ -415,11 +429,7 @@ namespace Mono.CSharp { protected override TypeExpr [] ResolveBaseTypes (out TypeExpr base_class) { iterator_type_expr = new TypeExpression (MutateType (Iterator.OriginalIteratorType), Location); - -#if GMCS_SOURCE - generic_args = new TypeArguments (Location); - generic_args.Add (iterator_type_expr); -#endif + generic_args = new TypeArguments (iterator_type_expr); ArrayList list = new ArrayList (); if (Iterator.IsEnumerable) { @@ -427,12 +437,12 @@ namespace Mono.CSharp { TypeManager.ienumerable_type, Location); list.Add (enumerable_type); -#if GMCS_SOURCE - generic_enumerable_type = new ConstructedType ( - TypeManager.generic_ienumerable_type, - generic_args, Location); - list.Add (generic_enumerable_type); -#endif + if (TypeManager.generic_ienumerable_type != null) { + generic_enumerable_type = new GenericTypeExpr ( + TypeManager.generic_ienumerable_type, + generic_args, Location); + list.Add (generic_enumerable_type); + } } enumerator_type = new TypeExpression ( @@ -441,12 +451,12 @@ namespace Mono.CSharp { list.Add (new TypeExpression (TypeManager.idisposable_type, Location)); -#if GMCS_SOURCE - generic_enumerator_type = new ConstructedType ( - TypeManager.generic_ienumerator_type, - generic_args, Location); - list.Add (generic_enumerator_type); -#endif + if (TypeManager.generic_ienumerator_type != null) { + generic_enumerator_type = new GenericTypeExpr ( + TypeManager.generic_ienumerator_type, + generic_args, Location); + list.Add (generic_enumerator_type); + } type_bases = list; @@ -463,58 +473,82 @@ namespace Mono.CSharp { pc_field = AddCompilerGeneratedField ("$PC", TypeManager.system_int32_expr); current_field = AddCompilerGeneratedField ("$current", iterator_type_expr); -#if GMCS_SOURCE - Define_Current (true); -#endif + if (hoisted_params != null) { + // + // Iterators are independent, each GetEnumerator call has to + // create same enumerator therefore we have to keep original values + // around for re-initialization + // + // TODO: Do it for assigned/modified parameters only + // + hoisted_params_copy = new ArrayList (hoisted_params.Count); + foreach (HoistedParameter hp in hoisted_params) { + hoisted_params_copy.Add (new HoistedParameter (hp, "<$>" + hp.Field.Name)); + } + } + + if (generic_enumerator_type != null) + Define_Current (true); + Define_Current (false); new DisposeMethod (this); Define_Reset (); if (Iterator.IsEnumerable) { - MemberName name = new MemberName ( - new MemberName ("System.Collections.IEnumerable", Location), "GetEnumerator", Location); - -#if GMCS_SOURCE - Method get_enumerator = new IteratorMethod (this, enumerator_type, 0, name); - - name = new MemberName ( - new MemberName ("System.Collections.Generic.IEnumerable", generic_args, Location), "GetEnumerator", Location); - Method gget_enumerator = new GetEnumeratorMethod (this, generic_enumerator_type, name); - - // - // Just call generic GetEnumerator implementation - // - get_enumerator.Block.AddStatement ( - new Return (new Invocation (new DynamicMethodGroupExpr (gget_enumerator, Location), new ArrayList (0)), Location)); - - AddMethod (get_enumerator); - AddMethod (gget_enumerator); -#else - AddMethod (new GetEnumeratorMethod (this, enumerator_type, name)); -#endif + MemberName name = new MemberName (QualifiedAliasMember.GlobalAlias, "System", null, Location); + name = new MemberName (name, "Collections", Location); + name = new MemberName (name, "IEnumerable", Location); + name = new MemberName (name, "GetEnumerator", Location); + + if (generic_enumerator_type != null) { + Method get_enumerator = new IteratorMethod (this, enumerator_type, 0, name); + + name = new MemberName (name.Left.Left, "Generic", Location); + name = new MemberName (name, "IEnumerable", generic_args, Location); + name = new MemberName (name, "GetEnumerator", Location); + Method gget_enumerator = new GetEnumeratorMethod (this, generic_enumerator_type, name); + + // + // Just call generic GetEnumerator implementation + // + get_enumerator.Block.AddStatement ( + new Return (new Invocation (new DynamicMethodGroupExpr (gget_enumerator, Location), null), Location)); + + AddMethod (get_enumerator); + AddMethod (gget_enumerator); + } else { + AddMethod (new GetEnumeratorMethod (this, enumerator_type, name)); + } } } + protected override void EmitHoistedParameters (EmitContext ec, ArrayList hoisted) + { + base.EmitHoistedParameters (ec, hoisted); + base.EmitHoistedParameters (ec, hoisted_params_copy); + } + void Define_Current (bool is_generic) { - MemberName left; TypeExpr type; + MemberName name = new MemberName (QualifiedAliasMember.GlobalAlias, "System", null, Location); + name = new MemberName (name, "Collections", Location); + if (is_generic) { - left = new MemberName ( - "System.Collections.Generic.IEnumerator", - generic_args, Location); + name = new MemberName (name, "Generic", Location); + name = new MemberName (name, "IEnumerator", generic_args, Location); type = iterator_type_expr; } else { - left = new MemberName ("System.Collections.IEnumerator", Location); + name = new MemberName (name, "IEnumerator"); type = TypeManager.system_object_expr; } - MemberName name = new MemberName (left, "Current", null, Location); + name = new MemberName (name, "Current", Location); ToplevelBlock get_block = new ToplevelBlock (Location); - get_block.AddStatement (new CurrentBlock (this, is_generic)); - + get_block.AddStatement (new Return (new DynamicFieldExpr (CurrentField, Location), Location)); + Accessor getter = new Accessor (get_block, 0, null, null, Location); Property current = new Property ( @@ -528,58 +562,16 @@ namespace Mono.CSharp { this, null, TypeManager.system_void_expr, Modifiers.PUBLIC | Modifiers.DEBUGGER_HIDDEN, new MemberName ("Reset", Location), - Parameters.EmptyReadOnlyParameters, null); + ParametersCompiled.EmptyReadOnlyParameters, null); AddMethod (reset); reset.Block = new ToplevelBlock (Location); - reset.Block.AddStatement (Create_ThrowNotSupported ()); - } - - Statement Create_ThrowNotSupported () - { - TypeExpr ex_type = new TypeLookupExpression ("System.NotSupportedException"); - - return new Throw (new New (ex_type, null, Location), Location); - } - - protected class CurrentBlock : Statement { - IteratorStorey host; - bool is_generic; - - public CurrentBlock (IteratorStorey host, bool is_generic) - { - this.host = host; - this.is_generic = is_generic; - loc = host.Location; - } - - protected override void CloneTo (CloneContext clonectx, Statement target) - { - throw new NotSupportedException (); - } - - public override bool Resolve (EmitContext ec) - { - // We emit a 'ret', so prevent the enclosing TopLevelBlock from emitting one too - ec.CurrentBranching.CurrentUsageVector.Goto (); - return true; - } - - protected override void DoEmit (EmitContext ec) - { - ILGenerator ig = ec.ig; - ig.Emit (OpCodes.Ldarg_0); - ig.Emit (OpCodes.Ldfld, host.CurrentField.FieldBuilder); - if (!is_generic) - ig.Emit (OpCodes.Box, host.CurrentField.MemberType); - ig.Emit (OpCodes.Ret); - } + Type ex_type = TypeManager.CoreLookupType ("System", "NotSupportedException", Kind.Class, true); + if (ex_type == null) + return; - public override void MutateHoistedGenericType (AnonymousMethodStorey storey) - { - throw new NotSupportedException (); - } + reset.Block.AddStatement (new Throw (new New (new TypeExpression (ex_type, Location), null, Location), Location)); } } @@ -625,11 +617,6 @@ namespace Mono.CSharp { Start = 0 } - public override void AddStoreyReference (AnonymousMethodStorey storey) - { - // do nothing - } - public void EmitYieldBreak (ILGenerator ig, bool unwind_protect) { ig.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, move_next_error); @@ -827,7 +814,7 @@ namespace Mono.CSharp { // private Iterator (IMethodData method, TypeContainer host, Type iterator_type, bool is_enumerable) : base ( - new ToplevelBlock (method.Block, Parameters.EmptyReadOnlyParameters, method.Block.StartLocation), + new ToplevelBlock (method.Block, ParametersCompiled.EmptyReadOnlyParameters, method.Block.StartLocation), TypeManager.bool_type, method.Location) { @@ -850,7 +837,7 @@ namespace Mono.CSharp { this, Storey, null, TypeManager.system_boolean_expr, Modifiers.PUBLIC, OriginalMethod.GetSignatureForError (), new MemberName ("MoveNext", Location), - Parameters.EmptyReadOnlyParameters); + ParametersCompiled.EmptyReadOnlyParameters); if (!Compatible (ec)) return null; @@ -909,7 +896,7 @@ namespace Mono.CSharp { return; } - Parameters parameters = method.ParameterInfo; + ParametersCompiled parameters = method.ParameterInfo; for (int i = 0; i < parameters.Count; i++) { Parameter p = parameters [i]; Parameter.Modifier mod = p.ModFlags; @@ -919,7 +906,7 @@ namespace Mono.CSharp { return; } - if ((mod & Parameter.Modifier.ARGLIST) != 0) { + if (p is ArglistParameter) { Report.Error (1636, method.Location, "__arglist is not allowed in parameter list of iterators"); return; @@ -967,13 +954,13 @@ namespace Mono.CSharp { Type gt = TypeManager.DropGenericTypeArguments (ret); if (gt == TypeManager.generic_ienumerable_type) { - original_iterator_type = args [0]; + original_iterator_type = TypeManager.TypeToCoreType (args [0]); is_enumerable = true; return true; } if (gt == TypeManager.generic_ienumerator_type) { - original_iterator_type = args [0]; + original_iterator_type = TypeManager.TypeToCoreType (args [0]); is_enumerable = false; return true; }