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()); }