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