Example #1
0
        /// <summary>
        /// Reads a single CIL instruction from a given data stream.
        /// </summary>
        /// <param name="stream">The source data stream.</param>
        /// <param name="instruction">The instruction that was read, undefined if the method returns zero.</param>
        /// <returns>A value indicating if an instruction was read, <c>false</c> if the end of the stream was reached.</returns>
        public static bool ReadInstruction(Stream stream, out RawInstruction instruction)
        {
            Contract.Requires(stream != null && stream.CanRead);

            int firstOpcodeByte = stream.ReadByte();

            if (unchecked ((byte)firstOpcodeByte) != firstOpcodeByte)
            {
                instruction = default(RawInstruction);
                return(false);
            }

            OpcodeValue opcodeValue;

            if (OpcodeValueEnum.IsFirstOfTwoBytes((byte)firstOpcodeByte))
            {
                opcodeValue = (OpcodeValue)((firstOpcodeByte << 8) | stream.ReadUInt8());
            }
            else
            {
                opcodeValue = (OpcodeValue)firstOpcodeByte;
            }

            var opcode = Opcode.FromValue(opcodeValue);

            if (opcode == Opcode.Switch)
            {
                // Read jump table
                int[] jumpTable = new int[stream.ReadUInt32()];
                for (int i = 0; i < jumpTable.Length; ++i)
                {
                    jumpTable[i] = stream.ReadInt32();
                }
                instruction = RawInstruction.CreateSwitch(jumpTable);
            }
            else
            {
                NumericalOperand operand;
                switch ((int)opcode.OperandKind.GetSizeInBytes())
                {
                case 0: operand = default(NumericalOperand); break;

                case 1: operand = stream.ReadInt8(); break;

                case 2: operand = stream.ReadInt16(); break;

                case 4: operand = stream.ReadInt32(); break;

                case 8: operand = stream.ReadInt64(); break;

                default: throw new NotSupportedException("Unexpected opcode operand size");
                }
                instruction = new RawInstruction(opcode, operand);
            }

            return(true);
        }
Example #2
0
 /// <summary>
 /// Writes a <c>switch</c> CIL instruction to this sink.
 /// </summary>
 /// <param name="jumpTable">The switch's jump table.</param>
 public void Switch(int[] jumpTable)
 {
     Instruction(RawInstruction.CreateSwitch(jumpTable));
 }