Beispiel #1
0
        /// <summary>
        /// Constructs a control and data flow graph for the given method body.
        /// </summary>
        public static ControlAndDataFlowGraph <BasicBlock, Instruction> GetControlAndDataFlowGraphFor(IMetadataHost host, IMethodBody methodBody, ILocalScopeProvider /*?*/ localScopeProvider = null)
        {
            Contract.Requires(host != null);
            Contract.Requires(methodBody != null);
            Contract.Ensures(Contract.Result <ControlAndDataFlowGraph <BasicBlock, Instruction> >() != null);

            var cdfg = ControlFlowInferencer <BasicBlock, Instruction> .SetupControlFlow(host, methodBody, localScopeProvider);

            DataFlowInferencer <BasicBlock, Instruction> .SetupDataFlow(host, methodBody, cdfg);

            TypeInferencer <BasicBlock, Instruction> .FillInTypes(host, cdfg);

            return(cdfg);
        }
Beispiel #2
0
        /// <summary>
        ///
        /// </summary>
        internal static void FillInTypes(IMetadataHost host, ControlAndDataFlowGraph <BasicBlock, Instruction> cfg)
        {
            Contract.Requires(host != null);
            Contract.Requires(cfg != null);

            //If this is a dummy body, do nothing.
            if (cfg.AllBlocks.Count == 1 && cfg.AllBlocks[0] != null && cfg.AllBlocks[0].Instructions.Count <= 1)
            {
                return;
            }

            var stack                = new Stack <Instruction>(cfg.MethodBody.MaxStack, new List <Instruction>(0));
            var numberOfBlocks       = cfg.BlockFor.Count;
            var blocksToVisit        = new Queue <BasicBlock>((int)numberOfBlocks);
            var blocksAlreadyVisited = new SetOfObjects(numberOfBlocks);
            var inferencer           = new TypeInferencer <BasicBlock, Instruction>(host, cfg, stack, blocksToVisit, blocksAlreadyVisited);

            foreach (var root in cfg.RootBlocks)
            {
                blocksToVisit.Enqueue(root);
                while (blocksToVisit.Count != 0)
                {
                    inferencer.DequeueBlockAndFillInItsTypes();
                }
            }
            //At this point, all reachable code blocks have had their types inferred. Now look for unreachable blocks.
            foreach (var block in cfg.AllBlocks)
            {
                if (blocksAlreadyVisited.Contains(block))
                {
                    continue;
                }
                blocksToVisit.Enqueue(block);
                while (blocksToVisit.Count != 0)
                {
                    inferencer.DequeueBlockAndFillInItsTypes();
                }
            }
        }