static MethodBody CreateTestMethod (params OpCode [] opcodes) { var method = new MethodDefinition { Name = "function", }; var il = method.Body.GetILProcessor (); foreach (var opcode in opcodes) il.Emit (opcode); return method.Body; }
HashSet<ILVariable> localVariablesToDefine = new HashSet<ILVariable>(); // local variables that are missing a definition /// <summary> /// Creates the body for the method definition. /// </summary> /// <param name="methodDef">Method definition to decompile.</param> /// <param name="context">Decompilation context.</param> /// <param name="parameters">Parameter declarations of the method being decompiled. /// These are used to update the parameter names when the decompiler generates names for the parameters.</param> /// <param name="localVariables">Local variables storage that will be filled/updated with the local variables.</param> /// <returns>Block for the method body</returns> public static BlockStatement CreateMethodBody(MethodDefinition methodDef, DecompilerContext context, IEnumerable<ParameterDeclaration> parameters = null, /*Concurrent*/Dictionary<int, IEnumerable<ILVariable>> localVariables = null) { if (localVariables == null) localVariables = new /*Concurrent*/Dictionary<int, IEnumerable<ILVariable>>(); MethodDefinition oldCurrentMethod = context.CurrentMethod; Debug.Assert(oldCurrentMethod == null || oldCurrentMethod == methodDef); context.CurrentMethod = methodDef; try { AstMethodBodyBuilder builder = new AstMethodBodyBuilder(); builder.methodDef = methodDef; builder.context = context; builder.typeSystem = methodDef.Module.TypeSystem; return builder.CreateMethodBody(parameters, localVariables); } finally { context.CurrentMethod = oldCurrentMethod; } }
public static void WriteMethodBody (TextWriter writer, MethodDefinition method) { var body = method.Body; WriteVariables (writer, body); foreach (Instruction instruction in body.Instructions) { var sequence_point = instruction.SequencePoint; if (sequence_point != null) { writer.Write ('\t'); WriteSequencePoint (writer, sequence_point); writer.WriteLine (); } writer.Write ('\t'); WriteInstruction (writer, instruction); writer.WriteLine (); } WriteExceptionHandlers (writer, body); }
public static string FormatMethodBody (MethodDefinition method) { var writer = new StringWriter (); WriteMethodBody (writer, method); return writer.ToString (); }
public void RemoveOverrideMapping (MethodDefinition method) { Overrides.Remove (method.token.RID); }
public bool TryGetOverrideMapping (MethodDefinition method, out MetadataToken [] mapping) { return Overrides.TryGetValue (method.token.RID, out mapping); }
public void AddMethodDefinition (MethodDefinition method) { Methods [method.token.RID - 1] = method; }
ILBlock ConvertFinallyBlock(MethodDefinition finallyMethod) { ILBlock block = CreateILAst(finallyMethod); // Get rid of assignment to state FieldReference stfld; List<ILExpression> args; if (block.Body.Count > 0 && block.Body[0].Match(ILCode.Stfld, out stfld, out args)) { if (GetFieldDefinition(stfld) == stateField && args[0].MatchThis()) block.Body.RemoveAt(0); } // Convert ret to endfinally foreach (ILExpression expr in block.EnumerateSelfAndChildrenRecursive().OfType<ILExpression>()) { if (expr.Code == ILCode.Ret) expr.Code = ILCode.Endfinally; } return block; }
void ConstructExceptionTable() { disposeMethod = enumeratorType.Methods.FirstOrDefault(m => m.Name == "System.IDisposable.Dispose"); ILBlock ilMethod = CreateILAst(disposeMethod); finallyMethodToStateInterval = new Dictionary<MethodDefinition, Interval>(); InitStateRanges(ilMethod.Body[0]); AssignStateRanges(ilMethod.Body, ilMethod.Body.Count, forDispose: true); // Now look at the finally blocks: foreach (var tryFinally in ilMethod.EnumerateSelfAndChildrenRecursive().OfType<ILTryCatchBlock>()) { Interval interval = ranges[tryFinally.TryBlock.Body[0]].ToEnclosingInterval(); var finallyBody = tryFinally.FinallyBlock.Body; if (finallyBody.Count != 2) throw new YieldAnalysisFailedException(); ILExpression call = finallyBody[0] as ILExpression; if (call == null || call.Code != ILCode.Call || call.Arguments.Count != 1) throw new YieldAnalysisFailedException(); if (!call.Arguments[0].MatchThis()) throw new YieldAnalysisFailedException(); if (!finallyBody[1].Match(ILCode.Endfinally)) throw new YieldAnalysisFailedException(); MethodDefinition mdef = GetMethodDefinition(call.Operand as MethodReference); if (mdef == null || finallyMethodToStateInterval.ContainsKey(mdef)) throw new YieldAnalysisFailedException(); finallyMethodToStateInterval.Add(mdef, interval); } ranges = null; }
bool MatchEnumeratorCreationNewObj(ILExpression expr, out MethodDefinition ctor) { // newobj(CurrentType/...::.ctor, ldc.i4(-2)) ctor = null; if (expr.Code != ILCode.Newobj || expr.Arguments.Count != 1) return false; if (expr.Arguments[0].Code != ILCode.Ldc_I4) return false; int initialState = (int)expr.Arguments[0].Operand; if (!(initialState == -2 || initialState == 0)) return false; ctor = GetMethodDefinition(expr.Operand as MethodReference); if (ctor == null || ctor.DeclaringType.DeclaringType != context.CurrentType) return false; return IsCompilerGeneratorEnumerator(ctor.DeclaringType); }
public static ILMethodAst Build(MethodDefinition methodDef, bool optimize) { if (methodDef.Body.Instructions.Count == 0) { return ILMethodAst.Empty; } else { var ilastBuilder = new ILMethodAstBuilder(methodDef, optimize); List<ByteCode> body = ilastBuilder.StackAnalysis(methodDef); List<ILNode> ast = ilastBuilder.ConvertToAst(body, new HashSet<ExceptionHandler>(methodDef.Body.ExceptionHandlers)); return new ILMethodAst(ilastBuilder.parameterList, ast); } }
private ILMethodAstBuilder(MethodDefinition methodDef, bool optimize) { this.methodDef = methodDef; this.optimize = optimize; }
public void RemoveInstruction () { var object_ref = new TypeReference ("System", "Object", null, null, false); var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); var body = new MethodBody (method); var il = body.GetILProcessor (); var first = il.Create (OpCodes.Nop); var second = il.Create (OpCodes.Nop); var third = il.Create (OpCodes.Nop); body.Instructions.Add (first); body.Instructions.Add (second); body.Instructions.Add (third); Assert.IsNull (first.Previous); Assert.AreEqual (second, first.Next); Assert.AreEqual (first, second.Previous); Assert.AreEqual (third, second.Next); Assert.AreEqual (second, third.Previous); Assert.IsNull (third.Next); body.Instructions.Remove (second); Assert.IsNull (first.Previous); Assert.AreEqual (third, first.Next); Assert.AreEqual (first, third.Previous); Assert.IsNull (third.Next); }
static void AssertCode (string expected, MethodDefinition method) { Assert.IsTrue (method.HasBody); Assert.IsNotNull (method.Body); Assert.AreEqual (Normalize (expected), Normalize (Formatter.FormatMethodBody (method))); }
/// <summary> /// Creates ILAst for the specified method, optimized up to before the 'YieldReturn' step. /// </summary> ILBlock CreateILAst(MethodDefinition method) { if (method == null || !method.HasBody) throw new YieldAnalysisFailedException(); ILBlock ilMethod = new ILBlock(); var astBuilder = ILMethodAstBuilder.Build(method, true); ilMethod.Body = astBuilder.Nodes.ToList(); ILAstOptimizer optimizer = new ILAstOptimizer(); optimizer.Optimize(context, ilMethod, ILAstOptimizationStep.YieldReturn); return ilMethod; }
public void InsertParameterIndex () { var object_ref = new TypeReference ("System", "Object", null, null, false); var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); var x = new ParameterDefinition ("x", ParameterAttributes.None, object_ref); var y = new ParameterDefinition ("y", ParameterAttributes.None, object_ref); var z = new ParameterDefinition ("y", ParameterAttributes.None, object_ref); method.Parameters.Add (x); method.Parameters.Add (z); Assert.AreEqual (0, x.Index); Assert.AreEqual (-1, y.Index); Assert.AreEqual (1, z.Index); method.Parameters.Insert (1, y); Assert.AreEqual (0, x.Index); Assert.AreEqual (1, y.Index); Assert.AreEqual (2, z.Index); }
static PropertyDefinition GetIndexer(MethodDefinition cecilMethodDef) { TypeDefinition typeDef = cecilMethodDef.DeclaringType; string indexerName = null; foreach (CustomAttribute ca in typeDef.CustomAttributes) { if (ca.Constructor.FullName == "System.Void System.Reflection.DefaultMemberAttribute::.ctor(System.String)") { indexerName = ca.ConstructorArguments.Single().Value as string; break; } } if (indexerName == null) return null; foreach (PropertyDefinition prop in typeDef.Properties) { if (prop.Name == indexerName) { if (prop.GetMethod == cecilMethodDef || prop.SetMethod == cecilMethodDef) return prop; } } return null; }