Merge pull request #2753 from xmcclure/checked-build-updates
[mono.git] / mcs / mcs / iterators.cs
index f10773009de7d715ecdd03b75f701cf871573441..df43ff38e8e09f0387a6810ad441a6d56c5d8457 100644 (file)
@@ -74,6 +74,9 @@ namespace Mono.CSharp
 
                public void RegisterResumePoint ()
                {
+                       if (resume_pc != 0)
+                               return;
+
                        if (inside_try_block == null) {
                                resume_pc = machine_initializer.AddResumePoint (this);
                        } else {
@@ -199,7 +202,6 @@ namespace Mono.CSharp
 
                Field pc_field;
                StateMachineMethod method;
-               int local_name_idx;
 
                protected StateMachine (ParametersBlock block, TypeDefinition parent, MemberBase host, TypeParameters tparams, string name, MemberKind kind)
                        : base (block, parent, host, tparams, name, kind)
@@ -241,12 +243,19 @@ namespace Mono.CSharp
                        return base.DoDefineMembers ();
                }
 
-               protected override string GetVariableMangledName (LocalVariable local_info)
+               protected override string GetVariableMangledName (ResolveContext rc, LocalVariable local_info)
                {
                        if (local_info.IsCompilerGenerated)
-                               return base.GetVariableMangledName (local_info);
+                               return base.GetVariableMangledName (rc, local_info);
 
-                       return "<" + local_info.Name + ">__" + local_name_idx++.ToString ("X");
+                       //
+                       // Special format which encodes original variable name and
+                       // it's scope to support lifted variables debugging. This
+                       // is same what csc does and allows to correctly set fields
+                       // scope information (like ambiguity, our of scope, etc).
+                       //
+                       var id = rc.CurrentBlock.Explicit.GetDebugSymbolScopeIndex ();
+                       return "<" + local_info.Name + ">__" + id;
                }
        }
 
@@ -723,8 +732,7 @@ namespace Mono.CSharp
                //
                // The state as we generate the machine
                //
-               Label move_next_ok;
-               Label iterator_body_end;
+               protected Label move_next_ok;
                protected Label move_next_error;
                LocalBuilder skip_finally;
                protected LocalBuilder current_pc;
@@ -738,11 +746,7 @@ namespace Mono.CSharp
 
                #region Properties
 
-               public Label BodyEnd {
-                       get {
-                               return iterator_body_end;
-                       }
-               }
+               public Label BodyEnd { get; set; }
 
                public LocalBuilder CurrentPC
                {
@@ -830,11 +834,18 @@ namespace Mono.CSharp
                        // We only care if the PC is zero (start executing) or non-zero (don't do anything)
                        ec.Emit (OpCodes.Brtrue, move_next_error);
 
-                       iterator_body_end = ec.DefineLabel ();
+                       BodyEnd = ec.DefineLabel ();
+
+                       var async_init = this as AsyncInitializer;
+                       if (async_init != null)
+                               ec.BeginExceptionBlock ();
 
                        block.EmitEmbedded (ec);
 
-                       ec.MarkLabel (iterator_body_end);
+                       if (async_init != null)
+                               async_init.EmitCatchBlock (ec);
+
+                       ec.MarkLabel (BodyEnd);
 
                        EmitMoveNextEpilogue (ec);
 
@@ -844,6 +855,8 @@ namespace Mono.CSharp
                                ec.EmitInt (0);
                                ec.Emit (OpCodes.Ret);
                        }
+
+                       ec.MarkLabel (move_next_ok);
                }
 
                void EmitMoveNext (EmitContext ec)
@@ -893,26 +906,14 @@ namespace Mono.CSharp
 
                        ec.MarkLabel (labels[0]);
 
-                       iterator_body_end = ec.DefineLabel ();
+                       BodyEnd = ec.DefineLabel ();
 
                        block.EmitEmbedded (ec);
 
-                       ec.MarkLabel (iterator_body_end);
+                       ec.MarkLabel (BodyEnd);
 
                        if (async_init != null) {
-                               var catch_value = LocalVariable.CreateCompilerGenerated (ec.Module.Compiler.BuiltinTypes.Exception, block, Location);
-
-                               ec.BeginCatchBlock (catch_value.Type);
-                               catch_value.EmitAssign (ec);
-
-                               ec.EmitThis ();
-                               ec.EmitInt ((int) IteratorStorey.State.After);
-                               ec.Emit (OpCodes.Stfld, storey.PC.Spec);
-
-                               ((AsyncTaskStorey) async_init.Storey).EmitSetException (ec, new LocalVariableReference (catch_value, Location));
-
-                               ec.Emit (OpCodes.Leave, move_next_ok);
-                               ec.EndExceptionBlock ();
+                               async_init.EmitCatchBlock (ec);
                        }
 
                        ec.Mark (Block.Original.EndLocation);