private Block CreateBlock(BlockLoadState blockState, int nextInstructionCount, ref int totalBranchCount) { // Calculate branch count for block int branchCount = 0; int zeroStackSizeNodeCount = blockState.ZeroStackSizeNodes.Count; do { branchCount++; zeroStackSizeNodeCount--; totalBranchCount--; blockState.InstructionCount /= 2; }while (totalBranchCount > 0 && zeroStackSizeNodeCount > 0 && blockState.InstructionCount > nextInstructionCount); var block = new Block(); block.Node = blockState.Node; // Sections int sectionCount = branchCount + 1; var sections = new BlockSection[sectionCount]; // Create for (int i = 0; i < sectionCount; i++) { sections[i] = new BlockSection(); } // Init var firstSection = sections[0]; firstSection.ProxyNode = blockState.Node.FirstChild.AddPrevious(OpCodes.Nop); firstSection.CodeNode = firstSection.ProxyNode.AddNext(OpCodes.Nop); var lastSection = sections[sectionCount - 1]; lastSection.LastNode = blockState.Node.LastChild.AddNext(OpCodes.Nop); int sectionOffsetSize = blockState.ZeroStackSizeNodes.Count / sectionCount; for (int i = 0; i < branchCount; i++) { var section1 = sections[i]; var section2 = sections[i + 1]; int branchIndex = (sectionOffsetSize * (i + 1)); var branchInstruction = blockState.ZeroStackSizeNodes[branchIndex]; section1.Next = section2; section1.LastNode = branchInstruction.AddPrevious(OpCodes.Nop); section2.ProxyNode = section1.LastNode.AddNext(OpCodes.Nop); section2.CodeNode = section2.ProxyNode.AddNext(OpCodes.Nop); } block.Sections = sections; block.FirstSection = sections[0]; return(block); }
private void Load(LoadState state, ILBlock block) { var zeroStackSizeNodes = new List <ILNode>(); int instructionCount = 0; bool hasChildren = false; var node = block.FirstChild; while (node != null) { switch (node.NodeType) { case ILNodeType.Instruction: { var instruction = (ILInstruction)node; int stackSize; if (state.StackSizeByInstruction.TryGetValue(instruction, out stackSize) && stackSize == 0) { if (CanBranchAtInstruction(instruction)) { zeroStackSizeNodes.Add(instruction); } } instructionCount++; } break; case ILNodeType.Block: { var tryBlock = node as ILTryBlock; if (tryBlock != null) { if (node.PreviousSibling != null) { zeroStackSizeNodes.Add(tryBlock); } hasChildren = true; instructionCount++; } } break; } node = node.NextSibling; } state.TotalInstructionCount += instructionCount; if (zeroStackSizeNodes.Count > 0) { var blockState = new BlockLoadState(); blockState.Index = state.Blocks.Count; blockState.InstructionCount = instructionCount; blockState.Node = block; blockState.ZeroStackSizeNodes = zeroStackSizeNodes; state.Blocks.Add(blockState); } // Load child blocks if (hasChildren) { node = block.FirstChild; while (node != null) { var tryBlock = node as ILTryBlock; if (tryBlock != null) { Load(state, tryBlock); } node = node.NextSibling; } } }