public CallInfo[] Collect(Mono.Cecil.MethodDefinition method, Func <Instruction, bool> filter = null) { //if (method.Name != "SimpleLogFromTryCatch" // && method.Name != "EnqueueNoOpIfNeeded") return new CallInfo[0]; if (!method.HasBody) { return(new CallInfo[0]); } var body = method.Body; if (method.Body.Instructions.Any(i => i.Is(OpCodes.Call, OpCodes.Callvirt) && filter(i))) { var function = ilReader.ReadIL(body); var opsByOffset = body.Instructions.ToDictionary(instr => instr.Offset); var transformContext = decompiler.CreateILTransformContext(function); //foreach (var t in ILTransforms) //{ // t.Run(function, transformContext); //} var collector = new BlockVisitor(function, i => { var range = i.ILRange; var op = opsByOffset[range.Start]; while (!op.Is(OpCodes.Call, OpCodes.Callvirt)) { op = op.Next; if (op.Offset > range.End) { return(false); } } return(filter(op)); }); function.AcceptVisitor(collector); if (collector.CallStarts.Count > 0) { var retval = new CallInfo[collector.CallStarts.Count]; var i = 0; foreach (var(blockStart, callOffset) in collector.CallStarts) { retval[i++] = new CallInfo(opsByOffset[blockStart], opsByOffset[callOffset]); } return(retval); } } return(new CallInfo[0]); }
public override void VisitBlock(Block block) { // Get stack if (block.Method.StartBlock == block || !block.Sources.Any()) { _nextStack = 0; } else { var key = block.Sources.First(source => _stacks.ContainsKey(source)); var stack = _stacks[key]; _nextStack = stack; } // Run visitor var visitor = new BlockVisitor(_nextStack); visitor.Visit(block); // Add to stack list _stacks[block] = visitor.GetNextStack(); }
public override void VisitBlock(Block block) { // Get variables Variables currentVariables; if (block.Method.StartBlock == block || !block.Sources.Any()) { currentVariables = new Variables(_method); } else { var key = block.Sources.First(source => _variables.ContainsKey(source)); var variables = _variables[key]; currentVariables = variables.Copy(); } // Add to stack list _variables[block] = currentVariables; // Run visitor var visitor = new BlockVisitor(currentVariables); visitor.Visit(block); }