예제 #1
0
        public void Append(Instruction instruction)
        {
            if (instruction == null)
                throw new ArgumentNullException ("instruction");

            instructions.Add (instruction);
        }
예제 #2
0
파일: Formatter.cs 프로젝트: ttRevan/cecil
 static void WriteInstruction(TextWriter writer, Instruction instruction)
 {
     writer.Write (FormatLabel (instruction.Offset));
     writer.Write (": ");
     writer.Write (instruction.OpCode.Name);
     if (null != instruction.Operand) {
         writer.Write (' ');
         WriteOperand (writer, instruction.Operand);
     }
 }
예제 #3
0
        public static Instruction Create(OpCode opcode, Instruction [] targets)
        {
            if (targets == null)
                throw new ArgumentNullException ("targets");
            if (opcode.OperandType != OperandType.InlineSwitch)
                throw new ArgumentException ("opcode");

            return new Instruction (opcode, targets);
        }
예제 #4
0
        public void Replace(Instruction target, Instruction instruction)
        {
            if (target == null)
                throw new ArgumentNullException ("target");
            if (instruction == null)
                throw new ArgumentNullException ("instruction");

            InsertAfter (target, instruction);
            Remove (target);
        }
예제 #5
0
        public void InsertBefore(Instruction target, Instruction instruction)
        {
            if (target == null)
                throw new ArgumentNullException ("target");
            if (instruction == null)
                throw new ArgumentNullException ("instruction");

            var index = instructions.IndexOf (target);
            if (index == -1)
                throw new ArgumentOutOfRangeException ("target");

            instructions.Insert (index, instruction);
        }
예제 #6
0
 public Instruction Create(OpCode opcode, Instruction [] targets)
 {
     return Instruction.Create (opcode, targets);
 }
예제 #7
0
파일: CodeReader.cs 프로젝트: ttRevan/cecil
        object ReadOperand(Instruction instruction)
        {
            switch (instruction.opcode.OperandType) {
            case OperandType.InlineSwitch:
                var length = ReadInt32 ();
                var base_offset = Offset + (4 * length);
                var branches = new int [length];
                for (int i = 0; i < length; i++)
                    branches [i] = base_offset + ReadInt32 ();
                return branches;
            case OperandType.ShortInlineBrTarget:
                return ReadSByte () + Offset;
            case OperandType.InlineBrTarget:
                return ReadInt32 () + Offset;
            case OperandType.ShortInlineI:
                if (instruction.opcode == OpCodes.Ldc_I4_S)
                    return ReadSByte ();

                return ReadByte ();
            case OperandType.InlineI:
                return ReadInt32 ();
            case OperandType.ShortInlineR:
                return ReadSingle ();
            case OperandType.InlineR:
                return ReadDouble ();
            case OperandType.InlineI8:
                return ReadInt64 ();
            case OperandType.ShortInlineVar:
                return GetVariable (ReadByte ());
            case OperandType.InlineVar:
                return GetVariable (ReadUInt16 ());
            case OperandType.ShortInlineArg:
                return GetParameter (ReadByte ());
            case OperandType.InlineArg:
                return GetParameter (ReadUInt16 ());
            case OperandType.InlineSig:
                return GetCallSite (ReadToken ());
            case OperandType.InlineString:
                return GetString (ReadToken ());
            case OperandType.InlineTok:
            case OperandType.InlineType:
            case OperandType.InlineMethod:
            case OperandType.InlineField:
                return reader.LookupToken (ReadToken ());
            default:
                throw new NotSupportedException ();
            }
        }
예제 #8
0
        static bool OptimizeBranch(Instruction instruction)
        {
            var offset = ((Instruction) instruction.Operand).Offset - (instruction.Offset + instruction.OpCode.Size + 4);
            if (!(offset >= -128 && offset <= 127))
                return false;

            switch (instruction.OpCode.Code) {
            case Code.Br:
                instruction.OpCode = OpCodes.Br_S;
                break;
            case Code.Brfalse:
                instruction.OpCode = OpCodes.Brfalse_S;
                break;
            case Code.Brtrue:
                instruction.OpCode = OpCodes.Brtrue_S;
                break;
            case Code.Beq:
                instruction.OpCode = OpCodes.Beq_S;
                break;
            case Code.Bge:
                instruction.OpCode = OpCodes.Bge_S;
                break;
            case Code.Bgt:
                instruction.OpCode = OpCodes.Bgt_S;
                break;
            case Code.Ble:
                instruction.OpCode = OpCodes.Ble_S;
                break;
            case Code.Blt:
                instruction.OpCode = OpCodes.Blt_S;
                break;
            case Code.Bne_Un:
                instruction.OpCode = OpCodes.Bne_Un_S;
                break;
            case Code.Bge_Un:
                instruction.OpCode = OpCodes.Bge_Un_S;
                break;
            case Code.Bgt_Un:
                instruction.OpCode = OpCodes.Bgt_Un_S;
                break;
            case Code.Ble_Un:
                instruction.OpCode = OpCodes.Ble_Un_S;
                break;
            case Code.Blt_Un:
                instruction.OpCode = OpCodes.Blt_Un_S;
                break;
            case Code.Leave:
                instruction.OpCode = OpCodes.Leave_S;
                break;
            }

            return true;
        }
예제 #9
0
파일: CodeWriter.cs 프로젝트: ttRevan/cecil
        static bool IsFatRange(Instruction start, Instruction end)
        {
            if (start == null)
                throw new ArgumentException ();

            if (end == null)
                return true;

            return end.Offset - start.Offset > 255 || start.Offset > 65535;
        }
예제 #10
0
파일: CodeWriter.cs 프로젝트: ttRevan/cecil
        static void CopyBranchStackSize(ref Dictionary<Instruction, int> stack_sizes, Instruction target, int stack_size)
        {
            if (stack_sizes == null)
                stack_sizes = new Dictionary<Instruction, int> ();

            int branch_stack_size = stack_size;

            int computed_size;
            if (stack_sizes.TryGetValue (target, out computed_size))
                branch_stack_size = System.Math.Max (branch_stack_size, computed_size);

            stack_sizes [target] = branch_stack_size;
        }
예제 #11
0
파일: CodeWriter.cs 프로젝트: ttRevan/cecil
        static void CopyBranchStackSize(Instruction instruction, ref Dictionary<Instruction, int> stack_sizes, int stack_size)
        {
            if (stack_size == 0)
                return;

            switch (instruction.opcode.OperandType) {
            case OperandType.ShortInlineBrTarget:
            case OperandType.InlineBrTarget:
                CopyBranchStackSize (ref stack_sizes, (Instruction) instruction.operand, stack_size);
                break;
            case OperandType.InlineSwitch:
                var targets = (Instruction[]) instruction.operand;
                for (int i = 0; i < targets.Length; i++)
                    CopyBranchStackSize (ref stack_sizes, targets [i], stack_size);
                break;
            }
        }
예제 #12
0
파일: CodeWriter.cs 프로젝트: ttRevan/cecil
 static void ComputeStackSize(Instruction instruction, ref int stack_size)
 {
     switch (instruction.opcode.FlowControl) {
     case FlowControl.Branch:
     case FlowControl.Break:
     case FlowControl.Throw:
     case FlowControl.Return:
         stack_size = 0;
         break;
     }
 }
예제 #13
0
파일: CodeWriter.cs 프로젝트: ttRevan/cecil
        static void ComputeStackSize(Instruction instruction, ref Dictionary<Instruction, int> stack_sizes, ref int stack_size, ref int max_stack)
        {
            int computed_size;
            if (stack_sizes != null && stack_sizes.TryGetValue (instruction, out computed_size))
                stack_size = computed_size;

            max_stack = System.Math.Max (max_stack, stack_size);
            ComputeStackDelta (instruction, ref stack_size);
            max_stack = System.Math.Max (max_stack, stack_size);

            CopyBranchStackSize (instruction, ref stack_sizes, stack_size);
            ComputeStackSize (instruction, ref stack_size);
        }
예제 #14
0
파일: CodeWriter.cs 프로젝트: ttRevan/cecil
 static void ComputeStackDelta(Instruction instruction, ref int stack_size)
 {
     switch (instruction.opcode.FlowControl) {
     case FlowControl.Call: {
         var method = (IMethodSignature) instruction.operand;
         // pop 'this' argument
         if (method.HasImplicitThis() && instruction.opcode.Code != Code.Newobj)
             stack_size--;
         // pop normal arguments
         if (method.HasParameters)
             stack_size -= method.Parameters.Count;
         // pop function pointer
         if (instruction.opcode.Code == Code.Calli)
             stack_size--;
         // push return value
         if (method.ReturnType.etype != ElementType.Void || instruction.opcode.Code == Code.Newobj)
             stack_size++;
         break;
     }
     default:
         ComputePopDelta (instruction.opcode.StackBehaviourPop, ref stack_size);
         ComputePushDelta (instruction.opcode.StackBehaviourPush, ref stack_size);
         break;
     }
 }
예제 #15
0
 static void AppendLabel(StringBuilder builder, Instruction instruction)
 {
     builder.Append ("IL_");
     builder.Append (instruction.offset.ToString ("x4"));
 }
예제 #16
0
 static void ExpandMacro(Instruction instruction, OpCode opcode, object operand)
 {
     instruction.OpCode = opcode;
     instruction.Operand = operand;
 }
예제 #17
0
 static void MakeMacro(Instruction instruction, OpCode opcode)
 {
     instruction.OpCode = opcode;
     instruction.Operand = null;
 }
예제 #18
0
파일: CodeWriter.cs 프로젝트: ttRevan/cecil
        int GetTargetOffset(Instruction instruction)
        {
            if (instruction == null) {
                var last = body.instructions [body.instructions.size - 1];
                return last.offset + last.GetSize ();
            }

            return instruction.offset;
        }
예제 #19
0
파일: CodeReader.cs 프로젝트: ttRevan/cecil
        void ReadCode()
        {
            start = position;
            var code_size = body.code_size;

            if (code_size < 0 || buffer.Length <= (uint) (code_size + position))
                code_size = 0;

            var end = start + code_size;
            var instructions = body.instructions = new InstructionCollection ((code_size + 1) / 2);

            while (position < end) {
                var offset = base.position - start;
                var opcode = ReadOpCode ();
                var current = new Instruction (offset, opcode);

                if (opcode.OperandType != OperandType.InlineNone)
                    current.operand = ReadOperand (current);

                instructions.Add (current);
            }

            ResolveBranches (instructions);
        }
예제 #20
0
파일: CodeWriter.cs 프로젝트: ttRevan/cecil
        void WriteOperand(Instruction instruction)
        {
            var opcode = instruction.opcode;
            var operand_type = opcode.OperandType;
            if (operand_type == OperandType.InlineNone)
                return;

            var operand = instruction.operand;
            if (operand == null)
                throw new ArgumentException ();

            switch (operand_type) {
            case OperandType.InlineSwitch: {
                var targets = (Instruction []) operand;
                WriteInt32 (targets.Length);
                var diff = instruction.Offset + opcode.Size + (4 * (targets.Length + 1));
                for (int i = 0; i < targets.Length; i++)
                    WriteInt32 (GetTargetOffset (targets [i]) - diff);
                break;
            }
            case OperandType.ShortInlineBrTarget: {
                var target = (Instruction) operand;
                WriteSByte ((sbyte) (GetTargetOffset (target) - (instruction.Offset + opcode.Size + 1)));
                break;
            }
            case OperandType.InlineBrTarget: {
                var target = (Instruction) operand;
                WriteInt32 (GetTargetOffset (target) - (instruction.Offset + opcode.Size + 4));
                break;
            }
            case OperandType.ShortInlineVar:
                WriteByte ((byte) GetVariableIndex ((VariableDefinition) operand));
                break;
            case OperandType.ShortInlineArg:
                WriteByte ((byte) GetParameterIndex ((ParameterDefinition) operand));
                break;
            case OperandType.InlineVar:
                WriteInt16 ((short) GetVariableIndex ((VariableDefinition) operand));
                break;
            case OperandType.InlineArg:
                WriteInt16 ((short) GetParameterIndex ((ParameterDefinition) operand));
                break;
            case OperandType.InlineSig:
                WriteMetadataToken (GetStandAloneSignature ((CallSite) operand));
                break;
            case OperandType.ShortInlineI:
                if (opcode == OpCodes.Ldc_I4_S)
                    WriteSByte ((sbyte) operand);
                else
                    WriteByte ((byte) operand);
                break;
            case OperandType.InlineI:
                WriteInt32 ((int) operand);
                break;
            case OperandType.InlineI8:
                WriteInt64 ((long) operand);
                break;
            case OperandType.ShortInlineR:
                WriteSingle ((float) operand);
                break;
            case OperandType.InlineR:
                WriteDouble ((double) operand);
                break;
            case OperandType.InlineString:
                WriteMetadataToken (
                    new MetadataToken (
                        TokenType.String,
                        GetUserStringIndex ((string) operand)));
                break;
            case OperandType.InlineType:
            case OperandType.InlineField:
            case OperandType.InlineMethod:
            case OperandType.InlineTok:
                WriteMetadataToken (metadata.LookupToken ((IMetadataTokenProvider) operand));
                break;
            default:
                throw new ArgumentException ();
            }
        }
예제 #21
0
파일: CodeReader.cs 프로젝트: ttRevan/cecil
        void ResolveBranches(Collection<Instruction> instructions)
        {
            var items = instructions.items;
            var size = instructions.size;

            for (int i = 0; i < size; i++) {
                var instruction = items [i];
                switch (instruction.opcode.OperandType) {
                case OperandType.ShortInlineBrTarget:
                case OperandType.InlineBrTarget:
                    instruction.operand = GetInstruction ((int) instruction.operand);
                    break;
                case OperandType.InlineSwitch:
                    var offsets = (int []) instruction.operand;
                    var branches = new Instruction [offsets.Length];
                    for (int j = 0; j < offsets.Length; j++)
                        branches [j] = GetInstruction (offsets [j]);

                    instruction.operand = branches;
                    break;
                }
            }
        }
예제 #22
0
파일: CodeWriter.cs 프로젝트: ttRevan/cecil
        static void AddExceptionStackSize(Instruction handler_start, ref Dictionary<Instruction, int> stack_sizes)
        {
            if (handler_start == null)
                return;

            if (stack_sizes == null)
                stack_sizes = new Dictionary<Instruction, int> ();

            stack_sizes [handler_start] = 1;
        }
예제 #23
0
 public void Emit(OpCode opcode, Instruction [] targets)
 {
     Append (Create (opcode, targets));
 }
예제 #24
0
파일: Formatter.cs 프로젝트: ttRevan/cecil
        static void WriteLabelList(TextWriter writer, Instruction [] instructions)
        {
            writer.Write ("(");

            for (int i = 0; i < instructions.Length; i++) {
                if (i != 0) writer.Write (", ");
                writer.Write (FormatLabel (instructions [i].Offset));
            }

            writer.Write (")");
        }
예제 #25
0
        public void Remove(Instruction instruction)
        {
            if (instruction == null)
                throw new ArgumentNullException ("instruction");

            if (!instructions.Remove (instruction))
                throw new ArgumentOutOfRangeException ("instruction");
        }
예제 #26
0
파일: Formatter.cs 프로젝트: ttRevan/cecil
 public static string FormatInstruction(Instruction instruction)
 {
     var writer = new StringWriter ();
     WriteInstruction (writer, instruction);
     return writer.ToString ();
 }
예제 #27
0
파일: Formatter.cs 프로젝트: ttRevan/cecil
 static string FormatLabel(Instruction instruction)
 {
     return FormatLabel (instruction.Offset);
 }
예제 #28
0
        public static Instruction Create(OpCode opcode, Instruction target)
        {
            if (target == null)
                throw new ArgumentNullException ("target");
            if (opcode.OperandType != OperandType.InlineBrTarget &&
                opcode.OperandType != OperandType.ShortInlineBrTarget)
                throw new ArgumentException ("opcode");

            return new Instruction (opcode, target);
        }