title: Array bounds check in DynamicAssembly only works when evaluation stack is empty
body: <p>I've got simple for loop with array access written using ILGenerator. When method is created with this exact code, I open disassembly and it's ok, no array bounds check.</p>
  
  <p>But when I first put instance of other class on evaluation stack, then run for loop, it does array bounds check. I'm running on release.</p>
  
  <p>Any idea why? I've already read blog post about array bound checks: <a href="http://blogs.msdn.com/b/clrcodegeneration/archive/2009/08/13/array-bounds-check-elimination-in-the-clr.aspx" rel="nofollow">http://blogs.msdn.com/b/clrcodegeneration/archive/2009/08/13/array-bounds-check-elimination-in-the-clr.aspx</a></p>
  
  <pre><code>        // Uncomment this to enable bound checks, type of arg0 is some my class
          //il.Emit(OpCodes.Ldarg_0);
  
          var startLbl = il.DefineLabel();
          var testLbl = il.DefineLabel();
          var index = il.DeclareLocal(typeof(Int32));
          var arr = il.DeclareLocal(typeof(Int32).MakeArrayType());
  
          // arr = new int[4];
          il.Emit(OpCodes.Ldc_I4_4);
          il.Emit(OpCodes.Newarr, typeof(Int32));
          il.Emit(OpCodes.Stloc, arr);
  
          // Index = 0
          il.Emit(OpCodes.Ldc_I4_0); // Push index
          il.Emit(OpCodes.Stloc, index); // Pop index, store
  
          il.Emit(OpCodes.Br_S, testLbl); // Go to test
  
          // Begin for
          il.MarkLabel(startLbl);
  
          // Load array, index
          il.Emit(OpCodes.Ldloc, arr);
          il.Emit(OpCodes.Ldloc, index);
  
          // Now on stack: array, index
          // Load element
          il.Emit(OpCodes.Ldelem_I4);
          // Nothing here now, later some function call
          il.Emit(OpCodes.Pop);
  
          // Index++
          il.Emit(OpCodes.Ldloc, index);
          il.Emit(OpCodes.Ldc_I4_1);
          il.Emit(OpCodes.Add);
          il.Emit(OpCodes.Stloc, index);
  
          il.MarkLabel(testLbl);
          // Load index, count, test for end
          il.Emit(OpCodes.Ldloc, index);
          il.Emit(OpCodes.Ldloc, arr);
          il.Emit(OpCodes.Ldlen); // Push len
          il.Emit(OpCodes.Conv_I4); // Push len
          il.Emit(OpCodes.Blt_S, startLbl);
          // End for
  
          // Remove instance added on top
          //il.Emit(OpCodes.Pop);
  </code></pre>
  
  <p>As I generate IL code, is better to keep instances of classes on evaluation stack or in local variables? </p>
  
  <p>E.g. I get instance, go through fields, for each field do anything and than return. I've just kept instance on stack and called Emit(OpCodes.Dup) before reading next field. But it seems wrong (at least for case mentioned above).</p>
  
  <p>Any articles/blog posts about generating (efficient/well-formed) IL code appreciated.</p>