コード例 #1
0
        void AdjustJumpTargets(BasicBlock oldBlock, BasicBlock newBlock)
        {
            foreach (var origin in oldBlock.JumpOrigins)
            {
                if (newBlock == null)
                {
                    throw CannotRemoveTarget;
                }
                if (origin.Exception != null)
                {
                    AdjustException(origin.Exception);
                    newBlock.AddJumpOrigin(origin);
                }
                else
                {
                    newBlock.AddJumpOrigin(new JumpOrigin(newBlock, origin.OriginBlock, origin.Origin));
                    AdjustJump(origin);
                }
            }

            var oldInstruction = oldBlock.LastInstruction;

            Scanner.LogDebug(2, $"ADJUST JUMPS: {oldBlock} {newBlock} {oldInstruction}");
            Scanner.Context.Debug();

            foreach (var block in _block_list)
            {
                for (var j = 0; j < block.JumpOrigins.Count; j++)
                {
                    var origin = block.JumpOrigins [j];
                    Scanner.LogDebug(2, $"  ORIGIN: {origin}");
                    if (origin.Exception != null)
                    {
                        Scanner.LogDebug(2, $"  EXCEPTION ORIGIN: {origin}");
                        if (origin.Exception.TryStart == oldInstruction)
                        {
                            throw CannotRemoveTarget;
                        }
                        if (origin.Exception.HandlerStart == oldInstruction)
                        {
                            throw CannotRemoveTarget;
                        }
                    }
                    if (origin.Origin == oldInstruction)
                    {
                        throw CannotRemoveTarget;
                    }
                    if (origin.OriginBlock == oldBlock)
                    {
                        origin.OriginBlock = newBlock ?? throw CannotRemoveTarget;
                        continue;
                    }
                }
            }

            void AdjustException(ExceptionHandler handler)
            {
                if (handler.TryStart == oldBlock.FirstInstruction)
                {
                    handler.TryStart = newBlock.FirstInstruction;
                }
                if (handler.TryEnd == oldBlock.FirstInstruction)
                {
                    handler.TryEnd = newBlock.FirstInstruction;
                }
                if (handler.HandlerStart == oldBlock.FirstInstruction)
                {
                    handler.HandlerStart = newBlock.FirstInstruction;
                }
                if (handler.HandlerEnd == oldBlock.FirstInstruction)
                {
                    handler.HandlerEnd = newBlock.FirstInstruction;
                }
                if (handler.FilterStart == oldBlock.FirstInstruction)
                {
                    handler.FilterStart = newBlock.FirstInstruction;
                }
            }

            void AdjustJump(JumpOrigin origin)
            {
                var instruction = origin.Origin;

                if (instruction.OpCode.OperandType == OperandType.InlineSwitch)
                {
                    var labels = (Instruction [])instruction.Operand;
                    for (int i = 0; i < labels.Length; i++)
                    {
                        if (labels [i] != oldBlock.FirstInstruction)
                        {
                            continue;
                        }
                        labels [i] = newBlock?.FirstInstruction ?? throw CannotRemoveTarget;
                    }
                    return;
                }
                if (instruction.OpCode.OperandType != OperandType.InlineBrTarget &&
                    instruction.OpCode.OperandType != OperandType.ShortInlineBrTarget)
                {
                    throw DebugHelpers.AssertFailUnexpected(Method, origin.OriginBlock, instruction);
                }
                if (instruction.Operand != oldBlock.FirstInstruction)
                {
                    throw DebugHelpers.AssertFailUnexpected(Method, origin.OriginBlock, instruction);
                }
                instruction.Operand = newBlock?.FirstInstruction ?? throw CannotRemoveTarget;
            }
        }
コード例 #2
0
 public void Dump(BasicBlock block)
 {
     Scanner.Context.LogMessage(MessageImportance.Low, $"{block}:");
     Scanner.LogDebug(0, "  ", null, block.JumpOrigins);
     Scanner.LogDebug(0, "  ", null, block.Instructions);
 }
コード例 #3
0
 public bool TryGetBlock(Instruction instruction, out BasicBlock block)
 {
     return(_bb_by_instruction.TryGetValue(instruction, out block));
 }
コード例 #4
0
 public int IndexOf(BasicBlock block) => _block_list.IndexOf(block);
コード例 #5
0
        internal void AddJumpOrigin(BasicBlock current, Instruction origin, Instruction target)
        {
            var block = _bb_by_instruction [target];

            block.AddJumpOrigin(new JumpOrigin(block, current, origin));
        }