Example #1
0
 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)
     }
 }
Example #2
0
        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);
        }
Example #4
0
 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);
 }