internal LoadArgAddress(MethodDefinition method, Instruction untyped, int index) : base(untyped, index) { switch (untyped.OpCode.Code) { case Code.Ldarga: case Code.Ldarga_S: ParameterDefinition param = untyped.Operand as ParameterDefinition; if (param != null) { Arg = param.Sequence; } else { Arg = (int)untyped.Operand; } break; default: DBC.Fail(untyped.OpCode.Code + " is not a valid LoadArg"); break; } if (Arg == 0) { Name = "this"; } else { Name = method.Parameters[Arg - 1].Name; } }
internal StoreArg(MethodDefinition method, Instruction untyped, int index) : base(untyped, index) { int delta = method.HasThis ? 1 : 0; switch (untyped.OpCode.Code) { case Code.Starg: case Code.Starg_S: ParameterDefinition param = untyped.Operand as ParameterDefinition; if (param != null) { if (method.HasThis) { Argument = param.Sequence; } else { Argument = param.Sequence - 1; } Name = param.Name; } else { Argument = (int)untyped.Operand; Name = method.Parameters[Argument - delta].Name; } break; default: DBC.Fail(untyped.OpCode.Code + " is not a valid StoreArg"); break; } }
internal LoadLocalAddress(SymbolTable symbols, MethodDefinition method, Instruction untyped, int index) : base(untyped, index) { switch (untyped.OpCode.Code) { case Code.Ldloca_S: case Code.Ldloca: VariableDefinition param = untyped.Operand as VariableDefinition; if (param != null) { Variable = param.Index; Type = param.VariableType; } else { Variable = (int)untyped.Operand; Type = method.Body.Variables[Variable].VariableType; } Name = symbols.LocalName(method, untyped, Variable); break; default: DBC.Fail(untyped.OpCode.Code + " is not a valid LoadLocalAddress"); break; } RealName = symbols.HaveLocalNames(method); }
internal LoadArg(MethodDefinition method, Instruction untyped, int index) : base(untyped, index) { int delta = method.HasThis ? 1 : 0; switch (untyped.OpCode.Code) { case Code.Ldarg_0: Arg = 1 - delta; break; case Code.Ldarg_1: Arg = 2 - delta; break; case Code.Ldarg_2: Arg = 3 - delta; break; case Code.Ldarg_3: Arg = 4 - delta; break; case Code.Ldarg: case Code.Ldarg_S: ParameterDefinition param = untyped.Operand as ParameterDefinition; if (param != null) { Arg = param.Sequence; } else { Arg = (int)untyped.Operand; } break; default: DBC.Fail(untyped.OpCode.Code + " is not a valid LoadArg"); break; } if (Arg == 0) { Name = "this"; Type = method.DeclaringType; } else { Name = method.Parameters[Arg - 1].Name; Type = method.Parameters[Arg - 1].ParameterType; } }
private int GetIndex(string text) { foreach (LoadString load in m_instructions.Match <LoadString>()) { if (load.Value.Contains(text)) { return(load.Index); } } DBC.Fail("Couldn't find {0}", text); return(-1); }
internal LoadStaticFieldAddress(Instruction untyped, int index) : base(untyped, index) { switch (untyped.OpCode.Code) { case Code.Ldsflda: Field = (FieldReference)untyped.Operand; break; default: DBC.Fail(untyped.OpCode.Code + " is not a valid LoadStaticFieldAddress"); break; } }
internal LoadString(Instruction untyped, int index) : base(untyped, index) { switch (untyped.OpCode.Code) { case Code.Ldstr: Value = (string)untyped.Operand; break; default: DBC.Fail(untyped.OpCode.Code + " is not a valid LoadString"); break; } }
internal StoreField(Instruction untyped, int index) : base(untyped, index) { switch (untyped.OpCode.Code) { case Code.Stfld: Field = (FieldReference)untyped.Operand; break; default: DBC.Fail(untyped.OpCode.Code + " is not a valid StoreField"); break; } }
internal LoadFunctionAddress(Instruction untyped, int index) : base(untyped, index) { switch (untyped.OpCode.Code) { case Code.Ldftn: case Code.Ldvirtftn: Method = (MethodReference)untyped.Operand; break; default: DBC.Fail(untyped.OpCode.Code + " is not a valid LoadFunctionAddress"); break; } }
internal StoreLocal(SymbolTable symbols, MethodDefinition method, Instruction untyped, int index) : base(untyped, index) { switch (untyped.OpCode.Code) { case Code.Stloc_0: Name = symbols.LocalName(method, untyped, 0); Type = method.Body.Variables[Variable].VariableType; break; case Code.Stloc_1: Variable = 1; Name = symbols.LocalName(method, untyped, 1); Type = method.Body.Variables[Variable].VariableType; break; case Code.Stloc_2: Variable = 2; Name = symbols.LocalName(method, untyped, 2); Type = method.Body.Variables[Variable].VariableType; break; case Code.Stloc_3: Variable = 3; Name = symbols.LocalName(method, untyped, 3); Type = method.Body.Variables[Variable].VariableType; break; case Code.Stloc: case Code.Stloc_S: VariableDefinition param = untyped.Operand as VariableDefinition; if (param != null) { Variable = param.Index; Type = param.VariableType; } else { Variable = (int)untyped.Operand; Type = method.Body.Variables[Variable].VariableType; } Name = symbols.LocalName(method, untyped, Variable); break; default: DBC.Fail(untyped.OpCode.Code + " is not a valid StoreLocal"); break; } RealName = symbols.HaveLocalNames(method); }
internal LoadConstantFloat(Instruction untyped, int index) : base(untyped, index) { switch (untyped.OpCode.Code) { case Code.Ldc_R4: Value = (double)Convert.ToSingle(untyped.Operand); break; case Code.Ldc_R8: Value = Convert.ToDouble(untyped.Operand); break; default: DBC.Fail(untyped.OpCode.Code + " is not a valid LoadConstantFloat"); break; } }
private bool DoMatchOperand(object lhs, object rhs) { if (lhs.GetType() != rhs.GetType()) { return(false); } if (lhs is int) { int i1 = (int)lhs; int i2 = (int)rhs; return(i1 == i2); } if (lhs is long) { long l1 = (long)lhs; long l2 = (long)rhs; return(l1 == l2); } if (lhs is float) { float i1 = (float)lhs; float i2 = (float)rhs; return(i1 == i2); } if (lhs is double) { double i1 = (double)lhs; double i2 = (double)rhs; return(i1 == i2); } if (lhs is SByte) { SByte i1 = (SByte)lhs; SByte i2 = (SByte)rhs; return(i1 == i2); } if (lhs is string) { string s1 = (string)lhs; string s2 = (string)rhs; return(s1 == s2); } if (lhs is FieldReference) { FieldReference f1 = (FieldReference)lhs; FieldReference f2 = (FieldReference)rhs; return(f1.Name == f2.Name); } if (lhs is Instruction) { Instruction i1 = (Instruction)lhs; Instruction i2 = (Instruction)rhs; return(i1.Offset == i2.Offset); } if (lhs is Instruction[]) // used for switch { Instruction[] i1s = (Instruction[])lhs; Instruction[] i2s = (Instruction[])rhs; return(i1s.Length == i2s.Length); // if the elements differ we'll find out about it soon enough } if (lhs is MethodReference) { MethodReference m1 = (MethodReference)lhs; MethodReference m2 = (MethodReference)rhs; string s1 = m1.ToString().Replace(m1.DeclaringType.Name, "self"); string s2 = m2.ToString().Replace(m2.DeclaringType.Name, "self"); return(s1 == s2); } if (lhs is ParameterDefinition) { ParameterDefinition p1 = (ParameterDefinition)lhs; ParameterDefinition p2 = (ParameterDefinition)rhs; return(p1.Sequence == p2.Sequence); } if (lhs is TypeReference) { TypeReference t1 = (TypeReference)lhs; TypeReference t2 = (TypeReference)rhs; return(t1.MetadataToken == t2.MetadataToken); } if (lhs is VariableDefinition) { VariableDefinition v1 = (VariableDefinition)lhs; VariableDefinition v2 = (VariableDefinition)rhs; return(v1.Index == v2.Index); } DBC.Fail("unexpected {0}", lhs.GetType()); return(false); }
public void TypeFailed(TypeDefinition type, string checkID, string details) { DBC.Fail("shouldn't get type failed for a method rule!"); }
private int DoGetStackCount(TypedInstruction instruction, StackBehaviour behavior) { int count = 0; switch (behavior) { case StackBehaviour.Pop0: case StackBehaviour.Push0: break; case StackBehaviour.Pop1: case StackBehaviour.Popi: case StackBehaviour.Popref: case StackBehaviour.Push1: case StackBehaviour.Pushi: case StackBehaviour.Pushi8: case StackBehaviour.Pushr4: case StackBehaviour.Pushr8: case StackBehaviour.Pushref: count = 1; break; case StackBehaviour.Pop1_pop1: case StackBehaviour.Popi_pop1: case StackBehaviour.Popi_popi: case StackBehaviour.Popi_popi8: case StackBehaviour.Popi_popr4: case StackBehaviour.Popi_popr8: case StackBehaviour.Popref_pop1: case StackBehaviour.Popref_popi: case StackBehaviour.Push1_push1: count = 2; break; case StackBehaviour.Popi_popi_popi: case StackBehaviour.Popref_popi_popi: case StackBehaviour.Popref_popi_popi8: case StackBehaviour.Popref_popi_popr4: case StackBehaviour.Popref_popi_popr8: case StackBehaviour.Popref_popi_popref: count = 3; break; case StackBehaviour.PopAll: // leave count = int.MaxValue; break; case StackBehaviour.Varpop: // call, newobj, ret Call call = instruction as Call; if (call != null) { count = call.Target.Parameters.Count + (call.Target.HasThis ? 1 : 0); } else if (instruction.Untyped.OpCode.Code == Code.Ret) { count = int.MaxValue; } else { NewObj no = instruction as NewObj; DBC.Assert(no != null, "Varpop opcode should be call, ret, or newobj"); count = no.Ctor.Parameters.Count; } break; case StackBehaviour.Varpush: // call Call call2 = instruction as Call; DBC.Assert(call2 != null, "Varpush opcode should be call"); if (call2.Target.ReturnType.ReturnType.FullName != "System.Void") { count = 1; } break; default: DBC.Fail("Bad stack behavior: {0}", behavior); break; } return(count); }
internal LoadConstantInt(Instruction untyped, int index) : base(untyped, index) { switch (untyped.OpCode.Code) { case Code.Ldc_I4_M1: Value = -1; break; case Code.Ldc_I4_0: Value = 0; break; case Code.Ldc_I4_1: Value = 1; break; case Code.Ldc_I4_2: Value = 2; break; case Code.Ldc_I4_3: Value = 3; break; case Code.Ldc_I4_4: Value = 4; break; case Code.Ldc_I4_5: Value = 5; break; case Code.Ldc_I4_6: Value = 6; break; case Code.Ldc_I4_7: Value = 7; break; case Code.Ldc_I4_8: Value = 8; break; case Code.Ldc_I4_S: Value = (SByte)untyped.Operand; break; case Code.Ldc_I4: Value = Convert.ToInt32(untyped.Operand); break; case Code.Ldc_I8: Value = Convert.ToInt64(untyped.Operand); break; default: DBC.Fail(untyped.OpCode.Code + " is not a valid LoadConstantInt"); break; } }
public override Lattice Transform(Lattice lhs, BasicBlock block) { DBC.Pre(lhs != null, "lhs is null"); DBC.Pre(block != null, "block is null"); Lattice result = lhs; if (!lhs.IsTop) { if (block.Length > 0) { for (int i = 0; i < block.Length; ++i) { result = result.Transform(block.First.Index + i); } } else { long?[] args = lhs.m_state.Arguments; long?[] locals = lhs.m_state.Locals; List <StackEntry> stack = lhs.m_state.Stack; if (block.Length == Tracker.CatchBlockLen || block.Length == Tracker.FinallyBlockLen) { stack = new List <StackEntry>(); if (block.Length == Tracker.CatchBlockLen) { stack.Add(new StackEntry(1, -1)); // catch blocks start with the exception on the stack } } else if (block.Length <= Tracker.FirstNullArgBlockLen && block.Length >= Tracker.LastNullArgBlockLen) { args = new long?[lhs.m_state.Arguments.Length]; lhs.m_state.Arguments.CopyTo(args, 0); int nth = Tracker.FirstNullArgBlockLen - block.Length; args[nth] = 0; } else if (block.Length <= Tracker.FirstNonNullArgBlockLen && block.Length >= Tracker.LastNonNullArgBlockLen) { args = new long?[lhs.m_state.Arguments.Length]; lhs.m_state.Arguments.CopyTo(args, 0); int nth = Tracker.FirstNonNullArgBlockLen - block.Length; args[nth] = 1; } else if (block.Length <= Tracker.FirstNullLocalBlockLen && block.Length >= Tracker.LastNullLocalBlockLen) { locals = new long?[lhs.m_state.Locals.Length]; lhs.m_state.Locals.CopyTo(locals, 0); int nth = Tracker.FirstNullLocalBlockLen - block.Length; locals[nth] = 0; } else if (block.Length <= Tracker.FirstNonNullLocalBlockLen && block.Length >= Tracker.LastNonNullLocalBlockLen) { locals = new long?[lhs.m_state.Locals.Length]; lhs.m_state.Locals.CopyTo(locals, 0); int nth = Tracker.FirstNonNullLocalBlockLen - block.Length; locals[nth] = 1; } else if (block.Length != 0) { DBC.Fail("bad block length: {0}", block.Length); } State state = new State(args, locals, stack); return(new Lattice(lhs.m_instructions, state)); } } return(result); }
public void AssemblyFailed(AssemblyDefinition assembly, string checkID, string details) { DBC.Fail("shouldn't get type failed for an event rule!"); }
public void MethodFailed(MethodDefinition method, string checkID, int offset, string details) { DBC.Fail("shouldn't get method failed for an event rule!"); }
private void DoStackPops(List <StackEntry> stack, int index) { int count = 0; TypedInstruction instruction = m_instructions[index]; switch (instruction.Untyped.OpCode.StackBehaviourPop) { case StackBehaviour.Pop0: DBC.Fail("DoStackPops shouldn't have been called for Pop0"); break; case StackBehaviour.Pop1: case StackBehaviour.Popi: case StackBehaviour.Popref: count = 1; break; case StackBehaviour.Pop1_pop1: case StackBehaviour.Popi_pop1: case StackBehaviour.Popi_popi: case StackBehaviour.Popi_popi8: case StackBehaviour.Popi_popr4: case StackBehaviour.Popi_popr8: case StackBehaviour.Popref_pop1: case StackBehaviour.Popref_popi: count = 2; break; case StackBehaviour.Popi_popi_popi: case StackBehaviour.Popref_popi_popi: case StackBehaviour.Popref_popi_popi8: case StackBehaviour.Popref_popi_popr4: case StackBehaviour.Popref_popi_popr8: case StackBehaviour.Popref_popi_popref: count = 3; break; case StackBehaviour.PopAll: // leave count = stack.Count; break; case StackBehaviour.Varpop: // call, newobj, ret Call call = instruction as Call; if (call != null) { count = call.Target.Parameters.Count + (call.Target.HasThis ? 1 : 0); } else if (instruction.Untyped.OpCode.Code == Code.Ret) { count = stack.Count; } else { NewObj no = instruction as NewObj; DBC.Assert(no != null, "Varpop opcode should be call, ret, or newobj"); count = no.Ctor.Parameters.Count; } break; default: DBC.Fail("Bad pop state: {0}", instruction.Untyped.OpCode.StackBehaviourPop); break; } if (instruction.Untyped.OpCode.Code == Code.Ldelem_Any) { count = 2; // cecil has a bug where it says this pops 1 value } // No assert for zero sized stack because we may not have met the block that gives us a stack. DBC.Assert(stack.Count == 0 || count <= stack.Count, "{0} at {1:X2} is trying to pop too many items", instruction.Untyped.OpCode.Code, instruction.Untyped.Offset); count = Math.Min(count, stack.Count); stack.RemoveRange(stack.Count - count, count); }