public void RegressiveTestILSplit() { MscorlibRegression(delegate(MethodTableCursor cur, MethodInfo method) { if (cur.RVA == 0) { return; } //FIXME: This test cannot pass because in exception handlers the catch blocks load the exception // onto the evaluation stack. I need to decide how to deal with it. CLIFileRW.MethodBody cb = cur.MethodBody; LocalsVarSig locals = cb.LocalsSignature; if (locals != null) { CLIType[] vars = locals.GetVariables().ToArray <CLIType>(); CLIType[] args = cur.GetMethodSignature().GetParameters(method.IsStatic ? null : cur.FindCLIType()).ToArray <CLIType>(); ILCursor ilc = cb.ILInstructions; ilc.TrackStack(args, vars); while (ilc.Next()) { ILInstruction instr = ilc.Instr; object o = instr.ResolveParameter(reader); if (ilc.BeginStatement) { System.Diagnostics.Debug.WriteLine(string.Format("MethodTest statement at offset: {0:X4}", ilc.Position)); } } } }); }
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 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 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))); }