From 02b968315037a5a8a9d291ba4d065e70118f1661 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Thu, 5 Oct 2023 22:07:23 -0700 Subject: [PATCH 01/11] Add initial MaxStack calculation and tests --- .../System/Reflection/Emit/ILGeneratorImpl.cs | 126 ++++++++++++------ .../AssemblySaveILGeneratorTests.cs | 78 ++++++++++- 2 files changed, 160 insertions(+), 44 deletions(-) diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs index 7b61112ec8bf7a..d9cd6138e6abf5 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs @@ -1,10 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Buffers.Binary; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace System.Reflection.Emit @@ -17,6 +15,7 @@ internal sealed class ILGeneratorImpl : ILGenerator private readonly InstructionEncoder _il; private bool _hasDynamicStackAllocation; private int _maxStackSize; + private int _currentStack; internal ILGeneratorImpl(MethodBuilder methodBuilder, int size) { @@ -42,40 +41,88 @@ internal ILGeneratorImpl(MethodBuilder methodBuilder, int size) public override LocalBuilder DeclareLocal(Type localType, bool pinned) => throw new NotImplementedException(); public override Label DefineLabel() => throw new NotImplementedException(); - public override void Emit(OpCode opcode) + private static int GetStackChangeFor(StackBehaviour stackBehaviour) => + stackBehaviour switch + { + StackBehaviour.Pop0 or + StackBehaviour.Push0 => 0, + StackBehaviour.Pop1 or + StackBehaviour.Popi or + StackBehaviour.Popref or + StackBehaviour.Varpop => -1, + StackBehaviour.Pop1_pop1 or + StackBehaviour.Popi_pop1 or + StackBehaviour.Popi_popi or + StackBehaviour.Popi_popi8 or + StackBehaviour.Popi_popr4 or + StackBehaviour.Popi_popr8 or + StackBehaviour.Popref_pop1 or + StackBehaviour.Popref_popi => -2, + StackBehaviour.Popi_popi_popi or + StackBehaviour.Popref_popi_pop1 or + StackBehaviour.Popref_popi_popi or + StackBehaviour.Popref_popi_popi8 or + StackBehaviour.Popref_popi_popr4 or + StackBehaviour.Popref_popi_popr8 or + StackBehaviour.Popref_popi_popref => -3, + StackBehaviour.Push1 or + StackBehaviour.Pushi or + StackBehaviour.Pushi8 or + StackBehaviour.Pushr4 or + StackBehaviour.Pushr8 or + StackBehaviour.Pushref or + StackBehaviour.Varpush => 1, + StackBehaviour.Push1_push1 => 2, + _ => throw new InvalidOperationException() + }; + + private void UpdateStackSize(OpCode opCode) + { + _currentStack += GetStackChangeFor(opCode.StackBehaviourPush) + GetStackChangeFor(opCode.StackBehaviourPop); + + if (_currentStack > _maxStackSize) + { + _maxStackSize = _currentStack; + } + } + + public void EmitOpcode(OpCode opcode) { if (opcode == OpCodes.Localloc) { _hasDynamicStackAllocation = true; } + _il.OpCode((ILOpCode)opcode.Value); + UpdateStackSize(opcode); + } - // TODO: for now only count the Opcodes emitted, in order to calculate it correctly we might need to make internal Opcode APIs public - // https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs#L48 - _maxStackSize++; + public override void Emit(OpCode opcode) + { + EmitOpcode(opcode); } public override void Emit(OpCode opcode, byte arg) { - _il.OpCode((ILOpCode)opcode.Value); + EmitOpcode(opcode); _builder.WriteByte(arg); } public override void Emit(OpCode opcode, double arg) { - _il.OpCode((ILOpCode)opcode.Value); + EmitOpcode(opcode); _builder.WriteDouble(arg); } public override void Emit(OpCode opcode, float arg) { - _il.OpCode((ILOpCode)opcode.Value); + EmitOpcode(opcode); _builder.WriteSingle(arg); } public override void Emit(OpCode opcode, short arg) { - _il.OpCode((ILOpCode)opcode.Value); + EmitOpcode(opcode); _builder.WriteInt16(arg); } @@ -86,26 +133,25 @@ public override void Emit(OpCode opcode, int arg) { if (arg >= -1 && arg <= 8) { - _il.OpCode(arg switch + EmitOpcode(arg switch { - -1 => ILOpCode.Ldc_i4_m1, - 0 => ILOpCode.Ldc_i4_0, - 1 => ILOpCode.Ldc_i4_1, - 2 => ILOpCode.Ldc_i4_2, - 3 => ILOpCode.Ldc_i4_3, - 4 => ILOpCode.Ldc_i4_4, - 5 => ILOpCode.Ldc_i4_5, - 6 => ILOpCode.Ldc_i4_6, - 7 => ILOpCode.Ldc_i4_7, - _ => ILOpCode.Ldc_i4_8, + -1 => OpCodes.Ldc_I4_M1, + 0 => OpCodes.Ldc_I4_0, + 1 => OpCodes.Ldc_I4_1, + 2 => OpCodes.Ldc_I4_2, + 3 => OpCodes.Ldc_I4_3, + 4 => OpCodes.Ldc_I4_4, + 5 => OpCodes.Ldc_I4_5, + 6 => OpCodes.Ldc_I4_6, + 7 => OpCodes.Ldc_I4_7, + _ => OpCodes.Ldc_I4_8 }); return; } if (arg >= -128 && arg <= 127) { - _il.OpCode(ILOpCode.Ldc_i4_s); - _builder.WriteSByte((sbyte)arg) ; + Emit(OpCodes.Ldc_I4_S, (sbyte)arg); return; } } @@ -113,27 +159,25 @@ public override void Emit(OpCode opcode, int arg) { if ((uint)arg <= 3) { - _il.OpCode(arg switch + EmitOpcode(arg switch { - 0 => ILOpCode.Ldarg_0, - 1 => ILOpCode.Ldarg_1, - 2 => ILOpCode.Ldarg_2, - _ => ILOpCode.Ldarg_3, + 0 => OpCodes.Ldarg_0, + 1 => OpCodes.Ldarg_1, + 2 => OpCodes.Ldarg_2, + _ => OpCodes.Ldarg_3, }); return; } if ((uint)arg <= byte.MaxValue) { - _il.OpCode(ILOpCode.Ldarg_s); - _builder.WriteByte((byte)arg); + Emit(OpCodes.Ldarg_S, (byte)arg); return; } if ((uint)arg <= ushort.MaxValue) // this will be true except on misuse of the opcode { - _il.OpCode(ILOpCode.Ldarg); - _builder.WriteInt16((short)arg); + Emit(OpCodes.Ldarg, (short)arg); return; } } @@ -141,15 +185,13 @@ public override void Emit(OpCode opcode, int arg) { if ((uint)arg <= byte.MaxValue) { - _il.OpCode(ILOpCode.Ldarga_s); - _builder.WriteByte((byte)arg); + Emit(OpCodes.Ldarga_S, (byte)arg); return; } if ((uint)arg <= ushort.MaxValue) // this will be true except on misuse of the opcode { - _il.OpCode(ILOpCode.Ldarga); - _builder.WriteInt16((short)arg); + Emit(OpCodes.Ldarga, (short)arg); return; } } @@ -157,27 +199,25 @@ public override void Emit(OpCode opcode, int arg) { if ((uint)arg <= byte.MaxValue) { - _il.OpCode(ILOpCode.Starg_s); - _builder.WriteByte((byte)arg); + Emit(OpCodes.Starg_S, (byte)arg); return; } if ((uint)arg <= ushort.MaxValue) // this will be true except on misuse of the opcode { - _il.OpCode(ILOpCode.Starg); - _builder.WriteInt16((short)arg); + Emit(OpCodes.Starg, (short)arg); return; } } // For everything else, put the opcode followed by the arg onto the stream of instructions. - _il.OpCode((ILOpCode)opcode.Value); + EmitOpcode(opcode); _builder.WriteInt32(arg); } public override void Emit(OpCode opcode, long arg) { - _il.OpCode((ILOpCode)opcode.Value); + EmitOpcode(opcode); _il.CodeBuilder.WriteInt64(arg); } @@ -187,7 +227,7 @@ public override void Emit(OpCode opcode, string str) // represented by str. ModuleBuilder modBuilder = (ModuleBuilder)_methodBuilder.Module; int tempVal = modBuilder.GetStringMetadataToken(str); - _il.OpCode((ILOpCode)opcode.Value); + EmitOpcode(opcode); _il.Token(tempVal); } diff --git a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveILGeneratorTests.cs b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveILGeneratorTests.cs index 2f4dde63b79fb8..e9d1560991ab9c 100644 --- a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveILGeneratorTests.cs +++ b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveILGeneratorTests.cs @@ -168,5 +168,81 @@ public void MultipleTypesWithMultipleMethods() Assert.Equal(OpCodes.Ldc_I8.Value, longBody[0]); } } + + [Fact] + public void ILOffset_Test() + { + AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod); + MethodBuilder method = type.DefineMethod("Method1", MethodAttributes.Public | MethodAttributes.Static, typeof(Type), new Type[0]); + ILGenerator ilGenerator = method.GetILGenerator(); + + Assert.Equal(0, ilGenerator.ILOffset); + ilGenerator.Emit(OpCodes.Ret); + Assert.Equal(1, ilGenerator.ILOffset); + } + + [Fact] + public void ILMaxStack_Test() + { + using (TempFile file = TempFile.Create()) + { + AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod); + MethodBuilder method1 = type.DefineMethod("Method1", MethodAttributes.Public, typeof(long), new Type[] { typeof(int), typeof(long), typeof(short), typeof(byte) }); + ILGenerator il1 = method1.GetILGenerator(); + + // public int Method1(int x, int y, short z, byte r) => + // x + (z + 2 * (r + (8 * y + 3 * (y - (5 + x)))) + il1.Emit(OpCodes.Ldarg_1); // push 1 MaxStack 1 + il1.Emit(OpCodes.Ldarg_3); // push 1 MaxStack 2 + il1.Emit(OpCodes.Ldc_I4_2); // push 1 MaxStack 3 + il1.Emit(OpCodes.Ldarg_S, 4); // push 1 MaxStack 4 + il1.Emit(OpCodes.Ldc_I4_8); // push 1 MaxStack 5 + il1.Emit(OpCodes.Ldarg_2); // push 1 MaxStack 6 + il1.Emit(OpCodes.Mul); // pop 2 push 1 MaxStack 5 + il1.Emit(OpCodes.Ldc_I4_3); // push 1 MaxStack 6 + il1.Emit(OpCodes.Ldarg_2); // push 1 MaxStack 7 + il1.Emit(OpCodes.Ldc_I4_5); // push 1 MaxStack 8 + il1.Emit(OpCodes.Ldarg_1); // push 1 MaxStack 9 + il1.Emit(OpCodes.Add); // pop 2 push 1 stack size 8 + il1.Emit(OpCodes.Sub); // pop 2 push 1 stack size 7 + il1.Emit(OpCodes.Mul); // pop 2 push 1 stack size 6 + il1.Emit(OpCodes.Add); // pop 2 push 1 stack size 5 + il1.Emit(OpCodes.Add); // pop 2 push 1 stack size 4 + il1.Emit(OpCodes.Mul); // pop 2 push 1 stack size 3 + il1.Emit(OpCodes.Add); // pop 2 push 1 stack size 2 + il1.Emit(OpCodes.Add); // pop 2 push 1 stack size 1 + il1.Emit(OpCodes.Ret); // pop 1 stack size 0 + + MethodBuilder method2 = type.DefineMethod("Method2", MethodAttributes.Public, typeof(int), new Type[] { typeof(int), typeof(byte) }); + ILGenerator il2 = method2.GetILGenerator(); + + // int Method2(int x, int y) => x + (y + 18); + il2.Emit(OpCodes.Ldarg_1); // push 1 MaxStack 1 + il2.Emit(OpCodes.Ldarg_2); // push 1 MaxStack 2 + il2.Emit(OpCodes.Ldc_I4_S, 8); // push 1 MaxStack 3 + il2.Emit(OpCodes.Add); // pop 2 push 1 stack size 2 + il2.Emit(OpCodes.Add); // pop 2 push 1 stack size 1 + il2.Emit(OpCodes.Ret); // pop 1 stack size 0 + + saveMethod.Invoke(ab, new object[] { file.Path }); + + MethodInfo getMaxStackSizeMethod = LoadILGenerator_GetMaxStackSizeMethod(); + Assert.Equal(9, getMaxStackSizeMethod.Invoke(il1, new object[0])); + Assert.Equal(3, getMaxStackSizeMethod.Invoke(il2, new object[0])); + + Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path); + Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType"); + MethodBody body1 = typeFromDisk.GetMethod("Method1").GetMethodBody(); + MethodBody body2 = typeFromDisk.GetMethod("Method2").GetMethodBody(); + Assert.Equal(9, body1.MaxStackSize); + Assert.Equal(8, body2.MaxStackSize); // apparently doesn't write lower than 8 + } + } + + private MethodInfo LoadILGenerator_GetMaxStackSizeMethod() + { + Type ilgType = Type.GetType("System.Reflection.Emit.ILGeneratorImpl, System.Reflection.Emit", throwOnError: true)!; + return ilgType.GetMethod("GetMaxStackSize", BindingFlags.NonPublic | BindingFlags.Instance, Type.EmptyTypes); + } } -} +} From 49c69adba3180b4969d64f24631ad58d09ba1c35 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Mon, 9 Oct 2023 11:23:23 -0700 Subject: [PATCH 02/11] Apply suggestions from code review Co-authored-by: Aaron Robinson --- .../System/Reflection/Emit/ILGeneratorImpl.cs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs index d9cd6138e6abf5..b33c37f914c285 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs @@ -46,10 +46,10 @@ private static int GetStackChangeFor(StackBehaviour stackBehaviour) => { StackBehaviour.Pop0 or StackBehaviour.Push0 => 0, - StackBehaviour.Pop1 or - StackBehaviour.Popi or - StackBehaviour.Popref or - StackBehaviour.Varpop => -1, + StackBehaviour.Pop1 + or StackBehaviour.Popi + or StackBehaviour.Popref + or StackBehaviour.Varpop => -1, StackBehaviour.Pop1_pop1 or StackBehaviour.Popi_pop1 or StackBehaviour.Popi_popi or @@ -80,10 +80,7 @@ private void UpdateStackSize(OpCode opCode) { _currentStack += GetStackChangeFor(opCode.StackBehaviourPush) + GetStackChangeFor(opCode.StackBehaviourPop); - if (_currentStack > _maxStackSize) - { - _maxStackSize = _currentStack; - } + _maxStackSize = Math.Max(_maxStackSize, _currentStack); } public void EmitOpcode(OpCode opcode) @@ -97,10 +94,7 @@ public void EmitOpcode(OpCode opcode) UpdateStackSize(opcode); } - public override void Emit(OpCode opcode) - { - EmitOpcode(opcode); - } + public override void Emit(OpCode opcode) => EmitOpcode(opcode); public override void Emit(OpCode opcode, byte arg) { From 06be81da2da780eb96bc7999653bfed01ecf8225 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Mon, 9 Oct 2023 13:43:48 -0700 Subject: [PATCH 03/11] Update src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs Co-authored-by: Aaron Robinson --- .../System/Reflection/Emit/ILGeneratorImpl.cs | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs index b33c37f914c285..d1d4b8490e879e 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs @@ -44,34 +44,34 @@ internal ILGeneratorImpl(MethodBuilder methodBuilder, int size) private static int GetStackChangeFor(StackBehaviour stackBehaviour) => stackBehaviour switch { - StackBehaviour.Pop0 or - StackBehaviour.Push0 => 0, + StackBehaviour.Pop0 + or StackBehaviour.Push0 => 0, StackBehaviour.Pop1 or StackBehaviour.Popi or StackBehaviour.Popref or StackBehaviour.Varpop => -1, - StackBehaviour.Pop1_pop1 or - StackBehaviour.Popi_pop1 or - StackBehaviour.Popi_popi or - StackBehaviour.Popi_popi8 or - StackBehaviour.Popi_popr4 or - StackBehaviour.Popi_popr8 or - StackBehaviour.Popref_pop1 or - StackBehaviour.Popref_popi => -2, - StackBehaviour.Popi_popi_popi or - StackBehaviour.Popref_popi_pop1 or - StackBehaviour.Popref_popi_popi or - StackBehaviour.Popref_popi_popi8 or - StackBehaviour.Popref_popi_popr4 or - StackBehaviour.Popref_popi_popr8 or - StackBehaviour.Popref_popi_popref => -3, - StackBehaviour.Push1 or - StackBehaviour.Pushi or - StackBehaviour.Pushi8 or - StackBehaviour.Pushr4 or - StackBehaviour.Pushr8 or - StackBehaviour.Pushref or - StackBehaviour.Varpush => 1, + StackBehaviour.Pop1_pop1 + or StackBehaviour.Popi_pop1 + or StackBehaviour.Popi_popi + or StackBehaviour.Popi_popi8 + or StackBehaviour.Popi_popr4 + or StackBehaviour.Popi_popr8 + or StackBehaviour.Popref_pop1 + or StackBehaviour.Popref_popi => -2, + StackBehaviour.Popi_popi_popi + or StackBehaviour.Popref_popi_pop1 + or StackBehaviour.Popref_popi_popi + or StackBehaviour.Popref_popi_popi8 + or StackBehaviour.Popref_popi_popr4 + or StackBehaviour.Popref_popi_popr8 + or StackBehaviour.Popref_popi_popref => -3, + StackBehaviour.Push1 + or StackBehaviour.Pushi + or StackBehaviour.Pushi8 + or StackBehaviour.Pushr4 + or StackBehaviour.Pushr8 + or StackBehaviour.Pushref + or StackBehaviour.Varpush => 1, StackBehaviour.Push1_push1 => 2, _ => throw new InvalidOperationException() }; From 90cdba858b3bbfedc7ba768a2c9c7e2334bad987 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Mon, 9 Oct 2023 13:44:53 -0700 Subject: [PATCH 04/11] Remove space --- .../PersistableAssemblyBuilder/AssemblySaveILGeneratorTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveILGeneratorTests.cs b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveILGeneratorTests.cs index e9d1560991ab9c..97ec018b0e7f4d 100644 --- a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveILGeneratorTests.cs +++ b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveILGeneratorTests.cs @@ -245,4 +245,4 @@ private MethodInfo LoadILGenerator_GetMaxStackSizeMethod() return ilgType.GetMethod("GetMaxStackSize", BindingFlags.NonPublic | BindingFlags.Instance, Type.EmptyTypes); } } -} +} From f94e244871c6e651eb98a1215508178320002d9e Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Tue, 10 Oct 2023 09:31:46 -0700 Subject: [PATCH 05/11] Add new line between each switch case groups --- .../src/System/Reflection/Emit/ILGeneratorImpl.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs index d1d4b8490e879e..0c79df25f23fff 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs @@ -46,10 +46,12 @@ private static int GetStackChangeFor(StackBehaviour stackBehaviour) => { StackBehaviour.Pop0 or StackBehaviour.Push0 => 0, + StackBehaviour.Pop1 or StackBehaviour.Popi or StackBehaviour.Popref or StackBehaviour.Varpop => -1, + StackBehaviour.Pop1_pop1 or StackBehaviour.Popi_pop1 or StackBehaviour.Popi_popi @@ -58,6 +60,7 @@ or StackBehaviour.Popi_popr4 or StackBehaviour.Popi_popr8 or StackBehaviour.Popref_pop1 or StackBehaviour.Popref_popi => -2, + StackBehaviour.Popi_popi_popi or StackBehaviour.Popref_popi_pop1 or StackBehaviour.Popref_popi_popi @@ -65,6 +68,7 @@ or StackBehaviour.Popref_popi_popi8 or StackBehaviour.Popref_popi_popr4 or StackBehaviour.Popref_popi_popr8 or StackBehaviour.Popref_popi_popref => -3, + StackBehaviour.Push1 or StackBehaviour.Pushi or StackBehaviour.Pushi8 @@ -72,7 +76,9 @@ or StackBehaviour.Pushr4 or StackBehaviour.Pushr8 or StackBehaviour.Pushref or StackBehaviour.Varpush => 1, + StackBehaviour.Push1_push1 => 2, + _ => throw new InvalidOperationException() }; From ee3be835d7adc41e2b9c16b9527b7097f5909df0 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Tue, 10 Oct 2023 11:46:37 -0700 Subject: [PATCH 06/11] Remove spaces --- .../src/System/Reflection/Emit/ILGeneratorImpl.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs index 0c79df25f23fff..c829841ca5693d 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs @@ -46,12 +46,12 @@ private static int GetStackChangeFor(StackBehaviour stackBehaviour) => { StackBehaviour.Pop0 or StackBehaviour.Push0 => 0, - + StackBehaviour.Pop1 or StackBehaviour.Popi or StackBehaviour.Popref or StackBehaviour.Varpop => -1, - + StackBehaviour.Pop1_pop1 or StackBehaviour.Popi_pop1 or StackBehaviour.Popi_popi @@ -60,7 +60,7 @@ or StackBehaviour.Popi_popr4 or StackBehaviour.Popi_popr8 or StackBehaviour.Popref_pop1 or StackBehaviour.Popref_popi => -2, - + StackBehaviour.Popi_popi_popi or StackBehaviour.Popref_popi_pop1 or StackBehaviour.Popref_popi_popi @@ -68,7 +68,7 @@ or StackBehaviour.Popref_popi_popi8 or StackBehaviour.Popref_popi_popr4 or StackBehaviour.Popref_popi_popr8 or StackBehaviour.Popref_popi_popref => -3, - + StackBehaviour.Push1 or StackBehaviour.Pushi or StackBehaviour.Pushi8 @@ -76,9 +76,9 @@ or StackBehaviour.Pushr4 or StackBehaviour.Pushr8 or StackBehaviour.Pushref or StackBehaviour.Varpush => 1, - + StackBehaviour.Push1_push1 => 2, - + _ => throw new InvalidOperationException() }; From ae7f502dc38fab5d4373911852d871bacf7025a2 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Thu, 12 Oct 2023 15:05:59 -0700 Subject: [PATCH 07/11] Make OpCode.StackChange() public and use the method --- .../Reflection/Emit/RuntimeILGenerator.cs | 2 +- .../src/System/Reflection/Emit/Opcode.cs | 2 +- .../System/Reflection/Emit/ILGeneratorImpl.cs | 44 +------------------ .../ref/System.Reflection.Primitives.cs | 1 + 4 files changed, 4 insertions(+), 45 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeILGenerator.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeILGenerator.cs index 6cf211e713e383..2e58c7447e9ca2 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeILGenerator.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeILGenerator.cs @@ -128,7 +128,7 @@ internal void InternalEmit(OpCode opcode) m_ILStream[m_length++] = (byte)opcodeValue; } - UpdateStackSize(opcode, opcode.StackChange()); + UpdateStackSize(opcode, opcode.StackDifference()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs index e9fdc1ec38c9ad..72342fc27e61a9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs @@ -45,7 +45,7 @@ internal OpCode(OpCodeValues value, int flags) internal bool EndsUncondJmpBlk() => (m_flags & EndsUncondJmpBlkFlag) != 0; - internal int StackChange() => + public int StackDifference() => m_flags >> StackChangeShift; public OperandType OperandType => (OperandType)(m_flags & OperandTypeMask); diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs index c829841ca5693d..bbb41113d27334 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs @@ -41,51 +41,9 @@ internal ILGeneratorImpl(MethodBuilder methodBuilder, int size) public override LocalBuilder DeclareLocal(Type localType, bool pinned) => throw new NotImplementedException(); public override Label DefineLabel() => throw new NotImplementedException(); - private static int GetStackChangeFor(StackBehaviour stackBehaviour) => - stackBehaviour switch - { - StackBehaviour.Pop0 - or StackBehaviour.Push0 => 0, - - StackBehaviour.Pop1 - or StackBehaviour.Popi - or StackBehaviour.Popref - or StackBehaviour.Varpop => -1, - - StackBehaviour.Pop1_pop1 - or StackBehaviour.Popi_pop1 - or StackBehaviour.Popi_popi - or StackBehaviour.Popi_popi8 - or StackBehaviour.Popi_popr4 - or StackBehaviour.Popi_popr8 - or StackBehaviour.Popref_pop1 - or StackBehaviour.Popref_popi => -2, - - StackBehaviour.Popi_popi_popi - or StackBehaviour.Popref_popi_pop1 - or StackBehaviour.Popref_popi_popi - or StackBehaviour.Popref_popi_popi8 - or StackBehaviour.Popref_popi_popr4 - or StackBehaviour.Popref_popi_popr8 - or StackBehaviour.Popref_popi_popref => -3, - - StackBehaviour.Push1 - or StackBehaviour.Pushi - or StackBehaviour.Pushi8 - or StackBehaviour.Pushr4 - or StackBehaviour.Pushr8 - or StackBehaviour.Pushref - or StackBehaviour.Varpush => 1, - - StackBehaviour.Push1_push1 => 2, - - _ => throw new InvalidOperationException() - }; - private void UpdateStackSize(OpCode opCode) { - _currentStack += GetStackChangeFor(opCode.StackBehaviourPush) + GetStackChangeFor(opCode.StackBehaviourPop); - + _currentStack += opCode.StackDifference(); _maxStackSize = Math.Max(_maxStackSize, _currentStack); } diff --git a/src/libraries/System.Reflection.Primitives/ref/System.Reflection.Primitives.cs b/src/libraries/System.Reflection.Primitives/ref/System.Reflection.Primitives.cs index 2bd85772fef7bf..d8c0a9de6d6743 100644 --- a/src/libraries/System.Reflection.Primitives/ref/System.Reflection.Primitives.cs +++ b/src/libraries/System.Reflection.Primitives/ref/System.Reflection.Primitives.cs @@ -33,6 +33,7 @@ public enum FlowControl public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public bool Equals(System.Reflection.Emit.OpCode obj) { throw null; } public override int GetHashCode() { throw null; } + public int StackDifference() { throw null; } public static bool operator ==(System.Reflection.Emit.OpCode a, System.Reflection.Emit.OpCode b) { throw null; } public static bool operator !=(System.Reflection.Emit.OpCode a, System.Reflection.Emit.OpCode b) { throw null; } public override string? ToString() { throw null; } From b38d18c6eb683421a866ce9465830e346ac5a18a Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Tue, 24 Oct 2023 11:12:16 -0700 Subject: [PATCH 08/11] Apply the approved API shape --- .../src/System/Reflection/Emit/RuntimeILGenerator.cs | 2 +- .../System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs | 2 +- .../src/System/Reflection/Emit/ILGeneratorImpl.cs | 2 +- .../ref/System.Reflection.Primitives.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeILGenerator.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeILGenerator.cs index 2e58c7447e9ca2..7bb7ee6beca98f 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeILGenerator.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeILGenerator.cs @@ -128,7 +128,7 @@ internal void InternalEmit(OpCode opcode) m_ILStream[m_length++] = (byte)opcodeValue; } - UpdateStackSize(opcode, opcode.StackDifference()); + UpdateStackSize(opcode, opcode.EvaluationStackDelta); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs index 72342fc27e61a9..f92c69b3a4dae7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs @@ -45,7 +45,7 @@ internal OpCode(OpCodeValues value, int flags) internal bool EndsUncondJmpBlk() => (m_flags & EndsUncondJmpBlkFlag) != 0; - public int StackDifference() => + public int EvaluationStackDelta => m_flags >> StackChangeShift; public OperandType OperandType => (OperandType)(m_flags & OperandTypeMask); diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs index bbb41113d27334..9e7b43844c1041 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs @@ -43,7 +43,7 @@ internal ILGeneratorImpl(MethodBuilder methodBuilder, int size) private void UpdateStackSize(OpCode opCode) { - _currentStack += opCode.StackDifference(); + _currentStack += opCode.EvaluationStackDelta; _maxStackSize = Math.Max(_maxStackSize, _currentStack); } diff --git a/src/libraries/System.Reflection.Primitives/ref/System.Reflection.Primitives.cs b/src/libraries/System.Reflection.Primitives/ref/System.Reflection.Primitives.cs index d8c0a9de6d6743..8547124fbf173d 100644 --- a/src/libraries/System.Reflection.Primitives/ref/System.Reflection.Primitives.cs +++ b/src/libraries/System.Reflection.Primitives/ref/System.Reflection.Primitives.cs @@ -33,7 +33,7 @@ public enum FlowControl public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public bool Equals(System.Reflection.Emit.OpCode obj) { throw null; } public override int GetHashCode() { throw null; } - public int StackDifference() { throw null; } + public int EvaluationStackDelta { get { throw null; } } public static bool operator ==(System.Reflection.Emit.OpCode a, System.Reflection.Emit.OpCode b) { throw null; } public static bool operator !=(System.Reflection.Emit.OpCode a, System.Reflection.Emit.OpCode b) { throw null; } public override string? ToString() { throw null; } From 9b284c366f6b9fcb96095f74661584a22525b69d Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Tue, 24 Oct 2023 14:35:42 -0700 Subject: [PATCH 09/11] Add doc, update the ref API ordering --- .../src/System/Reflection/Emit/Opcode.cs | 6 ++++++ .../ref/System.Reflection.Primitives.cs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs index f92c69b3a4dae7..ed1c23e936b6f2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs @@ -45,6 +45,12 @@ internal OpCode(OpCodeValues value, int flags) internal bool EndsUncondJmpBlk() => (m_flags & EndsUncondJmpBlkFlag) != 0; + /// + /// The value of how the IL instruction changes the evaluation stack. + /// + /// + /// The difference between how many elements are popped from the stack and how many are pushed onto the stack as a result of the IL instruction. + /// public int EvaluationStackDelta => m_flags >> StackChangeShift; diff --git a/src/libraries/System.Reflection.Primitives/ref/System.Reflection.Primitives.cs b/src/libraries/System.Reflection.Primitives/ref/System.Reflection.Primitives.cs index 8547124fbf173d..c5d2beb82b6ba8 100644 --- a/src/libraries/System.Reflection.Primitives/ref/System.Reflection.Primitives.cs +++ b/src/libraries/System.Reflection.Primitives/ref/System.Reflection.Primitives.cs @@ -22,6 +22,7 @@ public enum FlowControl public readonly partial struct OpCode : System.IEquatable { private readonly int _dummyPrimitive; + public int EvaluationStackDelta { get { throw null; } } public System.Reflection.Emit.FlowControl FlowControl { get { throw null; } } public string? Name { get { throw null; } } public System.Reflection.Emit.OpCodeType OpCodeType { get { throw null; } } @@ -33,7 +34,6 @@ public enum FlowControl public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public bool Equals(System.Reflection.Emit.OpCode obj) { throw null; } public override int GetHashCode() { throw null; } - public int EvaluationStackDelta { get { throw null; } } public static bool operator ==(System.Reflection.Emit.OpCode a, System.Reflection.Emit.OpCode b) { throw null; } public static bool operator !=(System.Reflection.Emit.OpCode a, System.Reflection.Emit.OpCode b) { throw null; } public override string? ToString() { throw null; } From a8f47940f29c0a9baf5d503aedfee5101692634a Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Tue, 24 Oct 2023 16:50:33 -0700 Subject: [PATCH 10/11] Add more doc info, add test --- .../src/System/Reflection/Emit/Opcode.cs | 2 + .../tests/OpCodesTests.cs | 455 +++++++++--------- 2 files changed, 230 insertions(+), 227 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs index ed1c23e936b6f2..ae780604cb1634 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs @@ -50,6 +50,8 @@ internal bool EndsUncondJmpBlk() => /// /// /// The difference between how many elements are popped from the stack and how many are pushed onto the stack as a result of the IL instruction. + /// For some IL instructions like this value is not fixed and depends on the called reference signature, for example if it is + /// calling a method, depends on the method signature (push count depends on the returning a value, pop count depends how many parameters passed). /// public int EvaluationStackDelta => m_flags >> StackChangeShift; diff --git a/src/libraries/System.Reflection.Emit/tests/OpCodesTests.cs b/src/libraries/System.Reflection.Emit/tests/OpCodesTests.cs index 064a572207ef19..ebea2df47ba6a8 100644 --- a/src/libraries/System.Reflection.Emit/tests/OpCodesTests.cs +++ b/src/libraries/System.Reflection.Emit/tests/OpCodesTests.cs @@ -11,237 +11,237 @@ public class OpCodesTests { public static IEnumerable TestData() { - yield return new object[] { OpCodes.Add, "add", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x58, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Add_Ovf, "add.ovf", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xd6, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Add_Ovf_Un, "add.ovf.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xd7, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.And, "and", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x5f, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Arglist, "arglist", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe00, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Beq, "beq", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x3b, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Beq_S, "beq.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x2e, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Bge, "bge", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x3c, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Bge_S, "bge.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x2f, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Bge_Un, "bge.un", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x41, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Bge_Un_S, "bge.un.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x34, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Bgt, "bgt", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x3d, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Bgt_S, "bgt.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x30, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Bgt_Un, "bgt.un", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x42, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Bgt_Un_S, "bgt.un.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x35, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Ble, "ble", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x3e, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Ble_S, "ble.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x31, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Ble_Un, "ble.un", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x43, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Ble_Un_S, "ble.un.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x36, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Blt, "blt", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x3f, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Blt_S, "blt.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x32, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Blt_Un, "blt.un", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x44, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Blt_Un_S, "blt.un.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x37, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Bne_Un, "bne.un", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x40, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Bne_Un_S, "bne.un.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x33, StackBehaviour.Pop1_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Box, "box", OpCodeType.Primitive, OperandType.InlineType, 1, 0x8c, StackBehaviour.Pop1, StackBehaviour.Pushref }; - yield return new object[] { OpCodes.Br, "br", OpCodeType.Primitive, OperandType.InlineBrTarget, 1, 0x38, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Br_S, "br.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x2b, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Break, "break", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x1, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Brfalse, "brfalse", OpCodeType.Primitive, OperandType.InlineBrTarget, 1, 0x39, StackBehaviour.Popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Brfalse_S, "brfalse.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x2c, StackBehaviour.Popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Brtrue, "brtrue", OpCodeType.Primitive, OperandType.InlineBrTarget, 1, 0x3a, StackBehaviour.Popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Brtrue_S, "brtrue.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x2d, StackBehaviour.Popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Call, "call", OpCodeType.Primitive, OperandType.InlineMethod, 1, 0x28, StackBehaviour.Varpop, StackBehaviour.Varpush }; - yield return new object[] { OpCodes.Calli, "calli", OpCodeType.Primitive, OperandType.InlineSig, 1, 0x29, StackBehaviour.Varpop, StackBehaviour.Varpush }; - yield return new object[] { OpCodes.Callvirt, "callvirt", OpCodeType.Objmodel, OperandType.InlineMethod, 1, 0x6f, StackBehaviour.Varpop, StackBehaviour.Varpush }; - yield return new object[] { OpCodes.Castclass, "castclass", OpCodeType.Objmodel, OperandType.InlineType, 1, 0x74, StackBehaviour.Popref, StackBehaviour.Pushref }; - yield return new object[] { OpCodes.Ceq, "ceq", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe01, StackBehaviour.Pop1_pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Cgt, "cgt", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe02, StackBehaviour.Pop1_pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Cgt_Un, "cgt.un", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe03, StackBehaviour.Pop1_pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ckfinite, "ckfinite", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xc3, StackBehaviour.Pop1, StackBehaviour.Pushr8 }; - yield return new object[] { OpCodes.Clt, "clt", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe04, StackBehaviour.Pop1_pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Clt_Un, "clt.un", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe05, StackBehaviour.Pop1_pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Constrained, "constrained.", OpCodeType.Prefix, OperandType.InlineType, 2, 0xfe16, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Conv_I, "conv.i", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xd3, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_I1, "conv.i1", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x67, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_I2, "conv.i2", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x68, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_I4, "conv.i4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x69, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_I8, "conv.i8", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x6a, StackBehaviour.Pop1, StackBehaviour.Pushi8 }; - yield return new object[] { OpCodes.Conv_Ovf_I, "conv.ovf.i", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xd4, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_Ovf_I_Un, "conv.ovf.i.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x8a, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_Ovf_I1, "conv.ovf.i1", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xb3, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_Ovf_I1_Un, "conv.ovf.i1.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x82, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_Ovf_I2, "conv.ovf.i2", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xb5, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_Ovf_I2_Un, "conv.ovf.i2.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x83, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_Ovf_I4, "conv.ovf.i4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xb7, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_Ovf_I4_Un, "conv.ovf.i4.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x84, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_Ovf_I8, "conv.ovf.i8", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xb9, StackBehaviour.Pop1, StackBehaviour.Pushi8 }; - yield return new object[] { OpCodes.Conv_Ovf_I8_Un, "conv.ovf.i8.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x85, StackBehaviour.Pop1, StackBehaviour.Pushi8 }; - yield return new object[] { OpCodes.Conv_Ovf_U, "conv.ovf.u", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xd5, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_Ovf_U_Un, "conv.ovf.u.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x8b, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_Ovf_U1, "conv.ovf.u1", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xb4, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_Ovf_U1_Un, "conv.ovf.u1.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x86, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_Ovf_U2, "conv.ovf.u2", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xb6, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_Ovf_U2_Un, "conv.ovf.u2.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x87, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_Ovf_U4, "conv.ovf.u4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xb8, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_Ovf_U4_Un, "conv.ovf.u4.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x88, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_Ovf_U8, "conv.ovf.u8", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xba, StackBehaviour.Pop1, StackBehaviour.Pushi8 }; - yield return new object[] { OpCodes.Conv_Ovf_U8_Un, "conv.ovf.u8.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x89, StackBehaviour.Pop1, StackBehaviour.Pushi8 }; - yield return new object[] { OpCodes.Conv_R_Un, "conv.r.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x76, StackBehaviour.Pop1, StackBehaviour.Pushr8 }; - yield return new object[] { OpCodes.Conv_R4, "conv.r4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x6b, StackBehaviour.Pop1, StackBehaviour.Pushr4 }; - yield return new object[] { OpCodes.Conv_R8, "conv.r8", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x6c, StackBehaviour.Pop1, StackBehaviour.Pushr8 }; - yield return new object[] { OpCodes.Conv_U, "conv.u", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xe0, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_U1, "conv.u1", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xd2, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_U2, "conv.u2", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xd1, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_U4, "conv.u4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x6d, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Conv_U8, "conv.u8", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x6e, StackBehaviour.Pop1, StackBehaviour.Pushi8 }; - yield return new object[] { OpCodes.Cpblk, "cpblk", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe17, StackBehaviour.Popi_popi_popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Cpobj, "cpobj", OpCodeType.Objmodel, OperandType.InlineType, 1, 0x70, StackBehaviour.Popi_popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Div, "div", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x5b, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Div_Un, "div.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x5c, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Dup, "dup", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x25, StackBehaviour.Pop1, StackBehaviour.Push1_push1 }; - yield return new object[] { OpCodes.Endfilter, "endfilter", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe11, StackBehaviour.Popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Endfinally, "endfinally", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xdc, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Initblk, "initblk", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe18, StackBehaviour.Popi_popi_popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Initobj, "initobj", OpCodeType.Objmodel, OperandType.InlineType, 2, 0xfe15, StackBehaviour.Popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Isinst, "isinst", OpCodeType.Objmodel, OperandType.InlineType, 1, 0x75, StackBehaviour.Popref, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Jmp, "jmp", OpCodeType.Primitive, OperandType.InlineMethod, 1, 0x27, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Ldarg, "ldarg", OpCodeType.Primitive, OperandType.InlineVar, 2, 0xfe09, StackBehaviour.Pop0, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Ldarg_0, "ldarg.0", OpCodeType.Macro, OperandType.InlineNone, 1, 0x2, StackBehaviour.Pop0, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Ldarg_1, "ldarg.1", OpCodeType.Macro, OperandType.InlineNone, 1, 0x3, StackBehaviour.Pop0, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Ldarg_2, "ldarg.2", OpCodeType.Macro, OperandType.InlineNone, 1, 0x4, StackBehaviour.Pop0, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Ldarg_3, "ldarg.3", OpCodeType.Macro, OperandType.InlineNone, 1, 0x5, StackBehaviour.Pop0, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Ldarg_S, "ldarg.s", OpCodeType.Macro, OperandType.ShortInlineVar, 1, 0xe, StackBehaviour.Pop0, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Ldarga, "ldarga", OpCodeType.Primitive, OperandType.InlineVar, 2, 0xfe0a, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldarga_S, "ldarga.s", OpCodeType.Macro, OperandType.ShortInlineVar, 1, 0xf, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldc_I4, "ldc.i4", OpCodeType.Primitive, OperandType.InlineI, 1, 0x20, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldc_I4_0, "ldc.i4.0", OpCodeType.Macro, OperandType.InlineNone, 1, 0x16, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldc_I4_1, "ldc.i4.1", OpCodeType.Macro, OperandType.InlineNone, 1, 0x17, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldc_I4_2, "ldc.i4.2", OpCodeType.Macro, OperandType.InlineNone, 1, 0x18, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldc_I4_3, "ldc.i4.3", OpCodeType.Macro, OperandType.InlineNone, 1, 0x19, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldc_I4_4, "ldc.i4.4", OpCodeType.Macro, OperandType.InlineNone, 1, 0x1a, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldc_I4_5, "ldc.i4.5", OpCodeType.Macro, OperandType.InlineNone, 1, 0x1b, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldc_I4_6, "ldc.i4.6", OpCodeType.Macro, OperandType.InlineNone, 1, 0x1c, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldc_I4_7, "ldc.i4.7", OpCodeType.Macro, OperandType.InlineNone, 1, 0x1d, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldc_I4_8, "ldc.i4.8", OpCodeType.Macro, OperandType.InlineNone, 1, 0x1e, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldc_I4_M1, "ldc.i4.m1", OpCodeType.Macro, OperandType.InlineNone, 1, 0x15, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldc_I4_S, "ldc.i4.s", OpCodeType.Macro, OperandType.ShortInlineI, 1, 0x1f, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldc_I8, "ldc.i8", OpCodeType.Primitive, OperandType.InlineI8, 1, 0x21, StackBehaviour.Pop0, StackBehaviour.Pushi8 }; - yield return new object[] { OpCodes.Ldc_R4, "ldc.r4", OpCodeType.Primitive, OperandType.ShortInlineR, 1, 0x22, StackBehaviour.Pop0, StackBehaviour.Pushr4 }; - yield return new object[] { OpCodes.Ldc_R8, "ldc.r8", OpCodeType.Primitive, OperandType.InlineR, 1, 0x23, StackBehaviour.Pop0, StackBehaviour.Pushr8 }; - yield return new object[] { OpCodes.Ldelem, "ldelem", OpCodeType.Objmodel, OperandType.InlineType, 1, 0xa3, StackBehaviour.Popref_popi, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Ldelem_I, "ldelem.i", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x97, StackBehaviour.Popref_popi, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldelem_I1, "ldelem.i1", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x90, StackBehaviour.Popref_popi, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldelem_I2, "ldelem.i2", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x92, StackBehaviour.Popref_popi, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldelem_I4, "ldelem.i4", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x94, StackBehaviour.Popref_popi, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldelem_I8, "ldelem.i8", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x96, StackBehaviour.Popref_popi, StackBehaviour.Pushi8 }; - yield return new object[] { OpCodes.Ldelem_R4, "ldelem.r4", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x98, StackBehaviour.Popref_popi, StackBehaviour.Pushr4 }; - yield return new object[] { OpCodes.Ldelem_R8, "ldelem.r8", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x99, StackBehaviour.Popref_popi, StackBehaviour.Pushr8 }; - yield return new object[] { OpCodes.Ldelem_Ref, "ldelem.ref", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x9a, StackBehaviour.Popref_popi, StackBehaviour.Pushref }; - yield return new object[] { OpCodes.Ldelem_U1, "ldelem.u1", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x91, StackBehaviour.Popref_popi, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldelem_U2, "ldelem.u2", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x93, StackBehaviour.Popref_popi, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldelem_U4, "ldelem.u4", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x95, StackBehaviour.Popref_popi, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldelema, "ldelema", OpCodeType.Objmodel, OperandType.InlineType, 1, 0x8f, StackBehaviour.Popref_popi, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldfld, "ldfld", OpCodeType.Objmodel, OperandType.InlineField, 1, 0x7b, StackBehaviour.Popref, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Ldflda, "ldflda", OpCodeType.Objmodel, OperandType.InlineField, 1, 0x7c, StackBehaviour.Popref, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldftn, "ldftn", OpCodeType.Primitive, OperandType.InlineMethod, 2, 0xfe06, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldind_I, "ldind.i", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x4d, StackBehaviour.Popi, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldind_I1, "ldind.i1", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x46, StackBehaviour.Popi, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldind_I2, "ldind.i2", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x48, StackBehaviour.Popi, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldind_I4, "ldind.i4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x4a, StackBehaviour.Popi, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldind_I8, "ldind.i8", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x4c, StackBehaviour.Popi, StackBehaviour.Pushi8 }; - yield return new object[] { OpCodes.Ldind_R4, "ldind.r4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x4e, StackBehaviour.Popi, StackBehaviour.Pushr4 }; - yield return new object[] { OpCodes.Ldind_R8, "ldind.r8", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x4f, StackBehaviour.Popi, StackBehaviour.Pushr8 }; - yield return new object[] { OpCodes.Ldind_Ref, "ldind.ref", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x50, StackBehaviour.Popi, StackBehaviour.Pushref }; - yield return new object[] { OpCodes.Ldind_U1, "ldind.u1", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x47, StackBehaviour.Popi, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldind_U2, "ldind.u2", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x49, StackBehaviour.Popi, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldind_U4, "ldind.u4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x4b, StackBehaviour.Popi, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldlen, "ldlen", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x8e, StackBehaviour.Popref, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldloc, "ldloc", OpCodeType.Primitive, OperandType.InlineVar, 2, 0xfe0c, StackBehaviour.Pop0, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Ldloc_0, "ldloc.0", OpCodeType.Macro, OperandType.InlineNone, 1, 0x6, StackBehaviour.Pop0, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Ldloc_1, "ldloc.1", OpCodeType.Macro, OperandType.InlineNone, 1, 0x7, StackBehaviour.Pop0, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Ldloc_2, "ldloc.2", OpCodeType.Macro, OperandType.InlineNone, 1, 0x8, StackBehaviour.Pop0, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Ldloc_3, "ldloc.3", OpCodeType.Macro, OperandType.InlineNone, 1, 0x9, StackBehaviour.Pop0, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Ldloc_S, "ldloc.s", OpCodeType.Macro, OperandType.ShortInlineVar, 1, 0x11, StackBehaviour.Pop0, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Ldloca, "ldloca", OpCodeType.Primitive, OperandType.InlineVar, 2, 0xfe0d, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldloca_S, "ldloca.s", OpCodeType.Macro, OperandType.ShortInlineVar, 1, 0x12, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldnull, "ldnull", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x14, StackBehaviour.Pop0, StackBehaviour.Pushref }; - yield return new object[] { OpCodes.Ldobj, "ldobj", OpCodeType.Objmodel, OperandType.InlineType, 1, 0x71, StackBehaviour.Popi, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Ldsfld, "ldsfld", OpCodeType.Objmodel, OperandType.InlineField, 1, 0x7e, StackBehaviour.Pop0, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Ldsflda, "ldsflda", OpCodeType.Objmodel, OperandType.InlineField, 1, 0x7f, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldstr, "ldstr", OpCodeType.Objmodel, OperandType.InlineString, 1, 0x72, StackBehaviour.Pop0, StackBehaviour.Pushref }; - yield return new object[] { OpCodes.Ldtoken, "ldtoken", OpCodeType.Primitive, OperandType.InlineTok, 1, 0xd0, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Ldvirtftn, "ldvirtftn", OpCodeType.Primitive, OperandType.InlineMethod, 2, 0xfe07, StackBehaviour.Popref, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Leave, "leave", OpCodeType.Primitive, OperandType.InlineBrTarget, 1, 0xdd, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Leave_S, "leave.s", OpCodeType.Primitive, OperandType.ShortInlineBrTarget, 1, 0xde, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Localloc, "localloc", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe0f, StackBehaviour.Popi, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Mkrefany, "mkrefany", OpCodeType.Primitive, OperandType.InlineType, 1, 0xc6, StackBehaviour.Popi, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Mul, "mul", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x5a, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Mul_Ovf, "mul.ovf", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xd8, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Mul_Ovf_Un, "mul.ovf.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xd9, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Neg, "neg", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x65, StackBehaviour.Pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Newarr, "newarr", OpCodeType.Objmodel, OperandType.InlineType, 1, 0x8d, StackBehaviour.Popi, StackBehaviour.Pushref }; - yield return new object[] { OpCodes.Newobj, "newobj", OpCodeType.Objmodel, OperandType.InlineMethod, 1, 0x73, StackBehaviour.Varpop, StackBehaviour.Pushref }; - yield return new object[] { OpCodes.Nop, "nop", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x0, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Not, "not", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x66, StackBehaviour.Pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Or, "or", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x60, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Pop, "pop", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x26, StackBehaviour.Pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Prefix1, "prefix1", OpCodeType.Nternal, OperandType.InlineNone, 1, 0xfe, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Prefix2, "prefix2", OpCodeType.Nternal, OperandType.InlineNone, 1, 0xfd, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Prefix3, "prefix3", OpCodeType.Nternal, OperandType.InlineNone, 1, 0xfc, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Prefix4, "prefix4", OpCodeType.Nternal, OperandType.InlineNone, 1, 0xfb, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Prefix5, "prefix5", OpCodeType.Nternal, OperandType.InlineNone, 1, 0xfa, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Prefix6, "prefix6", OpCodeType.Nternal, OperandType.InlineNone, 1, 0xf9, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Prefix7, "prefix7", OpCodeType.Nternal, OperandType.InlineNone, 1, 0xf8, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Prefixref, "prefixref", OpCodeType.Nternal, OperandType.InlineNone, 1, 0xff, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Readonly, "readonly.", OpCodeType.Prefix, OperandType.InlineNone, 2, 0xfe1e, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Refanytype, "refanytype", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe1d, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Refanyval, "refanyval", OpCodeType.Primitive, OperandType.InlineType, 1, 0xc2, StackBehaviour.Pop1, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Rem, "rem", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x5d, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Rem_Un, "rem.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x5e, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Ret, "ret", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x2a, StackBehaviour.Varpop, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Rethrow, "rethrow", OpCodeType.Objmodel, OperandType.InlineNone, 2, 0xfe1a, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Shl, "shl", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x62, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Shr, "shr", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x63, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Shr_Un, "shr.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x64, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Sizeof, "sizeof", OpCodeType.Primitive, OperandType.InlineType, 2, 0xfe1c, StackBehaviour.Pop0, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Starg, "starg", OpCodeType.Primitive, OperandType.InlineVar, 2, 0xfe0b, StackBehaviour.Pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Starg_S, "starg.s", OpCodeType.Macro, OperandType.ShortInlineVar, 1, 0x10, StackBehaviour.Pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stelem, "stelem", OpCodeType.Objmodel, OperandType.InlineType, 1, 0xa4, StackBehaviour.Popref_popi_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stelem_I, "stelem.i", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x9b, StackBehaviour.Popref_popi_popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stelem_I1, "stelem.i1", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x9c, StackBehaviour.Popref_popi_popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stelem_I2, "stelem.i2", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x9d, StackBehaviour.Popref_popi_popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stelem_I4, "stelem.i4", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x9e, StackBehaviour.Popref_popi_popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stelem_I8, "stelem.i8", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x9f, StackBehaviour.Popref_popi_popi8, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stelem_R4, "stelem.r4", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0xa0, StackBehaviour.Popref_popi_popr4, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stelem_R8, "stelem.r8", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0xa1, StackBehaviour.Popref_popi_popr8, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stelem_Ref, "stelem.ref", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0xa2, StackBehaviour.Popref_popi_popref, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stfld, "stfld", OpCodeType.Objmodel, OperandType.InlineField, 1, 0x7d, StackBehaviour.Popref_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stind_I, "stind.i", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xdf, StackBehaviour.Popi_popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stind_I1, "stind.i1", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x52, StackBehaviour.Popi_popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stind_I2, "stind.i2", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x53, StackBehaviour.Popi_popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stind_I4, "stind.i4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x54, StackBehaviour.Popi_popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stind_I8, "stind.i8", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x55, StackBehaviour.Popi_popi8, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stind_R4, "stind.r4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x56, StackBehaviour.Popi_popr4, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stind_R8, "stind.r8", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x57, StackBehaviour.Popi_popr8, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stind_Ref, "stind.ref", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x51, StackBehaviour.Popi_popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stloc, "stloc", OpCodeType.Primitive, OperandType.InlineVar, 2, 0xfe0e, StackBehaviour.Pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stloc_0, "stloc.0", OpCodeType.Macro, OperandType.InlineNone, 1, 0xa, StackBehaviour.Pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stloc_1, "stloc.1", OpCodeType.Macro, OperandType.InlineNone, 1, 0xb, StackBehaviour.Pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stloc_2, "stloc.2", OpCodeType.Macro, OperandType.InlineNone, 1, 0xc, StackBehaviour.Pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stloc_3, "stloc.3", OpCodeType.Macro, OperandType.InlineNone, 1, 0xd, StackBehaviour.Pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stloc_S, "stloc.s", OpCodeType.Macro, OperandType.ShortInlineVar, 1, 0x13, StackBehaviour.Pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stobj, "stobj", OpCodeType.Primitive, OperandType.InlineType, 1, 0x81, StackBehaviour.Popi_pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Stsfld, "stsfld", OpCodeType.Objmodel, OperandType.InlineField, 1, 0x80, StackBehaviour.Pop1, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Sub, "sub", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x59, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Sub_Ovf, "sub.ovf", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xda, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Sub_Ovf_Un, "sub.ovf.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xdb, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Switch, "switch", OpCodeType.Primitive, OperandType.InlineSwitch, 1, 0x45, StackBehaviour.Popi, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Tailcall, "tail.", OpCodeType.Prefix, OperandType.InlineNone, 2, 0xfe14, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Throw, "throw", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x7a, StackBehaviour.Popref, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Unaligned, "unaligned.", OpCodeType.Prefix, OperandType.ShortInlineI, 2, 0xfe12, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Unbox, "unbox", OpCodeType.Primitive, OperandType.InlineType, 1, 0x79, StackBehaviour.Popref, StackBehaviour.Pushi }; - yield return new object[] { OpCodes.Unbox_Any, "unbox.any", OpCodeType.Objmodel, OperandType.InlineType, 1, 0xa5, StackBehaviour.Popref, StackBehaviour.Push1 }; - yield return new object[] { OpCodes.Volatile, "volatile.", OpCodeType.Prefix, OperandType.InlineNone, 2, 0xfe13, StackBehaviour.Pop0, StackBehaviour.Push0 }; - yield return new object[] { OpCodes.Xor, "xor", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x61, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 }; + yield return new object[] { OpCodes.Add, "add", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x58, StackBehaviour.Pop1_pop1, StackBehaviour.Push1, -1}; + yield return new object[] { OpCodes.Add_Ovf, "add.ovf", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xd6, StackBehaviour.Pop1_pop1, StackBehaviour.Push1, -1 }; + yield return new object[] { OpCodes.Add_Ovf_Un, "add.ovf.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xd7, StackBehaviour.Pop1_pop1, StackBehaviour.Push1, -1 }; + yield return new object[] { OpCodes.And, "and", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x5f, StackBehaviour.Pop1_pop1, StackBehaviour.Push1 , -1 }; + yield return new object[] { OpCodes.Arglist, "arglist", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe00, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Beq, "beq", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x3b, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Beq_S, "beq.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x2e, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Bge, "bge", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x3c, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Bge_S, "bge.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x2f, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Bge_Un, "bge.un", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x41, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Bge_Un_S, "bge.un.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x34, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Bgt, "bgt", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x3d, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Bgt_S, "bgt.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x30, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Bgt_Un, "bgt.un", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x42, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Bgt_Un_S, "bgt.un.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x35, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Ble, "ble", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x3e, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Ble_S, "ble.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x31, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Ble_Un, "ble.un", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x43, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Ble_Un_S, "ble.un.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x36, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Blt, "blt", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x3f, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Blt_S, "blt.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x32, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Blt_Un, "blt.un", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x44, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Blt_Un_S, "blt.un.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x37, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Bne_Un, "bne.un", OpCodeType.Macro, OperandType.InlineBrTarget, 1, 0x40, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Bne_Un_S, "bne.un.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x33, StackBehaviour.Pop1_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Box, "box", OpCodeType.Primitive, OperandType.InlineType, 1, 0x8c, StackBehaviour.Pop1, StackBehaviour.Pushref, 0 }; + yield return new object[] { OpCodes.Br, "br", OpCodeType.Primitive, OperandType.InlineBrTarget, 1, 0x38, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Br_S, "br.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x2b, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Break, "break", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x1, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Brfalse, "brfalse", OpCodeType.Primitive, OperandType.InlineBrTarget, 1, 0x39, StackBehaviour.Popi, StackBehaviour.Push0, -1 }; + yield return new object[] { OpCodes.Brfalse_S, "brfalse.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x2c, StackBehaviour.Popi, StackBehaviour.Push0, -1 }; + yield return new object[] { OpCodes.Brtrue, "brtrue", OpCodeType.Primitive, OperandType.InlineBrTarget, 1, 0x3a, StackBehaviour.Popi, StackBehaviour.Push0, -1 }; + yield return new object[] { OpCodes.Brtrue_S, "brtrue.s", OpCodeType.Macro, OperandType.ShortInlineBrTarget, 1, 0x2d, StackBehaviour.Popi, StackBehaviour.Push0, -1 }; + yield return new object[] { OpCodes.Call, "call", OpCodeType.Primitive, OperandType.InlineMethod, 1, 0x28, StackBehaviour.Varpop, StackBehaviour.Varpush, 0 }; + yield return new object[] { OpCodes.Calli, "calli", OpCodeType.Primitive, OperandType.InlineSig, 1, 0x29, StackBehaviour.Varpop, StackBehaviour.Varpush, 0 }; + yield return new object[] { OpCodes.Callvirt, "callvirt", OpCodeType.Objmodel, OperandType.InlineMethod, 1, 0x6f, StackBehaviour.Varpop, StackBehaviour.Varpush, 0 }; + yield return new object[] { OpCodes.Castclass, "castclass", OpCodeType.Objmodel, OperandType.InlineType, 1, 0x74, StackBehaviour.Popref, StackBehaviour.Pushref, 0 }; + yield return new object[] { OpCodes.Ceq, "ceq", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe01, StackBehaviour.Pop1_pop1, StackBehaviour.Pushi, -1 }; + yield return new object[] { OpCodes.Cgt, "cgt", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe02, StackBehaviour.Pop1_pop1, StackBehaviour.Pushi, -1 }; + yield return new object[] { OpCodes.Cgt_Un, "cgt.un", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe03, StackBehaviour.Pop1_pop1, StackBehaviour.Pushi, -1 }; + yield return new object[] { OpCodes.Ckfinite, "ckfinite", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xc3, StackBehaviour.Pop1, StackBehaviour.Pushr8, 0 }; + yield return new object[] { OpCodes.Clt, "clt", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe04, StackBehaviour.Pop1_pop1, StackBehaviour.Pushi, -1 }; + yield return new object[] { OpCodes.Clt_Un, "clt.un", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe05, StackBehaviour.Pop1_pop1, StackBehaviour.Pushi, -1 }; + yield return new object[] { OpCodes.Constrained, "constrained.", OpCodeType.Prefix, OperandType.InlineType, 2, 0xfe16, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Conv_I, "conv.i", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xd3, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_I1, "conv.i1", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x67, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_I2, "conv.i2", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x68, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_I4, "conv.i4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x69, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_I8, "conv.i8", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x6a, StackBehaviour.Pop1, StackBehaviour.Pushi8, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_I, "conv.ovf.i", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xd4, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_I_Un, "conv.ovf.i.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x8a, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_I1, "conv.ovf.i1", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xb3, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_I1_Un, "conv.ovf.i1.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x82, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_I2, "conv.ovf.i2", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xb5, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_I2_Un, "conv.ovf.i2.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x83, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_I4, "conv.ovf.i4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xb7, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_I4_Un, "conv.ovf.i4.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x84, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_I8, "conv.ovf.i8", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xb9, StackBehaviour.Pop1, StackBehaviour.Pushi8, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_I8_Un, "conv.ovf.i8.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x85, StackBehaviour.Pop1, StackBehaviour.Pushi8, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_U, "conv.ovf.u", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xd5, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_U_Un, "conv.ovf.u.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x8b, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_U1, "conv.ovf.u1", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xb4, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_U1_Un, "conv.ovf.u1.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x86, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_U2, "conv.ovf.u2", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xb6, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_U2_Un, "conv.ovf.u2.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x87, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_U4, "conv.ovf.u4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xb8, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_U4_Un, "conv.ovf.u4.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x88, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_U8, "conv.ovf.u8", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xba, StackBehaviour.Pop1, StackBehaviour.Pushi8, 0 }; + yield return new object[] { OpCodes.Conv_Ovf_U8_Un, "conv.ovf.u8.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x89, StackBehaviour.Pop1, StackBehaviour.Pushi8, 0 }; + yield return new object[] { OpCodes.Conv_R_Un, "conv.r.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x76, StackBehaviour.Pop1, StackBehaviour.Pushr8, 0 }; + yield return new object[] { OpCodes.Conv_R4, "conv.r4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x6b, StackBehaviour.Pop1, StackBehaviour.Pushr4, 0 }; + yield return new object[] { OpCodes.Conv_R8, "conv.r8", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x6c, StackBehaviour.Pop1, StackBehaviour.Pushr8, 0 }; + yield return new object[] { OpCodes.Conv_U, "conv.u", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xe0, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_U1, "conv.u1", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xd2, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_U2, "conv.u2", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xd1, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_U4, "conv.u4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x6d, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Conv_U8, "conv.u8", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x6e, StackBehaviour.Pop1, StackBehaviour.Pushi8, 0 }; + yield return new object[] { OpCodes.Cpblk, "cpblk", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe17, StackBehaviour.Popi_popi_popi, StackBehaviour.Push0, -3 }; + yield return new object[] { OpCodes.Cpobj, "cpobj", OpCodeType.Objmodel, OperandType.InlineType, 1, 0x70, StackBehaviour.Popi_popi, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Div, "div", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x5b, StackBehaviour.Pop1_pop1, StackBehaviour.Push1, -1 }; + yield return new object[] { OpCodes.Div_Un, "div.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x5c, StackBehaviour.Pop1_pop1, StackBehaviour.Push1, -1 }; + yield return new object[] { OpCodes.Dup, "dup", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x25, StackBehaviour.Pop1, StackBehaviour.Push1_push1, 1 }; + yield return new object[] { OpCodes.Endfilter, "endfilter", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe11, StackBehaviour.Popi, StackBehaviour.Push0, -1 }; + yield return new object[] { OpCodes.Endfinally, "endfinally", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xdc, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Initblk, "initblk", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe18, StackBehaviour.Popi_popi_popi, StackBehaviour.Push0, -3 }; + yield return new object[] { OpCodes.Initobj, "initobj", OpCodeType.Objmodel, OperandType.InlineType, 2, 0xfe15, StackBehaviour.Popi, StackBehaviour.Push0, -1 }; + yield return new object[] { OpCodes.Isinst, "isinst", OpCodeType.Objmodel, OperandType.InlineType, 1, 0x75, StackBehaviour.Popref, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Jmp, "jmp", OpCodeType.Primitive, OperandType.InlineMethod, 1, 0x27, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Ldarg, "ldarg", OpCodeType.Primitive, OperandType.InlineVar, 2, 0xfe09, StackBehaviour.Pop0, StackBehaviour.Push1, 1 }; + yield return new object[] { OpCodes.Ldarg_0, "ldarg.0", OpCodeType.Macro, OperandType.InlineNone, 1, 0x2, StackBehaviour.Pop0, StackBehaviour.Push1, 1 }; + yield return new object[] { OpCodes.Ldarg_1, "ldarg.1", OpCodeType.Macro, OperandType.InlineNone, 1, 0x3, StackBehaviour.Pop0, StackBehaviour.Push1, 1 }; + yield return new object[] { OpCodes.Ldarg_2, "ldarg.2", OpCodeType.Macro, OperandType.InlineNone, 1, 0x4, StackBehaviour.Pop0, StackBehaviour.Push1, 1 }; + yield return new object[] { OpCodes.Ldarg_3, "ldarg.3", OpCodeType.Macro, OperandType.InlineNone, 1, 0x5, StackBehaviour.Pop0, StackBehaviour.Push1, 1 }; + yield return new object[] { OpCodes.Ldarg_S, "ldarg.s", OpCodeType.Macro, OperandType.ShortInlineVar, 1, 0xe, StackBehaviour.Pop0, StackBehaviour.Push1, 1 }; + yield return new object[] { OpCodes.Ldarga, "ldarga", OpCodeType.Primitive, OperandType.InlineVar, 2, 0xfe0a, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldarga_S, "ldarga.s", OpCodeType.Macro, OperandType.ShortInlineVar, 1, 0xf, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldc_I4, "ldc.i4", OpCodeType.Primitive, OperandType.InlineI, 1, 0x20, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldc_I4_0, "ldc.i4.0", OpCodeType.Macro, OperandType.InlineNone, 1, 0x16, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldc_I4_1, "ldc.i4.1", OpCodeType.Macro, OperandType.InlineNone, 1, 0x17, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldc_I4_2, "ldc.i4.2", OpCodeType.Macro, OperandType.InlineNone, 1, 0x18, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldc_I4_3, "ldc.i4.3", OpCodeType.Macro, OperandType.InlineNone, 1, 0x19, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldc_I4_4, "ldc.i4.4", OpCodeType.Macro, OperandType.InlineNone, 1, 0x1a, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldc_I4_5, "ldc.i4.5", OpCodeType.Macro, OperandType.InlineNone, 1, 0x1b, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldc_I4_6, "ldc.i4.6", OpCodeType.Macro, OperandType.InlineNone, 1, 0x1c, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldc_I4_7, "ldc.i4.7", OpCodeType.Macro, OperandType.InlineNone, 1, 0x1d, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldc_I4_8, "ldc.i4.8", OpCodeType.Macro, OperandType.InlineNone, 1, 0x1e, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldc_I4_M1, "ldc.i4.m1", OpCodeType.Macro, OperandType.InlineNone, 1, 0x15, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldc_I4_S, "ldc.i4.s", OpCodeType.Macro, OperandType.ShortInlineI, 1, 0x1f, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldc_I8, "ldc.i8", OpCodeType.Primitive, OperandType.InlineI8, 1, 0x21, StackBehaviour.Pop0, StackBehaviour.Pushi8, 1 }; + yield return new object[] { OpCodes.Ldc_R4, "ldc.r4", OpCodeType.Primitive, OperandType.ShortInlineR, 1, 0x22, StackBehaviour.Pop0, StackBehaviour.Pushr4, 1 }; + yield return new object[] { OpCodes.Ldc_R8, "ldc.r8", OpCodeType.Primitive, OperandType.InlineR, 1, 0x23, StackBehaviour.Pop0, StackBehaviour.Pushr8, 1 }; + yield return new object[] { OpCodes.Ldelem, "ldelem", OpCodeType.Objmodel, OperandType.InlineType, 1, 0xa3, StackBehaviour.Popref_popi, StackBehaviour.Push1, -1 }; + yield return new object[] { OpCodes.Ldelem_I, "ldelem.i", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x97, StackBehaviour.Popref_popi, StackBehaviour.Pushi, -1 }; + yield return new object[] { OpCodes.Ldelem_I1, "ldelem.i1", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x90, StackBehaviour.Popref_popi, StackBehaviour.Pushi, -1 }; + yield return new object[] { OpCodes.Ldelem_I2, "ldelem.i2", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x92, StackBehaviour.Popref_popi, StackBehaviour.Pushi, -1 }; + yield return new object[] { OpCodes.Ldelem_I4, "ldelem.i4", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x94, StackBehaviour.Popref_popi, StackBehaviour.Pushi, -1 }; + yield return new object[] { OpCodes.Ldelem_I8, "ldelem.i8", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x96, StackBehaviour.Popref_popi, StackBehaviour.Pushi8, -1 }; + yield return new object[] { OpCodes.Ldelem_R4, "ldelem.r4", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x98, StackBehaviour.Popref_popi, StackBehaviour.Pushr4, -1 }; + yield return new object[] { OpCodes.Ldelem_R8, "ldelem.r8", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x99, StackBehaviour.Popref_popi, StackBehaviour.Pushr8, -1 }; + yield return new object[] { OpCodes.Ldelem_Ref, "ldelem.ref", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x9a, StackBehaviour.Popref_popi, StackBehaviour.Pushref, -1 }; + yield return new object[] { OpCodes.Ldelem_U1, "ldelem.u1", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x91, StackBehaviour.Popref_popi, StackBehaviour.Pushi, -1 }; + yield return new object[] { OpCodes.Ldelem_U2, "ldelem.u2", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x93, StackBehaviour.Popref_popi, StackBehaviour.Pushi, -1 }; + yield return new object[] { OpCodes.Ldelem_U4, "ldelem.u4", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x95, StackBehaviour.Popref_popi, StackBehaviour.Pushi, -1 }; + yield return new object[] { OpCodes.Ldelema, "ldelema", OpCodeType.Objmodel, OperandType.InlineType, 1, 0x8f, StackBehaviour.Popref_popi, StackBehaviour.Pushi, -1 }; + yield return new object[] { OpCodes.Ldfld, "ldfld", OpCodeType.Objmodel, OperandType.InlineField, 1, 0x7b, StackBehaviour.Popref, StackBehaviour.Push1, 0 }; + yield return new object[] { OpCodes.Ldflda, "ldflda", OpCodeType.Objmodel, OperandType.InlineField, 1, 0x7c, StackBehaviour.Popref, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Ldftn, "ldftn", OpCodeType.Primitive, OperandType.InlineMethod, 2, 0xfe06, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldind_I, "ldind.i", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x4d, StackBehaviour.Popi, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Ldind_I1, "ldind.i1", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x46, StackBehaviour.Popi, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Ldind_I2, "ldind.i2", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x48, StackBehaviour.Popi, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Ldind_I4, "ldind.i4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x4a, StackBehaviour.Popi, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Ldind_I8, "ldind.i8", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x4c, StackBehaviour.Popi, StackBehaviour.Pushi8, 0 }; + yield return new object[] { OpCodes.Ldind_R4, "ldind.r4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x4e, StackBehaviour.Popi, StackBehaviour.Pushr4, 0 }; + yield return new object[] { OpCodes.Ldind_R8, "ldind.r8", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x4f, StackBehaviour.Popi, StackBehaviour.Pushr8, 0 }; + yield return new object[] { OpCodes.Ldind_Ref, "ldind.ref", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x50, StackBehaviour.Popi, StackBehaviour.Pushref, 0 }; + yield return new object[] { OpCodes.Ldind_U1, "ldind.u1", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x47, StackBehaviour.Popi, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Ldind_U2, "ldind.u2", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x49, StackBehaviour.Popi, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Ldind_U4, "ldind.u4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x4b, StackBehaviour.Popi, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Ldlen, "ldlen", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x8e, StackBehaviour.Popref, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Ldloc, "ldloc", OpCodeType.Primitive, OperandType.InlineVar, 2, 0xfe0c, StackBehaviour.Pop0, StackBehaviour.Push1, 1 }; + yield return new object[] { OpCodes.Ldloc_0, "ldloc.0", OpCodeType.Macro, OperandType.InlineNone, 1, 0x6, StackBehaviour.Pop0, StackBehaviour.Push1, 1 }; + yield return new object[] { OpCodes.Ldloc_1, "ldloc.1", OpCodeType.Macro, OperandType.InlineNone, 1, 0x7, StackBehaviour.Pop0, StackBehaviour.Push1, 1 }; + yield return new object[] { OpCodes.Ldloc_2, "ldloc.2", OpCodeType.Macro, OperandType.InlineNone, 1, 0x8, StackBehaviour.Pop0, StackBehaviour.Push1, 1 }; + yield return new object[] { OpCodes.Ldloc_3, "ldloc.3", OpCodeType.Macro, OperandType.InlineNone, 1, 0x9, StackBehaviour.Pop0, StackBehaviour.Push1, 1 }; + yield return new object[] { OpCodes.Ldloc_S, "ldloc.s", OpCodeType.Macro, OperandType.ShortInlineVar, 1, 0x11, StackBehaviour.Pop0, StackBehaviour.Push1, 1 }; + yield return new object[] { OpCodes.Ldloca, "ldloca", OpCodeType.Primitive, OperandType.InlineVar, 2, 0xfe0d, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldloca_S, "ldloca.s", OpCodeType.Macro, OperandType.ShortInlineVar, 1, 0x12, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldnull, "ldnull", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x14, StackBehaviour.Pop0, StackBehaviour.Pushref, 1 }; + yield return new object[] { OpCodes.Ldobj, "ldobj", OpCodeType.Objmodel, OperandType.InlineType, 1, 0x71, StackBehaviour.Popi, StackBehaviour.Push1, 0 }; + yield return new object[] { OpCodes.Ldsfld, "ldsfld", OpCodeType.Objmodel, OperandType.InlineField, 1, 0x7e, StackBehaviour.Pop0, StackBehaviour.Push1, 1 }; + yield return new object[] { OpCodes.Ldsflda, "ldsflda", OpCodeType.Objmodel, OperandType.InlineField, 1, 0x7f, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldstr, "ldstr", OpCodeType.Objmodel, OperandType.InlineString, 1, 0x72, StackBehaviour.Pop0, StackBehaviour.Pushref, 1 }; + yield return new object[] { OpCodes.Ldtoken, "ldtoken", OpCodeType.Primitive, OperandType.InlineTok, 1, 0xd0, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Ldvirtftn, "ldvirtftn", OpCodeType.Primitive, OperandType.InlineMethod, 2, 0xfe07, StackBehaviour.Popref, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Leave, "leave", OpCodeType.Primitive, OperandType.InlineBrTarget, 1, 0xdd, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Leave_S, "leave.s", OpCodeType.Primitive, OperandType.ShortInlineBrTarget, 1, 0xde, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Localloc, "localloc", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe0f, StackBehaviour.Popi, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Mkrefany, "mkrefany", OpCodeType.Primitive, OperandType.InlineType, 1, 0xc6, StackBehaviour.Popi, StackBehaviour.Push1, 0 }; + yield return new object[] { OpCodes.Mul, "mul", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x5a, StackBehaviour.Pop1_pop1, StackBehaviour.Push1, -1 }; + yield return new object[] { OpCodes.Mul_Ovf, "mul.ovf", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xd8, StackBehaviour.Pop1_pop1, StackBehaviour.Push1, -1 }; + yield return new object[] { OpCodes.Mul_Ovf_Un, "mul.ovf.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xd9, StackBehaviour.Pop1_pop1, StackBehaviour.Push1, -1 }; + yield return new object[] { OpCodes.Neg, "neg", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x65, StackBehaviour.Pop1, StackBehaviour.Push1, 0 }; + yield return new object[] { OpCodes.Newarr, "newarr", OpCodeType.Objmodel, OperandType.InlineType, 1, 0x8d, StackBehaviour.Popi, StackBehaviour.Pushref, 0 }; + yield return new object[] { OpCodes.Newobj, "newobj", OpCodeType.Objmodel, OperandType.InlineMethod, 1, 0x73, StackBehaviour.Varpop, StackBehaviour.Pushref, 1 }; + yield return new object[] { OpCodes.Nop, "nop", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x0, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Not, "not", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x66, StackBehaviour.Pop1, StackBehaviour.Push1, 0 }; + yield return new object[] { OpCodes.Or, "or", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x60, StackBehaviour.Pop1_pop1, StackBehaviour.Push1, -1 }; + yield return new object[] { OpCodes.Pop, "pop", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x26, StackBehaviour.Pop1, StackBehaviour.Push0, -1 }; + yield return new object[] { OpCodes.Prefix1, "prefix1", OpCodeType.Nternal, OperandType.InlineNone, 1, 0xfe, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Prefix2, "prefix2", OpCodeType.Nternal, OperandType.InlineNone, 1, 0xfd, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Prefix3, "prefix3", OpCodeType.Nternal, OperandType.InlineNone, 1, 0xfc, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Prefix4, "prefix4", OpCodeType.Nternal, OperandType.InlineNone, 1, 0xfb, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Prefix5, "prefix5", OpCodeType.Nternal, OperandType.InlineNone, 1, 0xfa, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Prefix6, "prefix6", OpCodeType.Nternal, OperandType.InlineNone, 1, 0xf9, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Prefix7, "prefix7", OpCodeType.Nternal, OperandType.InlineNone, 1, 0xf8, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Prefixref, "prefixref", OpCodeType.Nternal, OperandType.InlineNone, 1, 0xff, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Readonly, "readonly.", OpCodeType.Prefix, OperandType.InlineNone, 2, 0xfe1e, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Refanytype, "refanytype", OpCodeType.Primitive, OperandType.InlineNone, 2, 0xfe1d, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Refanyval, "refanyval", OpCodeType.Primitive, OperandType.InlineType, 1, 0xc2, StackBehaviour.Pop1, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Rem, "rem", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x5d, StackBehaviour.Pop1_pop1, StackBehaviour.Push1, -1 }; + yield return new object[] { OpCodes.Rem_Un, "rem.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x5e, StackBehaviour.Pop1_pop1, StackBehaviour.Push1, -1 }; + yield return new object[] { OpCodes.Ret, "ret", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x2a, StackBehaviour.Varpop, StackBehaviour.Push0, 0 }; // it depends if the method returns a value + yield return new object[] { OpCodes.Rethrow, "rethrow", OpCodeType.Objmodel, OperandType.InlineNone, 2, 0xfe1a, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Shl, "shl", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x62, StackBehaviour.Pop1_pop1, StackBehaviour.Push1, -1 }; + yield return new object[] { OpCodes.Shr, "shr", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x63, StackBehaviour.Pop1_pop1, StackBehaviour.Push1, -1 }; + yield return new object[] { OpCodes.Shr_Un, "shr.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x64, StackBehaviour.Pop1_pop1, StackBehaviour.Push1, -1 }; + yield return new object[] { OpCodes.Sizeof, "sizeof", OpCodeType.Primitive, OperandType.InlineType, 2, 0xfe1c, StackBehaviour.Pop0, StackBehaviour.Pushi, 1 }; + yield return new object[] { OpCodes.Starg, "starg", OpCodeType.Primitive, OperandType.InlineVar, 2, 0xfe0b, StackBehaviour.Pop1, StackBehaviour.Push0, -1 }; + yield return new object[] { OpCodes.Starg_S, "starg.s", OpCodeType.Macro, OperandType.ShortInlineVar, 1, 0x10, StackBehaviour.Pop1, StackBehaviour.Push0, -1 }; + yield return new object[] { OpCodes.Stelem, "stelem", OpCodeType.Objmodel, OperandType.InlineType, 1, 0xa4, StackBehaviour.Popref_popi_pop1, StackBehaviour.Push0, -3 }; + yield return new object[] { OpCodes.Stelem_I, "stelem.i", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x9b, StackBehaviour.Popref_popi_popi, StackBehaviour.Push0, -3 }; + yield return new object[] { OpCodes.Stelem_I1, "stelem.i1", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x9c, StackBehaviour.Popref_popi_popi, StackBehaviour.Push0, -3 }; + yield return new object[] { OpCodes.Stelem_I2, "stelem.i2", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x9d, StackBehaviour.Popref_popi_popi, StackBehaviour.Push0, -3 }; + yield return new object[] { OpCodes.Stelem_I4, "stelem.i4", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x9e, StackBehaviour.Popref_popi_popi, StackBehaviour.Push0, -3 }; + yield return new object[] { OpCodes.Stelem_I8, "stelem.i8", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x9f, StackBehaviour.Popref_popi_popi8, StackBehaviour.Push0, -3 }; + yield return new object[] { OpCodes.Stelem_R4, "stelem.r4", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0xa0, StackBehaviour.Popref_popi_popr4, StackBehaviour.Push0, -3 }; + yield return new object[] { OpCodes.Stelem_R8, "stelem.r8", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0xa1, StackBehaviour.Popref_popi_popr8, StackBehaviour.Push0, -3 }; + yield return new object[] { OpCodes.Stelem_Ref, "stelem.ref", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0xa2, StackBehaviour.Popref_popi_popref, StackBehaviour.Push0, -3 }; + yield return new object[] { OpCodes.Stfld, "stfld", OpCodeType.Objmodel, OperandType.InlineField, 1, 0x7d, StackBehaviour.Popref_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Stind_I, "stind.i", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xdf, StackBehaviour.Popi_popi, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Stind_I1, "stind.i1", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x52, StackBehaviour.Popi_popi, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Stind_I2, "stind.i2", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x53, StackBehaviour.Popi_popi, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Stind_I4, "stind.i4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x54, StackBehaviour.Popi_popi, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Stind_I8, "stind.i8", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x55, StackBehaviour.Popi_popi8, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Stind_R4, "stind.r4", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x56, StackBehaviour.Popi_popr4, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Stind_R8, "stind.r8", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x57, StackBehaviour.Popi_popr8, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Stind_Ref, "stind.ref", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x51, StackBehaviour.Popi_popi, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Stloc, "stloc", OpCodeType.Primitive, OperandType.InlineVar, 2, 0xfe0e, StackBehaviour.Pop1, StackBehaviour.Push0, -1 }; + yield return new object[] { OpCodes.Stloc_0, "stloc.0", OpCodeType.Macro, OperandType.InlineNone, 1, 0xa, StackBehaviour.Pop1, StackBehaviour.Push0, -1 }; + yield return new object[] { OpCodes.Stloc_1, "stloc.1", OpCodeType.Macro, OperandType.InlineNone, 1, 0xb, StackBehaviour.Pop1, StackBehaviour.Push0, -1 }; + yield return new object[] { OpCodes.Stloc_2, "stloc.2", OpCodeType.Macro, OperandType.InlineNone, 1, 0xc, StackBehaviour.Pop1, StackBehaviour.Push0, -1 }; + yield return new object[] { OpCodes.Stloc_3, "stloc.3", OpCodeType.Macro, OperandType.InlineNone, 1, 0xd, StackBehaviour.Pop1, StackBehaviour.Push0, -1 }; + yield return new object[] { OpCodes.Stloc_S, "stloc.s", OpCodeType.Macro, OperandType.ShortInlineVar, 1, 0x13, StackBehaviour.Pop1, StackBehaviour.Push0, -1 }; + yield return new object[] { OpCodes.Stobj, "stobj", OpCodeType.Primitive, OperandType.InlineType, 1, 0x81, StackBehaviour.Popi_pop1, StackBehaviour.Push0, -2 }; + yield return new object[] { OpCodes.Stsfld, "stsfld", OpCodeType.Objmodel, OperandType.InlineField, 1, 0x80, StackBehaviour.Pop1, StackBehaviour.Push0, -1 }; + yield return new object[] { OpCodes.Sub, "sub", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x59, StackBehaviour.Pop1_pop1, StackBehaviour.Push1, -1 }; + yield return new object[] { OpCodes.Sub_Ovf, "sub.ovf", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xda, StackBehaviour.Pop1_pop1, StackBehaviour.Push1, -1 }; + yield return new object[] { OpCodes.Sub_Ovf_Un, "sub.ovf.un", OpCodeType.Primitive, OperandType.InlineNone, 1, 0xdb, StackBehaviour.Pop1_pop1, StackBehaviour.Push1, -1 }; + yield return new object[] { OpCodes.Switch, "switch", OpCodeType.Primitive, OperandType.InlineSwitch, 1, 0x45, StackBehaviour.Popi, StackBehaviour.Push0, -1 }; + yield return new object[] { OpCodes.Tailcall, "tail.", OpCodeType.Prefix, OperandType.InlineNone, 2, 0xfe14, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Throw, "throw", OpCodeType.Objmodel, OperandType.InlineNone, 1, 0x7a, StackBehaviour.Popref, StackBehaviour.Push0, -1 }; + yield return new object[] { OpCodes.Unaligned, "unaligned.", OpCodeType.Prefix, OperandType.ShortInlineI, 2, 0xfe12, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Unbox, "unbox", OpCodeType.Primitive, OperandType.InlineType, 1, 0x79, StackBehaviour.Popref, StackBehaviour.Pushi, 0 }; + yield return new object[] { OpCodes.Unbox_Any, "unbox.any", OpCodeType.Objmodel, OperandType.InlineType, 1, 0xa5, StackBehaviour.Popref, StackBehaviour.Push1, 0 }; + yield return new object[] { OpCodes.Volatile, "volatile.", OpCodeType.Prefix, OperandType.InlineNone, 2, 0xfe13, StackBehaviour.Pop0, StackBehaviour.Push0, 0 }; + yield return new object[] { OpCodes.Xor, "xor", OpCodeType.Primitive, OperandType.InlineNone, 1, 0x61, StackBehaviour.Pop1_pop1, StackBehaviour.Push1, -1 }; } [Theory] [MemberData(nameof(TestData))] - public void VerifyOpCode(OpCode opCode, string name, OpCodeType opCodeType, OperandType operandType, int size, int value, StackBehaviour stackBehaviourPop, StackBehaviour stackBehaviourPush) + public void VerifyOpCode(OpCode opCode, string name, OpCodeType opCodeType, OperandType operandType, int size, int value, StackBehaviour stackBehaviourPop, StackBehaviour stackBehaviourPush, int evaluationStackDelta) { Assert.Equal(name, opCode.Name); Assert.Equal(opCodeType, opCode.OpCodeType); @@ -250,6 +250,7 @@ public void VerifyOpCode(OpCode opCode, string name, OpCodeType opCodeType, Oper Assert.Equal((short)value, opCode.Value); Assert.Equal(stackBehaviourPop, opCode.StackBehaviourPop); Assert.Equal(stackBehaviourPush, opCode.StackBehaviourPush); + Assert.Equal(evaluationStackDelta, opCode.EvaluationStackDelta); Assert.Equal(name, opCode.ToString()); Assert.Equal(opCode.GetHashCode(), opCode.GetHashCode()); From b6721c1944de165499378d2673d66ab76098fb39 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Wed, 25 Oct 2023 09:30:56 -0700 Subject: [PATCH 11/11] Update doc remarks --- .../src/System/Reflection/Emit/Opcode.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs index ae780604cb1634..3f29e6e0e35167 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/Opcode.cs @@ -50,8 +50,11 @@ internal bool EndsUncondJmpBlk() => /// /// /// The difference between how many elements are popped from the stack and how many are pushed onto the stack as a result of the IL instruction. - /// For some IL instructions like this value is not fixed and depends on the called reference signature, for example if it is - /// calling a method, depends on the method signature (push count depends on the returning a value, pop count depends how many parameters passed). + /// For some IL instructions like stack change is not fixed and depends on the called reference signature. + /// For such the returns 0. In this case you should not rely on + /// for calculating stack size and/or max stack, instead need to evaluate the reference signature. + /// For example, in case the instruction is calling a method reference, need to evaluate the method signature, + /// the push count depends on the returning value, the pop count depends on how many parameters passed. /// public int EvaluationStackDelta => m_flags >> StackChangeShift;