public override void BackTraceDataFlow(InstructionNode currentInst) { if (currentInst.InliningProperties.Inlined) { InlineableCallNode inlinedCall = currentInst.InliningProperties.CallNode; var argSuppliers = inlinedCall.DataFlowBackRelated.Where(x => x.ArgIndex == ((LdArgInstructionNode)currentInst).ArgIndex).Select(x => x.Argument).ToList(); currentInst.DataFlowBackRelated.AddTwoWaySingleIndex(argSuppliers); } else { //TODO, need to implement STARG as well (even though it's not that commonly used) } }
private List <InstructionNode> InlineRec(InlineableCallNode callNode) { MethodDefinition calledMethodDef = callNode.TargetMethodDefinition; callNode.CallWasInlined = true; if (calledMethodDef.Body == null) { return(new List <InstructionNode>()); } var isSecondLevelRecursiveCall = callNode.InliningProperties.CallSequence.Count(x => x.Method == callNode.TargetMethod) > 1; if (isSecondLevelRecursiveCall) { return(new List <InstructionNode>()); } callNode.StackPushCount = 0; List <InstructionNode> callNodeOriginalForwardRoutes = callNode.ProgramFlowForwardRoutes.ToList(); List <InstructionNode> inlinedNodes = calledMethodDef.Body.Instructions.SelectMany(x => _InstructionNodeFactory.GetInstructionNodes(x, calledMethodDef)).ToList(); inlinedNodes.ForEach(x => SetNodeProps(x, inlinedNodes, callNode)); callNode.BranchProperties.Branches.ForEach(x => x.BranchNodes.InsertRange(x.BranchNodes.IndexOf(callNode) + 1, inlinedNodes)); programFlowHanlder.AddFlowConnections(inlinedNodes); _BackTraceManager.DataTraceInFunctionBounds(inlinedNodes); StitchProgramFlow(callNode, inlinedNodes[0]); var retNodes = inlinedNodes.Where(x => x is RetInstructionNode).ToArray(); foreach (var forwardNode in callNode.DataFlowForwardRelated) { forwardNode.MirrorArg.ContainingList.AddTwoWay(retNodes, forwardNode.MirrorArg.ArgIndex); } foreach (var lastInlinedNode in inlinedNodes.Where(x => x.ProgramFlowForwardRoutes.Count == 0)) { StitchProgramFlow(lastInlinedNode, callNodeOriginalForwardRoutes); } foreach (InlineableCallNode secondLevelInlinedCallNode in inlinedNodes.Where(x => x is InlineableCallNode).ToList()) { inlinedNodes.InsertRange(inlinedNodes.IndexOf(secondLevelInlinedCallNode) + 1, InlineRec(secondLevelInlinedCallNode)); } if (!inlinedNodes.Where(x => x is InlineableCallNode).Any()) { // Console.WriteLine(callNode.TargetMethod.FullName + " is the last of the chain"); } return(inlinedNodes); }
private void AddVirtualCallImplementation(List <InstructionNode> instructionNodes, VirtualCallInstructionNode virtualNodeCall, InstructionNode objectArgument, MethodDefinition virtualMethodImpl, out bool methodStoresDynamic) { methodStoresDynamic = false; var callOpCode = Instruction.Create(CodeGroups.AllOpcodes.First(x => x.Code == Code.Call), virtualMethodImpl); CallNode virtualImplementationNode; if (!virtualMethodImpl.HasBody) { virtualImplementationNode = new NonInlineableCallInstructionNode(callOpCode, virtualNodeCall.Method); } else { virtualImplementationNode = new InlineableCallNode(callOpCode, virtualMethodImpl, virtualNodeCall.Method); methodStoresDynamic = IsStoringDynamicFromOutside(virtualNodeCall, virtualMethodImpl); } AddImplementation(instructionNodes, virtualNodeCall, virtualImplementationNode); virtualImplementationNode.OriginalVirtualNode = virtualNodeCall; virtualImplementationNode.DataFlowBackRelated.RemoveAllTwoWay(x => x.ArgIndex == 0 && x.Argument != objectArgument); }
private void SetNodeProps(InstructionNode inlinedNode, List <InstructionNode> nodes, InlineableCallNode callNode) { inlinedNode.InliningProperties.Inlined = true; inlinedNode.InliningProperties.CallNode = callNode; inlinedNode.InliningProperties.CallSequence = callNode.InliningProperties.CallSequence.ToList(); inlinedNode.BranchProperties.Branches.AddRangeDistinct(callNode.BranchProperties.Branches); inlinedNode.InliningProperties.CallSequence.Add(new MethodAndNode() { Method = callNode.TargetMethodDefinition, MethodsNodes = new List <InstructionNode>(nodes) }); SetRecursionIndex(inlinedNode, nodes); }