public static void WriteInstruction (TextWriter writer, Instruction instruction) { writer.Write (FormatLabel (instruction.Offset)); writer.Write (": "); writer.Write (instruction.OpCode.Name); WriteOperand (writer, instruction); }
public ProcessorState(Stack<Address> stack, VariableInfo[] locals, IList<Address> args, Instruction instruction, Instruction last = null, IDictionary<FieldInfo, Address> delegates = null) { Delegates = delegates ?? new Dictionary<FieldInfo, Address>(); Stack = stack; Locals = locals; Args = args; Instruction = instruction; Last = last; }
public Expression Process(Instruction instruction, Type returnType) { var ex = AdjustType(Process(instruction), returnType); if (ex.Type != returnType && returnType != typeof(void)) { return Expression.Convert(ex, returnType); } return ex; }
private static OpCode OpCodeFor(MR.Instruction instruction) { foreach (var opcode in _opcodes) { if (opcode.Value == instruction.OpCode.Value) { return(opcode); } } throw new NotSupportedException("OpCode not found: " + instruction.OpCode.Name); }
public static Expression Process(VariableInfo[] locals, IList<Address> args, Instruction instruction, Type returnType) { Processor processor = new Processor(); processor.states.Push(new ProcessorState(new Stack<Address>(), locals, args, instruction)); var ex = AdjustType(processor.Process(), returnType); if (ex.Type != returnType && returnType != typeof(void)) { return Expression.Convert(ex, returnType); } return ex; }
public ProcessorState Clone(Instruction instruction, Instruction last = null) { var state = new ProcessorState(null, new VariableInfo[Locals.Length], Args.ToArray(), instruction, last, Delegates); var addressMap = new Dictionary<Address, Address>(); var buffer = new List<Address>(); foreach (var address in Stack) { buffer.Add(address.Clone(addressMap)); } state.Stack = new Stack<Address>(Enumerable.Reverse(buffer)); for (int i = 0; i < Locals.Length; i++) { state.Locals[i] = new VariableInfo(Locals[i].Type); state.Locals[i].Address = Locals[i].Address.Clone(addressMap); } return state; }
void ReadOperand(Instruction instruction) { switch (instruction.OpCode.OperandType) { case OperandType.InlineNone: break; case OperandType.InlineSwitch: int length = il.ReadInt32(); int base_offset = il.position + (4 * length); int[] branches = new int[length]; for (int i = 0; i < length; i++) branches[i] = il.ReadInt32() + base_offset; instruction.Operand = branches; break; case OperandType.ShortInlineBrTarget: instruction.Operand = (((sbyte)il.ReadByte()) + il.position); break; case OperandType.InlineBrTarget: instruction.Operand = il.ReadInt32() + il.position; break; case OperandType.ShortInlineI: if (instruction.OpCode == OpCodes.Ldc_I4_S) instruction.Operand = (sbyte)il.ReadByte(); else instruction.Operand = il.ReadByte(); break; case OperandType.InlineI: instruction.Operand = il.ReadInt32(); break; case OperandType.ShortInlineR: instruction.Operand = il.ReadSingle(); break; case OperandType.InlineR: instruction.Operand = il.ReadDouble(); break; case OperandType.InlineI8: instruction.Operand = il.ReadInt64(); break; case OperandType.InlineSig: instruction.Operand = module.ResolveSignature(il.ReadInt32()); break; case OperandType.InlineString: instruction.Operand = module.ResolveString(il.ReadInt32()); break; case OperandType.InlineTok: case OperandType.InlineType: case OperandType.InlineMethod: case OperandType.InlineField: instruction.Operand = module.ResolveMember(il.ReadInt32(), type_arguments, method_arguments); break; case OperandType.ShortInlineVar: instruction.Operand = GetVariable(instruction, il.ReadByte()); break; case OperandType.InlineVar: instruction.Operand = GetVariable(instruction, il.ReadInt16()); break; default: throw new NotSupportedException(); } }
static string FormatLabel (Instruction instruction) { return FormatLabel (instruction.Offset); }
private void ReadOperand(Instruction instruction) { switch (instruction.OpCode.OperandType) { case OperandType.InlineNone: break; case OperandType.InlineSwitch: int length = il.ReadInt32(); int[] branches = new int[length]; int[] offsets = new int[length]; for (int i = 0; i < length; i++) offsets[i] = il.ReadInt32(); for (int i = 0; i < length; i++) branches[i] = il.position + offsets[i]; instruction.Operand = branches; break; case OperandType.ShortInlineBrTarget: instruction.Operand = (sbyte) (il.ReadByte() + il.position); break; case OperandType.InlineBrTarget: instruction.Operand = il.ReadInt32() + il.position; break; case OperandType.ShortInlineI: if (instruction.OpCode == OpCodes.Ldc_I4_S) instruction.Operand = (sbyte) il.ReadByte(); else instruction.Operand = il.ReadByte(); break; case OperandType.InlineI: instruction.Operand = il.ReadInt32(); break; case OperandType.ShortInlineR: instruction.Operand = il.ReadSingle(); break; case OperandType.InlineR: instruction.Operand = il.ReadDouble(); break; case OperandType.InlineI8: instruction.Operand = il.ReadInt64(); break; case OperandType.InlineSig: byte[] resolveSignature = module.ResolveSignature(il.ReadInt32()); instruction.Operand = resolveSignature; break; case OperandType.InlineString: string resolveString = module.ResolveString(il.ReadInt32()); instruction.Operand = resolveString; break; case OperandType.InlineTok: MemberInfo resolveMember = module.ResolveMember(il.ReadInt32(), generic_type_arguments, method_arguments); instruction.Operand = resolveMember; break; case OperandType.InlineType: Type resolveType = module.ResolveType(il.ReadInt32(), generic_type_arguments, method_arguments); instruction.Operand = resolveType; break; case OperandType.InlineMethod: MethodBase resolveMethod = module.ResolveMethod(il.ReadInt32(), generic_type_arguments, method_arguments); instruction.Operand = resolveMethod; break; case OperandType.InlineField: FieldInfo resolveField = module.ResolveField(il.ReadInt32(), generic_type_arguments, method_arguments); instruction.Operand = resolveField; break; case OperandType.ShortInlineVar: object variable = GetVariable(instruction, il.ReadByte()); instruction.Operand = variable; break; case OperandType.InlineVar: object operand = GetVariable(instruction, il.ReadInt16()); instruction.Operand = operand; break; default: throw new NotSupportedException(); } }
internal void Advance () { instruction = instruction.Next; }
internal MatchContext (Instruction instruction) { Reset(instruction); }
public JoinPointState(Instruction left, Instruction right) { Left = left; Right = right; LeftInstructions = new Stack<Instruction>(); RightInstructions = new Stack<Instruction>(); }
internal void Advance () { this.instruction = this.instruction.Next; }
Instruction ConditionalBranch(Instruction instruction, Func<Expression, BinaryExpression> condition) { var val1 = stack.Pop(); var test = condition(val1); var left = (Instruction)instruction.Operand; var right = instruction.Next; Instruction common = GetJoinPoint(left, right); var rightExpression = Clone().Process(right, common); var leftExpression = AdjustType(Clone().Process(left, common), rightExpression.Type); var expression = BuildConditionalBranch(test, val1, leftExpression, rightExpression); stack.Push(expression); return common; }
static Instruction GetJoinPoint(Instruction left, Instruction right) { return GetCommon(GetFlow(left), GetFlow(right)); }
static Stack<Instruction> GetFlow(Instruction instruction) { var instructions = new Stack<Instruction>(); while (instruction != null) { instructions.Push(instruction); if (instruction.OpCode.FlowControl == FlowControl.Return) break; if (instruction.OpCode.FlowControl == FlowControl.Branch) { instruction = (Instruction) instruction.Operand; } else if (instruction.OpCode.FlowControl == FlowControl.Cond_Branch) { instruction = GetJoinPoint((Instruction) instruction.Operand, instruction.Next); } else { instruction = instruction.Next; } } return instructions; }
public Expression Process(Instruction instruction, Instruction last = null) { while(instruction != null && instruction != last) { Debug.WriteLine(instruction); if (instruction.OpCode == OpCodes.Nop || instruction.OpCode == OpCodes.Break) { //do nothing; } else if (instruction.OpCode == OpCodes.Ldarg_0) { LdArg(0); } else if (instruction.OpCode == OpCodes.Ldarg_1) { LdArg(1); } else if (instruction.OpCode == OpCodes.Ldarg_2) { LdArg(2); } else if (instruction.OpCode == OpCodes.Ldarg_3) { LdArg(3); } else if (instruction.OpCode == OpCodes.Ldarg_S) { LdArg((short) instruction.Operand); } else if (instruction.OpCode == OpCodes.Ldarg) { LdArg((int) instruction.Operand); } else if (instruction.OpCode == OpCodes.Ldarga || instruction.OpCode == OpCodes.Ldarga_S) { var operand = (ParameterInfo) instruction.Operand; stack.Push(args.Single(x => x.Name == operand.Name)); } else if (instruction.OpCode == OpCodes.Ldlen) { var array = stack.Pop(); stack.Push(Expression.ArrayLength(array)); } else if (instruction.OpCode == OpCodes.Ldelem || instruction.OpCode == OpCodes.Ldelem_I || instruction.OpCode == OpCodes.Ldelem_I1 || instruction.OpCode == OpCodes.Ldelem_I2 || instruction.OpCode == OpCodes.Ldelem_I4 || instruction.OpCode == OpCodes.Ldelem_I8 || instruction.OpCode == OpCodes.Ldelem_U1 || instruction.OpCode == OpCodes.Ldelem_U2 || instruction.OpCode == OpCodes.Ldelem_U4 || instruction.OpCode == OpCodes.Ldelem_R4 || instruction.OpCode == OpCodes.Ldelem_R8 || instruction.OpCode == OpCodes.Ldelem_Ref) { var index = stack.Pop(); var array = stack.Pop(); stack.Push(Expression.ArrayIndex(array, index)); } else if (instruction.OpCode == OpCodes.Stloc_0) { StLoc(0); } else if (instruction.OpCode == OpCodes.Stloc_1) { StLoc(1); } else if (instruction.OpCode == OpCodes.Stloc_2) { StLoc(2); } else if (instruction.OpCode == OpCodes.Stloc_3) { StLoc(3); } else if (instruction.OpCode == OpCodes.Stloc_S) { StLoc((byte) instruction.Operand); } else if (instruction.OpCode == OpCodes.Stloc) { StLoc((int) instruction.Operand); } else if (instruction.OpCode == OpCodes.Stelem || instruction.OpCode == OpCodes.Stelem_I || instruction.OpCode == OpCodes.Stelem_I1 || instruction.OpCode == OpCodes.Stelem_I2 || instruction.OpCode == OpCodes.Stelem_I4 || instruction.OpCode == OpCodes.Stelem_I8 || instruction.OpCode == OpCodes.Stelem_R4 || instruction.OpCode == OpCodes.Stelem_R8 || instruction.OpCode == OpCodes.Stelem_Ref) { StElem(); } else if (instruction.OpCode == OpCodes.Ldnull) { stack.Push(Expression.Constant(null)); } else if (instruction.OpCode == OpCodes.Ldfld || instruction.OpCode == OpCodes.Ldflda) { var instance = stack.Pop(); stack.Push(Expression.Field(instance, (FieldInfo) instruction.Operand)); } else if (instruction.OpCode == OpCodes.Ldsfld) { var targetField = instruction.Operand as FieldInfo; if (IsCachedAnonymousMethodDelegate(targetField)) { // do nothing. } else { stack.Push(Expression.Field(null, (FieldInfo) instruction.Operand)); } } else if (instruction.OpCode == OpCodes.Ldloc_0) { LdLoc(0); } else if (instruction.OpCode == OpCodes.Ldloc_1) { LdLoc(1); } else if (instruction.OpCode == OpCodes.Ldloc_2) { LdLoc(2); } else if (instruction.OpCode == OpCodes.Ldloc_3) { LdLoc(3); } else if (instruction.OpCode == OpCodes.Ldloc_S) { LdLoc((byte) instruction.Operand); } else if (instruction.OpCode == OpCodes.Ldloc) { LdLoc((int) instruction.Operand); } else if (instruction.OpCode == OpCodes.Ldloca || instruction.OpCode == OpCodes.Ldloca_S) { var operand = (LocalVariableInfo) instruction.Operand; LdLoc(operand.LocalIndex); } else if (instruction.OpCode == OpCodes.Ldstr) { stack.Push(Expression.Constant((string) instruction.Operand)); } else if (instruction.OpCode == OpCodes.Ldc_I4_0) { LdC(0); } else if (instruction.OpCode == OpCodes.Ldc_I4_1) { LdC(1); } else if (instruction.OpCode == OpCodes.Ldc_I4_2) { LdC(2); } else if (instruction.OpCode == OpCodes.Ldc_I4_3) { LdC(3); } else if (instruction.OpCode == OpCodes.Ldc_I4_4) { LdC(4); } else if (instruction.OpCode == OpCodes.Ldc_I4_5) { LdC(5); } else if (instruction.OpCode == OpCodes.Ldc_I4_6) { LdC(6); } else if (instruction.OpCode == OpCodes.Ldc_I4_7) { LdC(7); } else if (instruction.OpCode == OpCodes.Ldc_I4_8) { LdC(8); } else if (instruction.OpCode == OpCodes.Ldc_I4_S) { LdC((sbyte) instruction.Operand); } else if (instruction.OpCode == OpCodes.Ldc_I4_M1) { LdC(-1); } else if (instruction.OpCode == OpCodes.Ldc_I4) { LdC((int) instruction.Operand); } else if (instruction.OpCode == OpCodes.Ldc_I8) { LdC((long) instruction.Operand); } else if (instruction.OpCode == OpCodes.Ldc_R4) { LdC((float) instruction.Operand); } else if (instruction.OpCode == OpCodes.Ldc_R8) { LdC((double) instruction.Operand); } else if (instruction.OpCode == OpCodes.Br_S || instruction.OpCode == OpCodes.Br) { instruction = (Instruction) instruction.Operand; continue; } else if (instruction.OpCode == OpCodes.Brfalse || instruction.OpCode == OpCodes.Brfalse_S) { instruction = ConditionalBranch(instruction, val => Expression.Equal(val, Default(val.Type))); continue; } else if (instruction.OpCode == OpCodes.Brtrue || instruction.OpCode == OpCodes.Brtrue_S) { var target = ((Instruction) instruction.Operand); if (target.OpCode == OpCodes.Ldsfld && IsCachedAnonymousMethodDelegate(target.Operand as FieldInfo)) { stack.Push(((MethodInfo) instruction.Next.Next.Operand).Decompile()); instruction = (Instruction) instruction.Operand; } else { instruction = ConditionalBranch(instruction, val => Expression.NotEqual(val, Default(val.Type))); } continue; } else if (instruction.OpCode == OpCodes.Bgt || instruction.OpCode == OpCodes.Bgt_S || instruction.OpCode == OpCodes.Bgt_Un || instruction.OpCode == OpCodes.Bgt_Un_S) { var val1 = stack.Pop(); instruction = ConditionalBranch(instruction, val => Expression.GreaterThan(val, val1)); continue; } else if (instruction.OpCode == OpCodes.Bge || instruction.OpCode == OpCodes.Bge_S || instruction.OpCode == OpCodes.Bge_Un || instruction.OpCode == OpCodes.Bge_Un_S) { var val1 = stack.Pop(); instruction = ConditionalBranch(instruction, val => Expression.GreaterThanOrEqual(val, val1)); continue; } else if (instruction.OpCode == OpCodes.Blt || instruction.OpCode == OpCodes.Blt_S || instruction.OpCode == OpCodes.Blt_Un || instruction.OpCode == OpCodes.Blt_Un_S) { var val1 = stack.Pop(); instruction = ConditionalBranch(instruction, val => Expression.LessThan(val, val1)); continue; } else if (instruction.OpCode == OpCodes.Ble || instruction.OpCode == OpCodes.Ble_S || instruction.OpCode == OpCodes.Ble_Un || instruction.OpCode == OpCodes.Ble_Un_S) { var val1 = stack.Pop(); instruction = ConditionalBranch(instruction, val => Expression.LessThanOrEqual(val, val1)); continue; } else if (instruction.OpCode == OpCodes.Beq || instruction.OpCode == OpCodes.Beq_S) { var val1 = stack.Pop(); instruction = ConditionalBranch(instruction, val => AdjustedBinaryExpression(val, val1, ExpressionType.Equal)); continue; } else if (instruction.OpCode == OpCodes.Bne_Un || instruction.OpCode == OpCodes.Bne_Un_S) { var val1 = stack.Pop(); instruction = ConditionalBranch(instruction, val => AdjustedBinaryExpression(val, val1, ExpressionType.NotEqual)); continue; } else if (instruction.OpCode == OpCodes.Dup) { stack.Push(stack.Peek()); } else if (instruction.OpCode == OpCodes.Pop) { stack.Pop(); } else if (instruction.OpCode == OpCodes.Add) { var val1 = stack.Pop(); var val2 = stack.Pop(); stack.Push(Expression.Add(val2, val1)); } else if (instruction.OpCode == OpCodes.Add_Ovf || instruction.OpCode == OpCodes.Add_Ovf_Un) { var val1 = stack.Pop(); var val2 = stack.Pop(); stack.Push(Expression.AddChecked(val2, val1)); } else if (instruction.OpCode == OpCodes.Sub) { var val1 = stack.Pop(); var val2 = stack.Pop(); stack.Push(Expression.Subtract(val2, val1)); } else if (instruction.OpCode == OpCodes.Sub_Ovf || instruction.OpCode == OpCodes.Sub_Ovf_Un) { var val1 = stack.Pop(); var val2 = stack.Pop(); stack.Push(Expression.SubtractChecked(val2, val1)); } else if (instruction.OpCode == OpCodes.Mul) { var val1 = stack.Pop(); var val2 = stack.Pop(); stack.Push(Expression.Multiply(val2, val1)); } else if (instruction.OpCode == OpCodes.Mul_Ovf || instruction.OpCode == OpCodes.Mul_Ovf_Un) { var val1 = stack.Pop(); var val2 = stack.Pop(); stack.Push(Expression.MultiplyChecked(val2, val1)); } else if (instruction.OpCode == OpCodes.Div || instruction.OpCode == OpCodes.Div_Un) { var val1 = stack.Pop(); var val2 = stack.Pop(); stack.Push(Expression.Divide(val2, val1)); } else if (instruction.OpCode == OpCodes.Rem || instruction.OpCode == OpCodes.Rem_Un) { var val1 = stack.Pop(); var val2 = stack.Pop(); stack.Push(Expression.Modulo(val2, val1)); } else if (instruction.OpCode == OpCodes.Xor) { var val1 = stack.Pop(); var val2 = stack.Pop(); stack.Push(Expression.ExclusiveOr(val2, val1)); } else if (instruction.OpCode == OpCodes.Shl) { var val1 = stack.Pop(); var val2 = stack.Pop(); stack.Push(Expression.LeftShift(val2, val1)); } else if (instruction.OpCode == OpCodes.Shr || instruction.OpCode == OpCodes.Shr_Un) { var val1 = stack.Pop(); var val2 = stack.Pop(); stack.Push(Expression.RightShift(val2, val1)); } else if (instruction.OpCode == OpCodes.Neg) { var val = stack.Pop(); stack.Push(Expression.Negate(val)); } else if (instruction.OpCode == OpCodes.Not) { var val = stack.Pop(); stack.Push(Expression.Not(val)); } else if (instruction.OpCode == OpCodes.Conv_I) { var val1 = stack.Pop(); stack.Push(Expression.Convert(val1, typeof (int))); // Support x64? } else if (instruction.OpCode == OpCodes.Conv_I1) { var val1 = stack.Pop(); stack.Push(Expression.Convert(val1, typeof (sbyte))); } else if (instruction.OpCode == OpCodes.Conv_I2) { var val1 = stack.Pop(); stack.Push(Expression.Convert(val1, typeof (short))); } else if (instruction.OpCode == OpCodes.Conv_I4) { var val1 = stack.Pop(); stack.Push(Expression.Convert(val1, typeof (int))); } else if (instruction.OpCode == OpCodes.Conv_I8) { var val1 = stack.Pop(); stack.Push(Expression.Convert(val1, typeof (long))); } else if (instruction.OpCode == OpCodes.Conv_U) { var val1 = stack.Pop(); stack.Push(Expression.Convert(val1, typeof (uint))); // Suppot x64? } else if (instruction.OpCode == OpCodes.Conv_U1) { var val1 = stack.Pop(); stack.Push(Expression.Convert(val1, typeof (byte))); } else if (instruction.OpCode == OpCodes.Conv_U2) { var val1 = stack.Pop(); stack.Push(Expression.Convert(val1, typeof (ushort))); } else if (instruction.OpCode == OpCodes.Conv_U4) { var val1 = stack.Pop(); stack.Push(Expression.Convert(val1, typeof (uint))); } else if (instruction.OpCode == OpCodes.Conv_U8) { var val1 = stack.Pop(); stack.Push(Expression.Convert(val1, typeof (ulong))); } else if (instruction.OpCode == OpCodes.Conv_Ovf_I || instruction.OpCode == OpCodes.Conv_Ovf_I_Un) { var val1 = stack.Pop(); stack.Push(Expression.ConvertChecked(val1, typeof (int))); // Suppot x64? } else if (instruction.OpCode == OpCodes.Conv_Ovf_I1 || instruction.OpCode == OpCodes.Conv_Ovf_I1_Un) { var val1 = stack.Pop(); stack.Push(Expression.ConvertChecked(val1, typeof (sbyte))); } else if (instruction.OpCode == OpCodes.Conv_Ovf_I2 || instruction.OpCode == OpCodes.Conv_Ovf_I2_Un) { var val1 = stack.Pop(); stack.Push(Expression.ConvertChecked(val1, typeof (short))); } else if (instruction.OpCode == OpCodes.Conv_Ovf_I4 || instruction.OpCode == OpCodes.Conv_Ovf_I4_Un) { var val1 = stack.Pop(); stack.Push(Expression.ConvertChecked(val1, typeof (int))); } else if (instruction.OpCode == OpCodes.Conv_Ovf_I8 || instruction.OpCode == OpCodes.Conv_Ovf_I8_Un) { var val1 = stack.Pop(); stack.Push(Expression.ConvertChecked(val1, typeof (long))); } else if (instruction.OpCode == OpCodes.Conv_Ovf_U || instruction.OpCode == OpCodes.Conv_Ovf_U_Un) { var val1 = stack.Pop(); stack.Push(Expression.ConvertChecked(val1, typeof (uint))); // Suppot x64? } else if (instruction.OpCode == OpCodes.Conv_Ovf_U1 || instruction.OpCode == OpCodes.Conv_Ovf_U1_Un) { var val1 = stack.Pop(); stack.Push(Expression.ConvertChecked(val1, typeof (byte))); } else if (instruction.OpCode == OpCodes.Conv_Ovf_U2 || instruction.OpCode == OpCodes.Conv_Ovf_U2_Un) { var val1 = stack.Pop(); stack.Push(Expression.ConvertChecked(val1, typeof (ushort))); } else if (instruction.OpCode == OpCodes.Conv_Ovf_U4 || instruction.OpCode == OpCodes.Conv_Ovf_U4_Un) { var val1 = stack.Pop(); stack.Push(Expression.ConvertChecked(val1, typeof (uint))); } else if (instruction.OpCode == OpCodes.Conv_Ovf_U8 || instruction.OpCode == OpCodes.Conv_Ovf_U8_Un) { var val1 = stack.Pop(); stack.Push(Expression.ConvertChecked(val1, typeof (ulong))); } else if (instruction.OpCode == OpCodes.Conv_R4 || instruction.OpCode == OpCodes.Conv_R_Un) { var val1 = stack.Pop(); stack.Push(Expression.ConvertChecked(val1, typeof (float))); } else if (instruction.OpCode == OpCodes.Conv_R8) { var val1 = stack.Pop(); stack.Push(Expression.ConvertChecked(val1, typeof (double))); } else if (instruction.OpCode == OpCodes.Castclass) { var val1 = stack.Pop(); stack.Push(Expression.Convert(val1, (Type) instruction.Operand)); } else if (instruction.OpCode == OpCodes.And) { var val1 = stack.Pop(); var val2 = stack.Pop(); stack.Push(Expression.And(val2, val1)); } else if (instruction.OpCode == OpCodes.Or) { var val1 = stack.Pop(); var val2 = stack.Pop(); stack.Push(Expression.Or(val2, val1)); } else if (instruction.OpCode == OpCodes.Newobj) { var operand = (ConstructorInfo) instruction.Operand; stack.Push(Expression.New(operand, GetArguments(operand))); } else if (instruction.OpCode == OpCodes.Newarr) { var operand = (Type) instruction.Operand; var expression = stack.Pop(); var size = expression as ConstantExpression; if (size != null && (int) size.Value == 0) // optimization stack.Push(Expression.NewArrayInit(operand)); else stack.Push(Expression.NewArrayBounds(operand, expression)); } else if (instruction.OpCode == OpCodes.Box) { stack.Push(Box(stack.Pop(), (Type) instruction.Operand)); } else if (instruction.OpCode == OpCodes.Call || instruction.OpCode == OpCodes.Callvirt) { Call((MethodInfo) instruction.Operand); } else if (instruction.OpCode == OpCodes.Ceq) { var val1 = stack.Pop(); var val2 = stack.Pop(); stack.Push(AdjustedBinaryExpression(val2, AdjustType(val1, val2.Type), ExpressionType.Equal)); } else if (instruction.OpCode == OpCodes.Cgt || instruction.OpCode == OpCodes.Cgt_Un) { var val1 = stack.Pop(); var val2 = stack.Pop(); stack.Push(Expression.GreaterThan(val2, AdjustType(val1, val2.Type))); } else if (instruction.OpCode == OpCodes.Clt || instruction.OpCode == OpCodes.Clt_Un) { var val1 = stack.Pop(); var val2 = stack.Pop(); stack.Push(Expression.LessThan(val2, AdjustType(val1, val2.Type))); } else if (instruction.OpCode == OpCodes.Ret) { break; } instruction = instruction.Next; } return stack.Count == 0 ? Expression.Empty() : stack.Pop(); }
static void WriteLabelList (TextWriter writer, Instruction [] targets) { writer.Write ("("); for (int i = 0; i < targets.Length; i++) { if (i != 0) writer.Write (", "); writer.Write (FormatLabel (targets [i])); } writer.Write (")"); }
private SourceLocation? FindSourceLocation(Instruction instruction, MethodNode methodNode) { var sequencePoints = this.symbols.GetSequencePointsForMethod(methodNode); return sequencePoints.NearestSequencePoint(instruction).Location; }
static void WriteOperand (TextWriter writer, Instruction instruction) { var opcode = instruction.OpCode; var operand = instruction.Operand; if (opcode.OperandType == OperandType.InlineNone) return; writer.Write (' '); switch (opcode.OperandType) { case OperandType.ShortInlineBrTarget: case OperandType.InlineBrTarget: writer.Write (FormatLabel ((Instruction) operand)); return; case OperandType.InlineSwitch: WriteLabelList (writer, (Instruction []) operand); return; case OperandType.InlineString: writer.Write ("\"" + operand.ToString () + "\""); return; case OperandType.ShortInlineVar: case OperandType.InlineVar: if (TargetsLocalVariable (opcode)) { var local = (LocalVariableInfo) operand; writer.Write ("V_{0}", local.LocalIndex); return; } var parameter = (ParameterInfo) operand; writer.Write (parameter.Name); return; case OperandType.InlineTok: case OperandType.InlineType: case OperandType.InlineMethod: case OperandType.InlineField: var member = (MemberInfo) operand; switch (member.MemberType) { case MemberTypes.Constructor: case MemberTypes.Method: WriteMethodReference (writer, (MethodBase) member); return; case MemberTypes.Field: WriteFieldReference (writer, (FieldInfo) member); return; case MemberTypes.TypeInfo: case MemberTypes.NestedType: writer.Write (FormatTypeReference ((Type) member)); return; default: throw new NotSupportedException (); } case OperandType.InlineI: case OperandType.ShortInlineI: case OperandType.InlineR: case OperandType.ShortInlineR: case OperandType.InlineI8: writer.Write (ToInvariantCultureString (operand)); return; default: throw new NotSupportedException (); } }
void ResolveBranches() { foreach (var instruction in instructions) { switch (instruction.OpCode.OperandType) { case OperandType.ShortInlineBrTarget: case OperandType.InlineBrTarget: instruction.Operand = GetInstruction(instructions, (int)instruction.Operand); break; case OperandType.InlineSwitch: var offsets = (int[])instruction.Operand; var branches = new Instruction[offsets.Length]; for (int j = 0; j < offsets.Length; j++) branches[j] = GetInstruction(instructions, offsets[j]); instruction.Operand = branches; break; } } }
object GetVariable(Instruction instruction, int index) { return TargetsLocalVariable(instruction.OpCode) ? (object)GetLocalVariable(index) : (object)GetParameter(index); }
private static ParameterDefinition ParameterFor(MR.Instruction instruction, MethodDefinition method) { var parameter = (ParameterInfo)instruction.Operand; return(method.Parameters[parameter.Position]); }
private static VariableDefinition VariableFor(MR.Instruction instruction, MethodDefinition method) { var local = (LocalVariableInfo)instruction.Operand; return(method.Body.Variables[local.LocalIndex]); }
internal void Reset (Instruction instruction) { this.instruction = instruction; this.success = true; }
static Instruction GetJoinPoint(Instruction left, Instruction right) { Stack<JoinPointState> joinPointStates = new Stack<JoinPointState>(); joinPointStates.Push(new JoinPointState(left, right)); JoinPointState joinPointState = null; while(joinPointStates.Count > 0) { joinPointState = joinPointStates.Peek(); // See if both flows have been computed (right goes second) and if so, get the common join point if(joinPointState.Right == null) { foreach (var leftInstruction in joinPointState.LeftInstructions) { if (joinPointState.RightInstructions.Count <= 0 || leftInstruction != joinPointState.RightInstructions.Pop()) { break; } joinPointState.Common = leftInstruction; } joinPointStates.Pop(); } else { // Check if we were waiting on a pending operation if (joinPointState.Pending != null) { joinPointState.Current = joinPointState.Pending.Common; joinPointState.Pending = null; } else { joinPointState.CurrentInstructions.Push(joinPointState.Current); if (joinPointState.Current.OpCode.FlowControl == FlowControl.Return) { joinPointState.Current = null; } else if (joinPointState.Current.OpCode.FlowControl == FlowControl.Branch) { joinPointState.Current = (Instruction)joinPointState.Current.Operand; } else if (joinPointState.Current.OpCode.FlowControl == FlowControl.Cond_Branch) { joinPointState.Pending = new JoinPointState((Instruction)joinPointState.Current.Operand, joinPointState.Current.Next); joinPointStates.Push(joinPointState.Pending); } else { joinPointState.Current = joinPointState.Current.Next; } } } } return joinPointState.Common; }
private static bool NextInstructionIsACallToAStep(Instruction instruction) { Instruction nextInstruction = instruction.Next; while(nextInstruction.Next != null) { if (nextInstruction.OpCode.FlowControl == System.Reflection.Emit.FlowControl.Call) { return nextInstruction.Operand.ToString().Contains("TechTalk.SpecFlow"); } nextInstruction = nextInstruction.Next; } return false; }
internal void Reset (Instruction resetInstruction) { instruction = resetInstruction; success = true; }
private bool GetSpecFlowStepInvocationHasTable(Instruction instruction) { Instruction nextInstruction = instruction.Next; while (nextInstruction != null && nextInstruction.OpCode.FlowControl != System.Reflection.Emit.FlowControl.Call) { nextInstruction = nextInstruction.Next; } if (nextInstruction.Operand == null) { return false; } return nextInstruction.Operand.ToString().Contains("TechTalk.SpecFlow.Table"); }
private void ReadInstructions() { Instruction previous = null; while (il.position < il.buffer.Length) { var instruction = new Instruction(il.position, ReadOpCode()); ReadOperand(instruction); if (previous != null) { instruction.Previous = previous; previous.Next = instruction; } instructions.Add(instruction); previous = instruction; } }
static void AppendLabel (StringBuilder builder, Instruction instruction) { builder.Append ("IL_"); builder.Append (instruction.offset.ToString ("x4")); }
private object GetVariable(Instruction instruction, int index) { if (TargetsLocalVariable(instruction.OpCode)) return GetLocalVariable(index); return GetParameter(index); }
public static string FormatInstruction (Instruction instruction) { var writer = new StringWriter (); WriteInstruction (writer, instruction); return writer.ToString (); }