예제 #1
0
        public virtual void Replace(InstructionBase instr)
        {
            if (_list == null)
            {
                return;
            }

            var ix = _list._instructions.IndexOf(this);

            instr._list = _list;
            if (instr == null)
            {
                _list.RemoveAt(ix);
            }
            else
            {
                _list[ix] = instr;
            }

            foreach (var e in _exceptionBlocks)
            {
                if (e.BeginInstruction == this)
                {
                    e.BeginInstruction = instr;
                }
                if (e.HandlerInstruction == this)
                {
                    e.HandlerInstruction = instr;
                }
                if (e.FilterInstruction == this)
                {
                    e.FilterInstruction = instr;
                }
                if (e.EndInstruction == this)
                {
                    e.EndInstruction = instr;
                }
            }
            _exceptionBlocks.Clear();

            foreach (var l in _referencedBy)
            {
                if (l is SwitchInstruction)
                {
                    ((SwitchInstruction)l).ReplaceAll(this, instr);
                }
                else if (l is LabelInstruction)
                {
                    ((LabelInstruction)l).JumpToInstruction = instr;
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
            _referencedBy.Clear();

            _list = null;
        }
예제 #2
0
 public void Add(InstructionBase item)
 {
     if (item != null)
     {
         _jumpToInstructions.Add(item);
         item._referencedBy.Add(this);
     }
 }
예제 #3
0
 public void Insert(int index, InstructionBase item)
 {
     if (item != null)
     {
         _jumpToInstructions.Insert(index, item);
         item._referencedBy.Add(this);
     }
 }
예제 #4
0
        public void ReplaceAll(InstructionBase item, InstructionBase newItem)
        {
            int index;

            while ((index = _jumpToInstructions.IndexOf(item)) >= 0)
            {
                this[index] = newItem;
            }
        }
예제 #5
0
        public bool Remove(InstructionBase item)
        {
            if (item == null)
            {
                return(false);
            }

            if (_jumpToInstructions.Remove(item))
            {
                if (!_jumpToInstructions.Contains(item))
                {
                    item._referencedBy.Remove(this);
                }
                return(true);
            }
            return(false);
        }
예제 #6
0
        private void LinkInstruction(ref InstructionBase current, InstructionBase value)
        {
            if (current == value)
            {
                return;
            }

            if (current != null)
            {
                current._exceptionBlocks.Remove(this);
            }

            if (value != null)
            {
                value._exceptionBlocks.Add(this);
            }

            current = value;
        }
예제 #7
0
 internal override void ParseOperand()
 {
     JumpToInstruction = _list._instructions.First(x => x.LineNumber == _offset);
 }
예제 #8
0
        public static InstructionBase Parse(byte[] data, ref int offset, InstructionList list)
        {
            int line = offset;
            int op   = data[offset++];

            if (op == 0xfe)
            {
                op = 0xfe00 | data[offset++];
            }

            InstructionBase inst = null;

            var opCode = OpCodeList.ByValue[op];

            switch (opCode.OperandType)
            {
            case OperandType.ShortInlineBrTarget:
            case OperandType.InlineBrTarget: inst = new LabelInstruction(); break;

            case OperandType.InlineField: inst = new FieldInstruction(); break;

            case OperandType.InlineI: inst = new Int32Instruction(); break;

            case OperandType.InlineI8: inst = new Int64Instruction(); break;

            case OperandType.InlineMethod: inst = new MethodInstruction(); break;

            case OperandType.InlineNone:
                switch ((ILCode)op)
                {
                case ILCode.Ldarg_0:
                case ILCode.Ldarg_1:
                case ILCode.Ldarg_2:
                case ILCode.Ldarg_3:
                    inst = new ParameterInstruction();
                    break;

                case ILCode.Stloc_0:
                case ILCode.Ldloc_0:
                case ILCode.Stloc_1:
                case ILCode.Ldloc_1:
                case ILCode.Stloc_2:
                case ILCode.Ldloc_2:
                case ILCode.Stloc_3:
                case ILCode.Ldloc_3:
                    inst = new LocalInstruction();
                    break;

                case ILCode.Ldc_I4_0:
                case ILCode.Ldc_I4_1:
                case ILCode.Ldc_I4_2:
                case ILCode.Ldc_I4_3:
                case ILCode.Ldc_I4_4:
                case ILCode.Ldc_I4_5:
                case ILCode.Ldc_I4_6:
                case ILCode.Ldc_I4_7:
                case ILCode.Ldc_I4_8:
                case ILCode.Ldc_I4_M1:
                    inst = new Int32Instruction();
                    break;

                default:
                    inst = new InstructionBase();
                    break;
                }
                break;

            case OperandType.InlineR: inst = new DoubleInstruction(); break;

            case OperandType.InlineSig: inst = new SignatureInstruction(); break;

            case OperandType.InlineString: inst = new StringInstruction(); break;

            case OperandType.InlineSwitch: inst = new SwitchInstruction(); break;

            case OperandType.InlineTok: inst = new MemberInstruction(); break;

            case OperandType.InlineType: inst = new TypeInstruction(); break;

            case OperandType.InlineVar:
                inst = (opCode == OpCodes.Ldarg || opCode == OpCodes.Ldarga || opCode == OpCodes.Starg) ? (InstructionBase) new ParameterInstruction() : new LocalInstruction();
                break;

            case OperandType.ShortInlineVar:
                inst = (opCode == OpCodes.Ldarga_S || opCode == OpCodes.Ldarg_S || opCode == OpCodes.Starg_S) ? (InstructionBase) new ParameterInstruction() : new LocalInstruction();
                break;

            case OperandType.ShortInlineI: inst = new Int8Instruction(); break;

            case OperandType.ShortInlineR: inst = new SingleInstruction(); break;

            default: throw new InvalidOperationException();
            }

            inst._lineNumber = line;
            inst._opCode     = opCode;
            inst._list       = list;

            inst.ReadOperand(data, ref offset);

            return(inst);
        }
예제 #9
0
 public bool Contains(InstructionBase item)
 {
     return(_jumpToInstructions.Contains(item));
 }
예제 #10
0
 public int IndexOf(InstructionBase item)
 {
     return(_jumpToInstructions.IndexOf(item));
 }