#pragma warning restore

        protected virtual void MarkExceptionBlock(ILGenerator il, ExceptionBlockInfo info)
        {
            ExceptionBlockType btype = info.blockType;

            if ((btype & ExceptionBlockType.End) != 0)
            {
                il.EndExceptionBlock();
            }
            else // begin
            {
                switch (btype & flagValue)
                {
                case ExceptionBlockType.BigBlock:
                    il.BeginExceptionBlock();
                    return;

                case ExceptionBlockType.FilterBlock:
                    il.BeginExceptFilterBlock();
                    return;

                case ExceptionBlockType.FinallyBlock:
                    il.BeginFinallyBlock();
                    return;

                case ExceptionBlockType.CatchBlock:
                    il.BeginCatchBlock(info.catchType);
                    return;

                case ExceptionBlockType.FaultBlock:
                    il.BeginFaultBlock();
                    return;

                default:
#if DEBUG
                    System.Diagnostics.Debug.WriteLine($"[ERROR] {btype}");
#endif
                    return;
                }
            }
        }
#pragma warning disable
        protected virtual void EmitCode(ILGenerator il, IReadOnlyList <ILBuffer> codes)
        {
            foreach (ILBuffer current in codes)
            {
                OpCode             code  = current.code;
                PublicLabel        label = current.label;
                ExceptionBlockInfo eb    = current.blockInfo;

                if (label.valid)
                {
                    il.MarkLabel((Label)label);
                }

                if (eb.IsValid)
                {
                    MarkExceptionBlock(il, eb);
                }

                switch (code.OperandType)
                {
                case OperandType.ShortInlineBrTarget:
                case OperandType.InlineBrTarget:
                    il.Emit(code, (Label)FindILBuffer(codes, (int)current.operand).label);
                    break;

                case OperandType.InlineField:
                    il.Emit(code, (FieldInfo)current.operand);
                    break;

                case OperandType.InlineMethod:
                {
                    if (current.operand is MethodInfo temp)
                    {
                        il.Emit(code, temp);
                    }
                    else
                    {
                        il.Emit(code, (ConstructorInfo)current.operand);
                    }
                }
                break;

                case OperandType.InlineType:
                    il.Emit(code, (Type)current.operand);
                    break;

                case OperandType.InlineI:
                    il.Emit(code, (int)current.operand);
                    break;

                case OperandType.InlineI8:
                    il.Emit(code, (long)current.operand);
                    break;

                case OperandType.InlineR:
                    il.Emit(code, (double)current.operand);
                    break;

                case OperandType.InlineSig:
                {
                    if (current.operand is SignatureHelper temp)
                    {
                        il.Emit(code, temp);
                    }
                    else
                    {
                        il.Emit(code, (int)current.operand);
                    }
                }
                break;

                case OperandType.InlineString:
                    il.Emit(code, (string)current.operand);
                    break;

                case OperandType.InlineSwitch:
                {
                    foreach (int temp in (int[])current.operand)
                    {
                        il.Emit(code, (Label)FindILBuffer(codes, temp).label);
                    }
                }
                break;

                case OperandType.InlineTok:
                {
                    if (current.operand is Type temp)
                    {
                        il.Emit(code, temp);
                    }
                    else
                    {
                        il.Emit(code, (int)current.operand);
                    }
                }
                break;

                case OperandType.InlineVar:
                    il.Emit(code, (short)current.operand);
                    break;

                case OperandType.ShortInlineI:
                    il.Emit(code, (byte)current.operand);
                    break;

                case OperandType.ShortInlineR:
                    il.Emit(code, (float)current.operand);
                    break;

                case OperandType.ShortInlineVar:
                    il.Emit(code, (byte)current.operand);
                    break;

                default:     // no operand
                    il.Emit(code);
                    break;
                }
            }
        }