/// <summary>
        /// Writes an <see cref="OperandType.InlineSwitch"/> operand
        /// </summary>
        /// <param name="writer">Instruction writer</param>
        /// <param name="instr">Instruction</param>
        protected virtual void WriteInlineSwitch(ref ArrayWriter writer, Instruction instr)
        {
            var targets = instr.Operand as IList <Instruction>;

            if (targets is null)
            {
                Error("switch operand is not a list of instructions");
                writer.WriteInt32(0);
            }
            else
            {
                uint offsetAfter = (uint)(ToInstructionOffset(ref writer) + 4 + targets.Count * 4);
                writer.WriteInt32(targets.Count);
                for (int i = 0; i < targets.Count; i++)
                {
                    var target = targets[i];
                    writer.WriteUInt32(GetOffset(target) - offsetAfter);
                }
            }
        }
        /// <summary>
        /// Writes a <see cref="OperandType.ShortInlineVar"/> operand
        /// </summary>
        /// <param name="writer">Instruction writer</param>
        /// <param name="instr">Instruction</param>
        protected virtual void WriteShortInlineVar(ref ArrayWriter writer, Instruction instr)
        {
            var variable = instr.Operand as IVariable;

            if (variable is null)
            {
                Error("Operand is not a local/arg");
                writer.WriteByte(0);
            }
            else
            {
                int index = variable.Index;
                if (byte.MinValue <= index && index <= byte.MaxValue)
                {
                    writer.WriteByte((byte)index);
                }
                else
                {
                    Error("Local/arg index doesn't fit in a Byte. Use the longer ldloc/ldarg/stloc/starg instruction.");
                    writer.WriteByte(0);
                }
            }
        }
        /// <summary>
        /// Writes an <see cref="OperandType.InlineVar"/> operand
        /// </summary>
        /// <param name="writer">Instruction writer</param>
        /// <param name="instr">Instruction</param>
        protected virtual void WriteInlineVar(ref ArrayWriter writer, Instruction instr)
        {
            var variable = instr.Operand as IVariable;

            if (variable is null)
            {
                Error("Operand is not a local/arg");
                writer.WriteUInt16(0);
            }
            else
            {
                int index = variable.Index;
                if (ushort.MinValue <= index && index <= ushort.MaxValue)
                {
                    writer.WriteUInt16((ushort)index);
                }
                else
                {
                    Error("Local/arg index doesn't fit in a UInt16");
                    writer.WriteUInt16(0);
                }
            }
        }
 /// <summary>
 /// Writes an <see cref="OperandType.InlineType"/> operand
 /// </summary>
 /// <param name="writer">Instruction writer</param>
 /// <param name="instr">Instruction</param>
 protected abstract void WriteInlineType(ref ArrayWriter writer, Instruction instr);
 /// <summary>
 /// Writes an <see cref="OperandType.InlinePhi"/> operand
 /// </summary>
 /// <param name="writer">Instruction writer</param>
 /// <param name="instr">Instruction</param>
 protected virtual void WriteInlinePhi(ref ArrayWriter writer, Instruction instr)
 {
 }
        /// <summary>
        /// Writes an <see cref="OperandType.InlineBrTarget"/> operand
        /// </summary>
        /// <param name="writer">Instruction writer</param>
        /// <param name="instr">Instruction</param>
        protected virtual void WriteInlineBrTarget(ref ArrayWriter writer, Instruction instr)
        {
            uint displ = GetOffset(instr.Operand as Instruction) - (ToInstructionOffset(ref writer) + 4);

            writer.WriteUInt32(displ);
        }
 /// <summary>
 /// Writes an instruction
 /// </summary>
 /// <param name="writer">The instruction writer</param>
 /// <param name="instr">The instruction</param>
 protected virtual void WriteInstruction(ref ArrayWriter writer, Instruction instr)
 {
     WriteOpCode(ref writer, instr);
     WriteOperand(ref writer, instr);
 }
 /// <summary>
 /// Gets the current offset in the instruction stream. This offset is relative to
 /// the first written instruction.
 /// </summary>
 /// <param name="writer">The instruction writer</param>
 /// <returns>Current offset, relative to the first written instruction</returns>
 protected uint ToInstructionOffset(ref ArrayWriter writer) => (uint)writer.Position - firstInstructionOffset;