Hey,

.NET's ILGenerator allows contructions such as:

il.Emit (OpCodes.Nop, local_builder);

We're currently translating that into a ldloc, while .net actually
emits the nop. The attached patch fixes this.

Please review, thanks.

-- 
Jb Evain  <j...@nurv.fr>
Index: System.Reflection.Emit/ILGenerator.cs
===================================================================
--- System.Reflection.Emit/ILGenerator.cs	(revision 147779)
+++ System.Reflection.Emit/ILGenerator.cs	(working copy)
@@ -659,21 +659,22 @@
 		{
 			if (local == null)
 				throw new ArgumentNullException ("local");
+			if (local.ilgen != this)
+				throw new ArgumentException ("Trying to emit a local from a different ILGenerator.");
 
 			uint pos = local.position;
 			bool load_addr = false;
 			bool is_store = false;
+			bool is_load = false;
 			make_room (6);
 
-			if (local.ilgen != this)
-				throw new ArgumentException ("Trying to emit a local from a different ILGenerator.");
-
 			/* inline the code from ll_emit () to optimize il code size */
 			if (opcode.StackBehaviourPop == StackBehaviour.Pop1) {
 				cur_stack --;
 				is_store = true;
-			} else {
+			} else if (opcode.StackBehaviourPush == StackBehaviour.Push1 || opcode.StackBehaviourPush == StackBehaviour.Pushi) {
 				cur_stack++;
+				is_load = true;
 				if (cur_stack > max_stack)
 					max_stack = cur_stack;
 				load_addr = opcode.StackBehaviourPush == StackBehaviour.Pushi;
@@ -701,7 +702,7 @@
 						code [code_len++] = (byte)(pos & 0xff);
 						code [code_len++] = (byte)((pos >> 8) & 0xff);
 					}
-				} else {
+				} else if (is_load) {
 					if (pos < 4) {
 						code [code_len++] = (byte)(0x06 + pos);
 					} else if (pos < 256) {
@@ -713,6 +714,8 @@
 						code [code_len++] = (byte)(pos & 0xff);
 						code [code_len++] = (byte)((pos >> 8) & 0xff);
 					}
+				} else {
+					ll_emit (opcode);
 				}
 			}
 		}
Index: Test/System.Reflection.Emit/ILGeneratorTest.cs
===================================================================
--- Test/System.Reflection.Emit/ILGeneratorTest.cs	(revision 147779)
+++ Test/System.Reflection.Emit/ILGeneratorTest.cs	(working copy)
@@ -426,5 +426,23 @@
 				throw tie.InnerException;
 			}
 		}
+
+		[Test]
+		public void TestEmitLocalInfoWithNopOpCode ()
+		{
+			var method_builder = tb.DefineMethod ("linop", MethodAttributes.Public | MethodAttributes.Static, typeof (bool), Type.EmptyTypes);
+			il_gen = method_builder.GetILGenerator ();
+
+			var local = il_gen.DeclareLocal (typeof (int));
+			il_gen.Emit (OpCodes.Nop, local);
+			il_gen.Emit (OpCodes.Ldc_I4_1);
+			il_gen.Emit (OpCodes.Ret);
+
+			var type = tb.CreateType ();
+			var method = type.GetMethod ("linop");
+
+			Assert.IsNotNull (method);
+			Assert.IsTrue ((bool) method.Invoke (null, new object [0]));
+		}
 	}
 }
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to