/// <summary> /// Validates an actual exception handling clause (the cloned version) against an expected one (its source). /// </summary> /// <param name="actualLocalVariable">Local variable to validate.</param> /// <param name="expectedLocalVariable">Local variable with expected info.</param> private static void ValidateLocalVariable(LocalVariableInfo actualLocalVariable, LocalVariableInfo expectedLocalVariable) { Assert.That(actualLocalVariable == null, Is.EqualTo(expectedLocalVariable == null)); if (actualLocalVariable == null) { return; } Assert.That(actualLocalVariable.IsPinned, Is.EqualTo(expectedLocalVariable.IsPinned)); Assert.That(actualLocalVariable.LocalIndex, Is.EqualTo(expectedLocalVariable.LocalIndex)); }
public static uint GetStackCountForLocal(MethodInfo aMethod, LocalVariableInfo aField) { var xSize = SizeOfType(aField.LocalType); var xResult = xSize / 4; if (xSize % 4 != 0) { xResult++; } return xResult; }
public MSIL_MethodResolver(System.Reflection.MethodBase Method) : base(Method.DeclaringType.Module) { System.Reflection.MethodBody body = Method.GetMethodBody(); if (Method.GetMethodBody() != null) { foreach (System.Reflection.LocalVariableInfo localsBody in body.LocalVariables) { System.Reflection.LocalVariableInfo _WAR_local = localsBody; _locals.Add(_WAR_local.LocalIndex, _WAR_local); } } }
void PushAsBoolean(CompilerState state, LocalVariableInfo local) { if (state == null) throw new Exception(); if (local == null) throw new Exception(); Label l1 = state.Generator.DefineLabel(); Label l2 = state.Generator.DefineLabel(); LoadLocalVariable(state, local); if (local.LocalType == typeof(Int32)) { state.Generator.Emit(OpCodes.Brfalse, l1); } else if (local.LocalType == typeof(Single)) { state.Generator.Emit(OpCodes.Ldc_R4, 0); state.Generator.Emit(OpCodes.Beq, l1); } else { throw new Exception(); } state.Generator.Emit(OpCodes.Ldc_I4_1); state.Generator.Emit(OpCodes.Br, l2); state.Generator.MarkLabel(l1); state.Generator.Emit(OpCodes.Ldc_I4_0); state.Generator.MarkLabel(l2); }
void StoreLocalVariable(CompilerState state, LocalVariableInfo local) { if (state == null) throw new Exception(); if (local == null) throw new Exception(); switch (local.LocalIndex) { case 0: state.Generator.Emit(OpCodes.Stloc_0); break; case 1: state.Generator.Emit(OpCodes.Stloc_1); break; case 2: state.Generator.Emit(OpCodes.Stloc_2); break; case 3: state.Generator.Emit(OpCodes.Stloc_3); break; default: state.Generator.Emit(OpCodes.Stloc, local.LocalIndex); break; } }
void CheckIfZero(CompilerState state, LocalVariableInfo local) { if (state == null) throw new Exception(); if (local == null) throw new Exception(); if (local.LocalType == typeof(Int32)) { LoadLocalVariable(state, local); state.Generator.Emit(OpCodes.Ldc_I4_0); state.Generator.Emit(OpCodes.Beq, state.ErrorLabel); } if (local.LocalType == typeof(Single)) { LoadLocalVariable(state, local); state.Generator.Emit(OpCodes.Ldc_R4, 0.0f); state.Generator.Emit(OpCodes.Beq, state.ErrorLabel); } }
LocalVariableInfo EmitArithmeticOperator(CompilerState state, OpCode msilcode, LocalVariableInfo lhs, LocalVariableInfo rhs) { if (state == null) throw new Exception(); if (lhs == null) throw new Exception(); if (rhs == null) throw new Exception(); if (msilcode == OpCodes.Div) CheckIfZero(state, rhs); LocalVariableInfo result; if (lhs.LocalType == typeof(Int32) && rhs.LocalType == typeof(Int32)) { result = state.Generator.DeclareLocal(typeof(Int32)); LoadLocalVariable(state, lhs); LoadLocalVariable(state, rhs); } else { result = state.Generator.DeclareLocal(typeof(Single)); LoadLocalVariable(state, lhs); state.Generator.Emit(OpCodes.Conv_R4); LoadLocalVariable(state, rhs); state.Generator.Emit(OpCodes.Conv_R4); } state.Generator.Emit(msilcode); StoreLocalVariable(state, result); return result; }
LocalVariableInfo EmitComparsionOperator(CompilerState state, Operator @operator, LocalVariableInfo lhs, LocalVariableInfo rhs) { if (state == null) throw new Exception(); if (lhs == null) throw new Exception(); if (rhs == null) throw new Exception(); LocalVariableInfo result = state.Generator.DeclareLocal(typeof(Int32)); if (lhs.LocalType == typeof(Int32) && rhs.LocalType == typeof(Int32)) { LoadLocalVariable(state, lhs); LoadLocalVariable(state, rhs); } else { LoadLocalVariable(state, lhs); state.Generator.Emit(OpCodes.Conv_R4); LoadLocalVariable(state, rhs); state.Generator.Emit(OpCodes.Conv_R4); } switch (@operator) { case Operator.Equals: state.Generator.Emit(OpCodes.Ceq); StoreLocalVariable(state, result); break; case Operator.NotEquals: state.Generator.Emit(OpCodes.Ceq); state.Generator.Emit(OpCodes.Ldc_I4_0); state.Generator.Emit(OpCodes.Ceq); StoreLocalVariable(state, result); break; case Operator.Lesser: state.Generator.Emit(OpCodes.Clt); StoreLocalVariable(state, result); break; case Operator.LesserEquals: state.Generator.Emit(OpCodes.Cgt); state.Generator.Emit(OpCodes.Ldc_I4_0); state.Generator.Emit(OpCodes.Ceq); StoreLocalVariable(state, result); break; case Operator.Greater: state.Generator.Emit(OpCodes.Cgt); StoreLocalVariable(state, result); break; case Operator.GreaterEquals: state.Generator.Emit(OpCodes.Clt); state.Generator.Emit(OpCodes.Ldc_I4_0); state.Generator.Emit(OpCodes.Ceq); StoreLocalVariable(state, result); break; default: throw new Exception(); } return result; }
LocalVariableInfo EmitLogicalOperator(CompilerState state, Operator @operator, LocalVariableInfo lhs, LocalVariableInfo rhs) { if (state == null) throw new Exception(); if (lhs == null) throw new Exception(); if (rhs == null) throw new Exception(); LocalVariableInfo result = state.Generator.DeclareLocal(typeof(Int32)); PushAsBoolean(state, lhs); PushAsBoolean(state, rhs); switch (@operator) { case Operator.LogicalAnd: state.Generator.Emit(OpCodes.And); StoreLocalVariable(state, result); break; case Operator.LogicalOr: state.Generator.Emit(OpCodes.Or); StoreLocalVariable(state, result); break; case Operator.LogicalXor: state.Generator.Emit(OpCodes.Xor); StoreLocalVariable(state, result); break; default: throw new Exception(); } return result; }
public static void StoreLocal(LocalVariableInfo local, ILGenerator body) { EmitSpecific((short) local.LocalIndex, storeLocal, OpCodes.Stloc, body); }
public static void LoadLocal(LocalVariableInfo local, ILGenerator body) { EmitSpecific((short) local.LocalIndex, loadLocal, OpCodes.Ldloc, body); }
public static ILGenerator ldloca(this ILGenerator il, LocalVariableInfo variable) { if (variable.LocalIndex > byte.MaxValue) il.Emit(OpCodes.Ldloca, variable.LocalIndex); else il.Emit(OpCodes.Ldloca_S, (byte) variable.LocalIndex); return il; }
public static ILGenerator ldloc(this ILGenerator il, LocalVariableInfo variable) { if (variable.LocalIndex < 4) switch (variable.LocalIndex) { case (0): il.Emit(OpCodes.Ldloc_0); return il; case (1): il.Emit(OpCodes.Ldloc_1); return il; case (2): il.Emit(OpCodes.Ldloc_2); return il; case (3): il.Emit(OpCodes.Ldloc_3); return il; default: throw new ArgumentOutOfRangeException("variable", "Variable index should be positive"); } if (variable.LocalIndex > byte.MaxValue) il.Emit(OpCodes.Ldloc, variable.LocalIndex); else il.Emit(OpCodes.Ldloc_S, (byte) variable.LocalIndex); return il; }
public static void emit(System.Reflection.Emit.OpCode OpCode, object Data, System.Reflection.Emit.ILGenerator Generator) { if (OpCode.FlowControl == System.Reflection.Emit.FlowControl.Branch || OpCode.FlowControl == System.Reflection.Emit.FlowControl.Cond_Branch) { if (Data is System.Reflection.Emit.Label) { Generator.Emit(OpCode, ((System.Reflection.Emit.Label)Data)); } else { throw new Exception("Invalid data. The target of a branch has to substituted by a label before beeing emitted"); } } else if (OpCode.FlowControl == System.Reflection.Emit.FlowControl.Call) { Generator.EmitCall(OpCode, Data as System.Reflection.MethodInfo, null); } else { if (Data is System.Reflection.LocalVariableInfo) { System.Reflection.LocalVariableInfo info = Data as System.Reflection.LocalVariableInfo; if (OpCode == System.Reflection.Emit.OpCodes.Ldloc || OpCode == System.Reflection.Emit.OpCodes.Ldloc_S || OpCode == System.Reflection.Emit.OpCodes.Ldloc_0 || OpCode == System.Reflection.Emit.OpCodes.Ldloc_1 || OpCode == System.Reflection.Emit.OpCodes.Ldloc_2 || OpCode == System.Reflection.Emit.OpCodes.Ldloc_3) { switch (info.LocalIndex) { case 0: Generator.Emit(System.Reflection.Emit.OpCodes.Ldloc_0); break; case 1: Generator.Emit(System.Reflection.Emit.OpCodes.Ldloc_1); break; case 2: Generator.Emit(System.Reflection.Emit.OpCodes.Ldloc_2); break; case 3: Generator.Emit(System.Reflection.Emit.OpCodes.Ldloc_3); break; default: if (info.LocalIndex < 256) { Generator.Emit(System.Reflection.Emit.OpCodes.Ldloc_S, (byte)info.LocalIndex); } else { Generator.Emit(System.Reflection.Emit.OpCodes.Ldloc, info.LocalIndex); } break; } } else if (OpCode == System.Reflection.Emit.OpCodes.Stloc || OpCode == System.Reflection.Emit.OpCodes.Stloc_S || OpCode == System.Reflection.Emit.OpCodes.Stloc_0 || OpCode == System.Reflection.Emit.OpCodes.Stloc_1 || OpCode == System.Reflection.Emit.OpCodes.Stloc_2 || OpCode == System.Reflection.Emit.OpCodes.Stloc_3) { switch (info.LocalIndex) { case 0: Generator.Emit(System.Reflection.Emit.OpCodes.Stloc_0); break; case 1: Generator.Emit(System.Reflection.Emit.OpCodes.Stloc_1); break; case 2: Generator.Emit(System.Reflection.Emit.OpCodes.Stloc_2); break; case 3: Generator.Emit(System.Reflection.Emit.OpCodes.Stloc_3); break; default: if (info.LocalIndex < 256) { Generator.Emit(System.Reflection.Emit.OpCodes.Stloc_S, (byte)info.LocalIndex); } else { Generator.Emit(System.Reflection.Emit.OpCodes.Stloc, info.LocalIndex); } break; } } else { throw new InvalidProgramException("Invalid OpCode and Data combinaison: " + OpCode.ToString() + " " + Data.ToString()); } } else if (OpCode == System.Reflection.Emit.OpCodes.Ldarg_0 || OpCode == System.Reflection.Emit.OpCodes.Ldarg_1 || OpCode == System.Reflection.Emit.OpCodes.Ldarg_2 || OpCode == System.Reflection.Emit.OpCodes.Ldarg_3 || OpCode == System.Reflection.Emit.OpCodes.Ldarg_S) { int argIndx = (int)Data; switch (argIndx) { case 0: Generator.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); break; case 1: Generator.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); break; case 2: Generator.Emit(System.Reflection.Emit.OpCodes.Ldarg_2); break; case 3: Generator.Emit(System.Reflection.Emit.OpCodes.Ldarg_3); break; default: if (argIndx < 256) { Generator.Emit(System.Reflection.Emit.OpCodes.Ldarg_S, (byte)argIndx); } else { Generator.Emit(System.Reflection.Emit.OpCodes.Ldarg, argIndx); } break; } } else { if (Data == null) { Generator.Emit(OpCode); } else if (Data is int) { Generator.Emit(OpCode, (int)Data); } else if (Data is byte) { Generator.Emit(OpCode, (byte)Data); } else if (Data is double) { Generator.Emit(OpCode, (double)Data); } else if (Data is float) { Generator.Emit(OpCode, (float)Data); } else if (Data is FieldInfo) { Generator.Emit(OpCode, (FieldInfo)Data); } else if (Data is long) { Generator.Emit(OpCode, (long)Data); } else if (Data is Type) { Generator.Emit(OpCode, (Type)Data); } else if (Data is ConstructorInfo) { Generator.Emit(OpCode, (ConstructorInfo)Data); } else { throw new InvalidProgramException("Invalid OpCode and Data combinaison: " + OpCode.ToString() + " " + Data.ToString()); } } } }
/// <summary> /// Implements the special treatment of a particular local variable. /// </summary> /// <param name="lvi">information on local variable</param> /// <param name="decomp">decompiler instance</param> public virtual void ImplementDeclaration(LocalVariableInfo lvi, IDecompiler decomp) { throw new NotSupportedException("Declaration as local variable is not allowed"); }