/// <summary> /// /// </summary> internal static void FillInTypes(IMetadataHost host, ControlAndDataFlowGraph <BasicBlock, Instruction> cfg) { Contract.Requires(host != null); Contract.Requires(cfg != null); 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(); } } }
/// <summary> /// /// </summary> internal static void FillInTypes(IMetadataHost host, ControlAndDataFlowGraph <BasicBlock, Instruction> cfg) { Contract.Requires(host != null); Contract.Requires(cfg != null); 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(); } } }