public void TrackCallsTest() { MethodTableCursor cur = CLIFile.FindMethod(typeof(GenericsUnitTest).GetMethod("ExpressionInput")); CLIFileRW.MethodBody cb = cur.MethodBody; LocalsVarSig locals = cb.LocalsSignature; CLIType[] vars = locals.GetVariables().ToArray <CLIType>(); CLIType[] args = cur.GetMethodSignature().GetParameters(cur.FindCLIType()).ToArray <CLIType>(); ILCursor ilc = cb.ILInstructions; ilc.TrackStack(args, vars, cb.MaxStack); while (ilc.Next()) { ILInstruction instr = ilc.Instr; object o = instr.ResolveParameter(f); if (ilc.IsCall) { Target[] cargs = ilc.CallLoadArguments(); MethodDesc m = (MethodDesc)o; System.Diagnostics.Debug.WriteLine(string.Format("{0} to {1} at offset {2:X4}", ilc.Instr.op, m.Name, ilc.Position)); for (int i = 0; i < cargs.Length; i++) { System.Diagnostics.Debug.WriteLine(string.Format("\tPar {0} at offset {1:X4}", i, cargs[i].Position)); } } } }
public void MscorlibRegression(Action <MethodTableCursor, MethodInfo> action) { MethodTableCursor cur = reader[TableNames.Method].GetCursor() as MethodTableCursor; foreach (Module m in asm.GetModules()) { foreach (Type t in asm.GetTypes()) { if (!t.IsAbstract && t.IsClass) { foreach (MethodInfo method in t.GetMethods()) { if (method.IsStatic && !method.IsAbstract && ((method.MetadataToken >> 24) == (int)TableNames.Method)) { var txt = t.ToString() + "\t" + method.ToString(); System.Diagnostics.Debug.WriteLine(txt); cur.Goto(method.MetadataToken & 0x00FFFFFF); action(cur, method); } } } } } }
public void MethodBodyTest() { MethodInfo m = typeof(GenericsUnitTest).GetMethod("MethodTest"); MethodTableCursor cur = f[TableNames.Method].GetCursor() as MethodTableCursor; cur.Goto(m.MetadataToken & 0xFFFFFF); System.Reflection.MethodBody rb = m.GetMethodBody(); CLIFileRW.MethodBody cb = cur.MethodBody; Assert.AreEqual(rb.LocalSignatureMetadataToken & 0xFFFFFF, cb.LocalsSig); LocalsVarSig locals = cb.LocalsSignature; IEnumerator <CLIType> lv = locals.GetVariables().GetEnumerator(); foreach (LocalVariableInfo v in rb.LocalVariables) { Assert.IsTrue(lv.MoveNext()); // Fetch instantiation from local type since we are not driven by CLIFile reflection Assert.AreSame(v.LocalType, lv.Current.GetReflectionType(v.LocalType.GetGenericArguments())); } ILCursor ilc = cb.ILInstructions; while (ilc.Next()) { ILInstruction instr = ilc.Instr; object o = instr.ResolveParameter(f); } }
public void LocalsTest() { MethodInfo m = typeof(LocalScope).GetMethod("Local"); MethodTableCursor cur = f[TableNames.Method].GetCursor() as MethodTableCursor; cur.Goto(m.MetadataToken & 0x00FFFFFF); ILCursor ilc = cur.MethodBody.ILInstructions; Target[] lvs = ilc.LocalScope(m.GetMethodBody().LocalVariables.Count); for (int i = 0; i < lvs.Length / 2; i++) { Target b = lvs[i * 2], e = lvs[i * 2 + 1]; System.Diagnostics.Debug.WriteLine(string.Format("{0}: ({1}, {2})", i, b, e)); Assert.IsTrue((b == null && e == null) || (b.Position <= e.Position)); } }
public void MethodTest() { Type me = typeof(Stack <GenericsUnitTest>); MethodTableCursor cur = f[TableNames.Method].GetCursor() as MethodTableCursor; foreach (MethodInfo m in me.GetMethods( BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)) { cur.Goto(m.MetadataToken & 0xFFFFFF); Assert.AreEqual(m.Name, f.Strings[cur.Name]); MethodSig s = cur.GetMethodSignature(); // Type instantiation is not known by looking only at metadata, we must help the resolver here! Assert.AreSame(s.ReturnType.GetReflectionType(me.GetGenericArguments()), m.ReturnType); IEnumerator <CLIType> cp = s.GetParameters().GetEnumerator(); foreach (ParameterInfo p in m.GetParameters()) { Assert.IsTrue(cp.MoveNext()); Assert.AreSame(cp.Current.GetReflectionType(me.GetGenericArguments()), p.ParameterType); } } }
public void StatementsBodyTest() { MethodTableCursor cur = CLIFile.FindMethod(typeof(GenericsUnitTest).GetMethod("MethodTest")); CLIFileRW.MethodBody cb = cur.MethodBody; LocalsVarSig locals = cb.LocalsSignature; CLIType[] vars = locals.GetVariables().ToArray <CLIType>(); CLIType[] args = cur.GetMethodSignature().GetParameters(cur.FindCLIType()).ToArray <CLIType>(); ILCursor ilc = cb.ILInstructions; ilc.TrackStack(args, vars, cb.MaxStack); while (ilc.Next()) { ILInstruction instr = ilc.Instr; object o = instr.ResolveParameter(f); if (ilc.BeginStatement) { System.Diagnostics.Debug.WriteLine(string.Format("MethodTest statement at offset: {0:X4}", ilc.Position)); } } }
public void MethodBodyAllTest() { Assembly mscorlib = typeof(object).Assembly; CLIFile f = CLIFile.Open(mscorlib.Location); MethodTableCursor cur = f[TableNames.Method].GetCursor() as MethodTableCursor; int instrcnt = 0; int methods = 0; int implmeth = 0; int brcnt = 0; while (cur.Next()) { // The token 0x0600449a is not resolved by ResolveMethod, it is likely a bug in reflection. // With .NET 3.5 SP1 the method has moved into token 0x44df. if (cur.Position == 0x44df) { continue; } MethodBase mb = mscorlib.ManifestModule.ResolveMethod(cur.MetadataToken); System.Reflection.MethodBody rb = mb.GetMethodBody(); methods++; if (rb == null) { Assert.IsTrue(rb == null && cur.RVA == 0); continue; } implmeth++; CLIFileRW.MethodBody cb = cur.MethodBody; Assert.AreEqual(rb.LocalSignatureMetadataToken & 0xFFFFFF, cb.LocalsSig); if (rb.LocalSignatureMetadataToken != 0) { LocalsVarSig locals = cb.LocalsSignature; IEnumerator <CLIType> lv = locals.GetVariables().GetEnumerator(); foreach (LocalVariableInfo v in rb.LocalVariables) { Assert.IsTrue(lv.MoveNext()); // Fetch instantiation from local type since we are not driven by CLIFile reflection Assert.AreSame(v.LocalType, lv.Current.GetReflectionType(mb.DeclaringType.ContainsGenericParameters ? mb.DeclaringType.GetGenericArguments() : null, mb.ContainsGenericParameters ? mb.GetGenericArguments() : null)); } } ILCursor ilc = cb.ILInstructions; while (ilc.Next()) { ILInstruction instr = ilc.Instr; object o = instr.ResolveParameter(f); instrcnt++; if (instr.op == System.Reflection.Emit.OpCodes.Br || instr.op == System.Reflection.Emit.OpCodes.Br_S) { brcnt++; } } } System.Diagnostics.Debug.WriteLine(string.Format("Total methods: {0}", methods)); System.Diagnostics.Debug.WriteLine(string.Format("Impl methods: {0}", implmeth)); System.Diagnostics.Debug.WriteLine(string.Format("Total instructions: {0}", instrcnt)); System.Diagnostics.Debug.WriteLine(string.Format("Total unconditional branch: {0}", brcnt)); System.Diagnostics.Debug.WriteLine(string.Format("Average method len: {0}", (instrcnt / (double)methods))); }