- protected class GetEnumeratorMethod : Method
- {
- public IteratorStorey Host;
-
- static MemberName GetMemberName (IteratorStorey host, bool is_generic)
- {
- MemberName left;
- if (is_generic) {
- left = new MemberName (
- "System.Collections.Generic.IEnumerable",
- host.generic_args, host.Location);
- } else {
- left = new MemberName (
- "System.Collections.IEnumerable", host.Location);
- }
-
- return new MemberName (left, "GetEnumerator", host.Location);
- }
-
- public GetEnumeratorMethod (IteratorStorey host, bool is_generic)
- : base (host, null, is_generic ?
- host.generic_enumerator_type : host.enumerator_type,
- Modifiers.DEBUGGER_HIDDEN, false, GetMemberName (host, is_generic),
- Parameters.EmptyReadOnlyParameters, null)
- {
- this.Host = host;
-
- host.AddMethod (this);
-
- Block = new ToplevelBlock (host.Iterator.Container.Toplevel, null, Location);
- Block.AddStatement (new GetEnumeratorStatement (host, type_name));
- }
-
- public override EmitContext CreateEmitContext (DeclSpace tc, ILGenerator ig)
- {
- EmitContext ec = new EmitContext (
- this, tc, this.ds, Location, ig, MemberType, ModFlags, false);
-
- ec.CurrentAnonymousMethod = Host.Iterator;
- return ec;
- }
-
- protected class GetEnumeratorStatement : Statement
- {
- IteratorStorey host;
- Expression type;
-
- Expression cast;
-
- public GetEnumeratorStatement (IteratorStorey host, Expression type)
- {
- this.host = host;
- this.type = type;
- loc = host.Location;
- }
-
- 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;
- if (host.hoisted_params != null) {
- ArrayList init = new ArrayList (host.HoistedParameters.Count);
- foreach (HoistedParameter hp in host.HoistedParameters) {
- FieldExpr from = new FieldExpr (hp.Field.FieldBuilder, loc);
- from.InstanceExpression = CompilerGeneratedThis.Instance;
- init.Add (new ElementInitializer (hp.Field.Name, from, loc));
- }
-
- new_storey = new NewInitialize (storey_type_expr, new ArrayList (0),
- new CollectionOrObjectInitializers (init, loc), loc);
- } else {
- new_storey = new New (storey_type_expr, new ArrayList (0), loc);
- }
-
- new_storey = new_storey.Resolve (ec);
- if (new_storey != null)
- cast = Convert.ImplicitConversionRequired (ec, new_storey, type.Type, loc);
-
- if (TypeManager.int_interlocked_compare_exchange == null) {
- Type t = TypeManager.CoreLookupType ("System.Threading", "Interlocked", Kind.Class, true);
- if (t != null) {
- TypeManager.int_interlocked_compare_exchange = TypeManager.GetPredefinedMethod (
- t, "CompareExchange", loc, TypeManager.GetReferenceType (TypeManager.int32_type),
- TypeManager.int32_type, TypeManager.int32_type);
- }
- }
-
- ec.CurrentBranching.CurrentUsageVector.Goto ();
- return true;
- }
-
- protected override void DoEmit (EmitContext ec)
- {
- ILGenerator ig = ec.ig;
- Label label_init = ig.DefineLabel ();
-
- 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);
- 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);
-
- ig.Emit (OpCodes.Ldarg_0);
- ig.Emit (OpCodes.Ret);
-
- ig.MarkLabel (label_init);