public void Branches1()
        {
            var branchBuilder = new BranchBuilder();

            var l0   = branchBuilder.AddLabel();
            var l64  = branchBuilder.AddLabel();
            var l255 = branchBuilder.AddLabel();

            branchBuilder.MarkLabel(0, l0);
            branchBuilder.MarkLabel(64, l64);
            branchBuilder.MarkLabel(255, l255);

            branchBuilder.AddBranch(0, l255, (byte)ILOpCode.Bge_s);
            branchBuilder.AddBranch(16, l0, (byte)ILOpCode.Bge_un_s);   // blob boundary
            branchBuilder.AddBranch(33, l255, (byte)ILOpCode.Ble_s);    // blob boundary
            branchBuilder.AddBranch(35, l0, (byte)ILOpCode.Ble_un_s);   // branches immediately next to each other
            branchBuilder.AddBranch(37, l255, (byte)ILOpCode.Blt_s);    // branches immediately next to each other
            branchBuilder.AddBranch(40, l64, (byte)ILOpCode.Blt_un_s);
            branchBuilder.AddBranch(254, l0, (byte)ILOpCode.Brfalse_s); // long branch at the end

            var dstBuilder = new BlobBuilder();
            var srcBuilder = new BlobBuilder(capacity: 17);

            WriteFakeILWithBranches(srcBuilder, branchBuilder, size: 256);

            branchBuilder.FixupBranches(srcBuilder, dstBuilder);

            AssertEx.Equal(new byte[]
            {
                (byte)ILOpCode.Bge, 0xFA, 0x00, 0x00, 0x00,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                (byte)ILOpCode.Bge_un_s, 0xEE,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                (byte)ILOpCode.Ble, 0xD9, 0x00, 0x00, 0x00,
                (byte)ILOpCode.Ble_un_s, 0xDB,
                (byte)ILOpCode.Blt, 0xD5, 0x00, 0x00, 0x00,
                0x01,
                (byte)ILOpCode.Blt_un_s, 0x16,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01,
                (byte)ILOpCode.Brfalse, 0xFD, 0xFE, 0xFF, 0xFF,
            }, dstBuilder.ToArray());
        }
        public ExceptionRegionEncoder WriteInstructions(BlobBuilder codeBuilder, BranchBuilder branchBuilder, out int bodyOffset)
        {
            if (branchBuilder == null || branchBuilder.BranchCount == 0)
            {
                return(WriteInstructions(codeBuilder, out bodyOffset));
            }

            // When emitting branches we emitted short branches.
            int  initialCodeSize = codeBuilder.Count;
            Blob codeSizeFixup;

            if (IsTiny(initialCodeSize))
            {
                // If the method is tiny so far then all branches have to be short
                // (the max distance between any label and a branch instruction is < 64).
                bodyOffset    = WriteHeader(initialCodeSize);
                codeSizeFixup = default(Blob);
            }
            else
            {
                // Otherwise, it's fat format and we can fixup the size later on:
                bodyOffset = WriteHeader(initialCodeSize, true, out codeSizeFixup);
            }

            int codeStartOffset = Builder.Count;

            branchBuilder.FixupBranches(codeBuilder, Builder);
            if (!codeSizeFixup.IsDefault)
            {
                new BlobWriter(codeSizeFixup).WriteInt32(Builder.Count - codeStartOffset);
            }
            else
            {
                Debug.Assert(initialCodeSize == Builder.Count - codeStartOffset);
            }

            return(CreateExceptionEncoder());
        }
        public void Branches1()
        {
            var branchBuilder = new BranchBuilder();

            var l0 = branchBuilder.AddLabel();
            var l64 = branchBuilder.AddLabel();
            var l255 = branchBuilder.AddLabel();

            branchBuilder.MarkLabel(0, l0);
            branchBuilder.MarkLabel(64, l64);
            branchBuilder.MarkLabel(255, l255);

            branchBuilder.AddBranch(0, l255, (byte)ILOpCode.Bge_s);
            branchBuilder.AddBranch(16, l0, (byte)ILOpCode.Bge_un_s); // blob boundary
            branchBuilder.AddBranch(33, l255, (byte)ILOpCode.Ble_s); // blob boundary
            branchBuilder.AddBranch(35, l0, (byte)ILOpCode.Ble_un_s); // branches immediately next to each other
            branchBuilder.AddBranch(37, l255, (byte)ILOpCode.Blt_s); // branches immediately next to each other
            branchBuilder.AddBranch(40, l64, (byte)ILOpCode.Blt_un_s);
            branchBuilder.AddBranch(254, l0, (byte)ILOpCode.Brfalse_s); // long branch at the end

            var dstBuilder = new BlobBuilder();
            var srcBuilder = new BlobBuilder(size: 17);
            WriteFakeILWithBranches(srcBuilder, branchBuilder, size: 256);

            branchBuilder.FixupBranches(srcBuilder, dstBuilder);

            AssertEx.Equal(new byte[] 
            {
                (byte)ILOpCode.Bge, 0xFA, 0x00, 0x00, 0x00,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                (byte)ILOpCode.Bge_un_s, 0xEE,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                (byte)ILOpCode.Ble, 0xD9, 0x00, 0x00, 0x00,
                (byte)ILOpCode.Ble_un_s, 0xDB,
                (byte)ILOpCode.Blt, 0xD5, 0x00, 0x00, 0x00,
                0x01,
                (byte)ILOpCode.Blt_un_s, 0x16,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                0x01, 0x01, 0x01, 0x01,
                (byte)ILOpCode.Brfalse, 0xFD, 0xFE, 0xFF, 0xFF,
            }, dstBuilder.ToArray());
        }