static byte[] GenerateSampleIL(ControlFlowBuilder cfb) { var code = new BlobBuilder(); var il = new InstructionEncoder(code, cfb); var l1 = il.DefineLabel(); var l2 = il.DefineLabel(); var l3 = il.DefineLabel(); var l4 = il.DefineLabel(); il.MarkLabel(l1); il.OpCode(ILOpCode.Nop); il.Branch(ILOpCode.Br_s, l1); il.MarkLabel(l2); il.OpCode(ILOpCode.Nop); il.MarkLabel(l3); il.OpCode(ILOpCode.Nop); il.MarkLabel(l4); cfb.AddCatchRegion(l1, l2, l3, l4, MetadataTokens.TypeDefinitionHandle(1)); var builder = new BlobBuilder(); new MethodBodyStreamEncoder(builder).AddMethodBody(il); return(builder.ToArray()); }
public unsafe void TinyBody() { var streamBuilder = new BlobBuilder(); var codeBuilder = new BlobBuilder(); var flowBuilder = new ControlFlowBuilder(); var il = new InstructionEncoder(codeBuilder, flowBuilder); codeBuilder.WriteBytes(1, 61); var l1 = il.DefineLabel(); il.MarkLabel(l1); Assert.Equal(61, flowBuilder.Labels.Single()); il.Branch(ILOpCode.Br_s, l1); var brInfo = flowBuilder.Branches.Single(); Assert.Equal(61, brInfo.ILOffset); Assert.Equal(l1, brInfo.Label); Assert.Equal(ILOpCode.Br_s, brInfo.OpCode); AssertEx.Equal(new byte[] { 1, (byte)ILOpCode.Br_s, unchecked ((byte)-1) }, codeBuilder.ToArray(60, 3)); var streamEncoder = new MethodBodyStreamEncoder(streamBuilder); int bodyOffset = streamEncoder.AddMethodBody( il, maxStack: 2, localVariablesSignature: default,
public void Branch_LongInstruction_ShortDistance() { var code = new BlobBuilder(); var flow = new ControlFlowBuilder(); var il = new InstructionEncoder(code, flow); var l1 = il.DefineLabel(); il.Branch(ILOpCode.Br, l1); il.Call(MetadataTokens.MethodDefinitionHandle(1)); il.MarkLabel(l1); il.OpCode(ILOpCode.Ret); var builder = new BlobBuilder(); new MethodBodyStreamEncoder(builder).AddMethodBody(il); AssertEx.Equal(new byte[] { 0x2E, // header (byte)ILOpCode.Br, 0x05, 0x00, 0x00, 0x00, (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06, (byte)ILOpCode.Ret }, builder.ToArray()); }
public void MarkLabel() { var code = new BlobBuilder(); var il = new InstructionEncoder(code, new ControlFlowBuilder()); var l = il.DefineLabel(); il.Branch(ILOpCode.Br_s, l); il.MarkLabel(l); il.OpCode(ILOpCode.Nop); il.OpCode(ILOpCode.Nop); il.MarkLabel(l); il.OpCode(ILOpCode.Ret); var builder = new BlobBuilder(); new MethodBodyStreamEncoder(builder).AddMethodBody(il); AssertEx.Equal(new byte[] { 0x16, // header (byte)ILOpCode.Br_s, 0x02, (byte)ILOpCode.Nop, (byte)ILOpCode.Nop, (byte)ILOpCode.Ret, }, builder.ToArray()); }
public void BranchErrors() { var codeBuilder = new BlobBuilder(); var il = new InstructionEncoder(codeBuilder); Assert.Throws <InvalidOperationException>(() => il.DefineLabel()); il = new InstructionEncoder(codeBuilder, new ControlFlowBuilder()); il.DefineLabel(); il.DefineLabel(); var l2 = il.DefineLabel(); var flowBuilder = new ControlFlowBuilder(); il = new InstructionEncoder(codeBuilder, flowBuilder); var l0 = il.DefineLabel(); Assert.Throws <ArgumentException>(() => il.Branch(ILOpCode.Nop, l0)); Assert.Throws <ArgumentNullException>(() => il.Branch(ILOpCode.Br, default(LabelHandle))); Assert.Throws <ArgumentException>(() => il.Branch(ILOpCode.Br, l2)); }
public void BranchErrors_UnmarkedLabel() { var streamBuilder = new BlobBuilder(); var codeBuilder = new BlobBuilder(); var flowBuilder = new ControlFlowBuilder(); var il = new InstructionEncoder(codeBuilder, flowBuilder); var l = il.DefineLabel(); il.Branch(ILOpCode.Br_s, l); il.OpCode(ILOpCode.Ret); Assert.Throws <InvalidOperationException>(() => new MethodBodyStreamEncoder(streamBuilder).AddMethodBody(il)); }
public void BranchAndLabel_Errors() { var builder = new BlobBuilder(); var il = new InstructionEncoder(builder); var ilcf1 = new InstructionEncoder(builder, new ControlFlowBuilder()); var ilcf2 = new InstructionEncoder(builder, new ControlFlowBuilder()); var l1 = ilcf1.DefineLabel(); ilcf2.DefineLabel(); var l2 = ilcf2.DefineLabel(); Assert.Throws <InvalidOperationException>(() => il.DefineLabel()); Assert.Throws <InvalidOperationException>(() => il.Branch(ILOpCode.Br, default(LabelHandle))); Assert.Throws <InvalidOperationException>(() => il.MarkLabel(default(LabelHandle))); Assert.Throws <ArgumentNullException>(() => ilcf1.Branch(ILOpCode.Br, default(LabelHandle))); Assert.Throws <ArgumentNullException>(() => ilcf1.MarkLabel(default(LabelHandle))); Assert.Throws <ArgumentException>(() => ilcf1.Branch(ILOpCode.Br, l2)); Assert.Throws <ArgumentException>(() => ilcf1.MarkLabel(l2)); Assert.Throws <ArgumentException>(() => ilcf1.Branch(ILOpCode.Box, l1)); }
public void Branch_ShortInstruction_LongDistance() { var code = new BlobBuilder(); var flow = new ControlFlowBuilder(); var il = new InstructionEncoder(code, flow); var l1 = il.DefineLabel(); il.Branch(ILOpCode.Br_s, l1); for (int i = 0; i < 100; i++) { il.Call(MetadataTokens.MethodDefinitionHandle(1)); } il.MarkLabel(l1); il.OpCode(ILOpCode.Ret); var builder = new BlobBuilder(); var encoder = new MethodBodyStreamEncoder(builder); Assert.Throws <InvalidOperationException>(() => encoder.AddMethodBody(il)); }
private static MethodDefinitionHandle BasicValidationEmit(MetadataBuilder metadata, BlobBuilder ilBuilder) { metadata.AddModule( 0, metadata.GetOrAddString("ConsoleApplication.exe"), metadata.GetOrAddGuid(Guid.NewGuid()), default(GuidHandle), default(GuidHandle)); metadata.AddAssembly( metadata.GetOrAddString("ConsoleApplication"), version: new Version(0, 0, 0, 0), culture: default(StringHandle), publicKey: default(BlobHandle), flags: default(AssemblyFlags), hashAlgorithm: AssemblyHashAlgorithm.Sha1); var mscorlibAssemblyRef = metadata.AddAssemblyReference( name: metadata.GetOrAddString("mscorlib"), version: new Version(4, 0, 0, 0), culture: default(StringHandle), publicKeyOrToken: metadata.GetOrAddBlob(ImmutableArray.Create<byte>(0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89)), flags: default(AssemblyFlags), hashValue: default(BlobHandle)); var systemObjectTypeRef = metadata.AddTypeReference( mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Object")); var systemConsoleTypeRefHandle = metadata.AddTypeReference( mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Console")); var consoleWriteLineSignature = new BlobBuilder(); new BlobEncoder(consoleWriteLineSignature). MethodSignature(). Parameters(1, returnType => returnType.Void(), parameters => { parameters.AddParameter().Type().String(); parameters.EndParameters(); }); var consoleWriteLineMemberRef = metadata.AddMemberReference( systemConsoleTypeRefHandle, metadata.GetOrAddString("WriteLine"), metadata.GetOrAddBlob(consoleWriteLineSignature)); var parameterlessCtorSignature = new BlobBuilder(); new BlobEncoder(parameterlessCtorSignature). MethodSignature(isInstanceMethod: true). Parameters(0, returnType => returnType.Void(), parameters => parameters.EndParameters()); var parameterlessCtorBlobIndex = metadata.GetOrAddBlob(parameterlessCtorSignature); var objectCtorMemberRef = metadata.AddMemberReference( systemObjectTypeRef, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex); var mainSignature = new BlobBuilder(); new BlobEncoder(mainSignature). MethodSignature(). Parameters(0, returnType => returnType.Void(), parameters => parameters.EndParameters()); var methodBodies = new MethodBodiesEncoder(ilBuilder); var codeBuilder = new BlobBuilder(); var branchBuilder = new BranchBuilder(); InstructionEncoder il; // // Program::.ctor // int ctorBodyOffset; il = new InstructionEncoder(codeBuilder); // ldarg.0 il.LoadArgument(0); // call instance void [mscorlib]System.Object::.ctor() il.Call(objectCtorMemberRef); // ret il.OpCode(ILOpCode.Ret); methodBodies.AddMethodBody().WriteInstructions(codeBuilder, out ctorBodyOffset); codeBuilder.Clear(); // // Program::Main // int mainBodyOffset; il = new InstructionEncoder(codeBuilder, branchBuilder); var endLabel = il.DefineLabel(); // .try int tryOffset = il.Offset; // ldstr "hello" il.LoadString(metadata.GetOrAddUserString("hello")); // call void [mscorlib]System.Console::WriteLine(string) il.Call(consoleWriteLineMemberRef); // leave.s END il.Branch(ILOpCode.Leave, endLabel); // .finally int handlerOffset = il.Offset; // ldstr "world" il.LoadString(metadata.GetOrAddUserString("world")); // call void [mscorlib]System.Console::WriteLine(string) il.Call(consoleWriteLineMemberRef); // .endfinally il.OpCode(ILOpCode.Endfinally); int handlerEnd = il.Offset; // END: il.MarkLabel(endLabel); // ret il.OpCode(ILOpCode.Ret); var body = methodBodies.AddMethodBody(exceptionRegionCount: 1); var eh = body.WriteInstructions(codeBuilder, branchBuilder, out mainBodyOffset); eh.StartRegions(); eh.AddFinally(tryOffset, handlerOffset - tryOffset, handlerOffset, handlerEnd - handlerOffset); eh.EndRegions(); codeBuilder.Clear(); branchBuilder.Clear(); var mainMethodDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig, MethodImplAttributes.IL | MethodImplAttributes.Managed, metadata.GetOrAddString("Main"), metadata.GetOrAddBlob(mainSignature), mainBodyOffset, paramList: default(ParameterHandle)); var ctorDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, MethodImplAttributes.IL | MethodImplAttributes.Managed, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex, ctorBodyOffset, paramList: default(ParameterHandle)); metadata.AddTypeDefinition( default(TypeAttributes), default(StringHandle), metadata.GetOrAddString("<Module>"), baseType: default(EntityHandle), fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: mainMethodDef); metadata.AddTypeDefinition( TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit, metadata.GetOrAddString("ConsoleApplication"), metadata.GetOrAddString("Program"), systemObjectTypeRef, fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: mainMethodDef); return mainMethodDef; }
public void BranchAndLabel_Errors() { var builder = new BlobBuilder(); var il = new InstructionEncoder(builder); var ilcf1 = new InstructionEncoder(builder, new ControlFlowBuilder()); var ilcf2 = new InstructionEncoder(builder, new ControlFlowBuilder()); var l1 = ilcf1.DefineLabel(); ilcf2.DefineLabel(); var l2 = ilcf2.DefineLabel(); Assert.Throws<InvalidOperationException>(() => il.DefineLabel()); Assert.Throws<InvalidOperationException>(() => il.Branch(ILOpCode.Br, default(LabelHandle))); Assert.Throws<InvalidOperationException>(() => il.MarkLabel(default(LabelHandle))); Assert.Throws<ArgumentNullException>(() => ilcf1.Branch(ILOpCode.Br, default(LabelHandle))); Assert.Throws<ArgumentNullException>(() => ilcf1.MarkLabel(default(LabelHandle))); Assert.Throws<ArgumentException>(() => ilcf1.Branch(ILOpCode.Br, l2)); Assert.Throws<ArgumentException>(() => ilcf1.MarkLabel(l2)); Assert.Throws<ArgumentException>(() => ilcf1.Branch(ILOpCode.Box, l1)); }
public unsafe void FatBody() { var streamBuilder = new BlobBuilder(); var codeBuilder = new BlobBuilder(); var flowBuilder = new ControlFlowBuilder(); var il = new InstructionEncoder(codeBuilder, flowBuilder); codeBuilder.WriteBytes(1, 62); var l1 = il.DefineLabel(); il.MarkLabel(l1); Assert.Equal(62, flowBuilder.Labels.Single()); il.Branch(ILOpCode.Br_s, l1); var brInfo = flowBuilder.Branches.Single(); Assert.Equal(62, brInfo.ILOffset); Assert.Equal(l1, brInfo.Label); Assert.Equal(ILOpCode.Br_s, brInfo.OpCode); AssertEx.Equal(new byte[] { 1, 1, (byte)ILOpCode.Br_s, unchecked ((byte)-1) }, codeBuilder.ToArray(60, 4)); var streamEncoder = new MethodBodyStreamEncoder(streamBuilder); int bodyOffset = streamEncoder.AddMethodBody( il, maxStack: 2, localVariablesSignature: default(StandaloneSignatureHandle), attributes: MethodBodyAttributes.None); var bodyBytes = streamBuilder.ToArray(); AssertEx.Equal(new byte[] { 0x03, 0x30, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // fat header 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x2B, 0xFE }, bodyBytes); fixed(byte *bodyPtr = &bodyBytes[0]) { var body = MethodBodyBlock.Create(new BlobReader(bodyPtr, bodyBytes.Length)); Assert.Equal(0, body.ExceptionRegions.Length); Assert.Equal(default(StandaloneSignatureHandle), body.LocalSignature); Assert.Equal(2, body.MaxStack); Assert.Equal(bodyBytes.Length, body.Size); var ilBytes = body.GetILBytes(); AssertEx.Equal(new byte[] { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x2B, 0xFE }, ilBytes); } }
private static MethodDefinitionHandle BasicValidationEmit(MetadataBuilder metadata, BlobBuilder ilBuilder) { metadata.AddModule( 0, metadata.GetOrAddString("ConsoleApplication.exe"), metadata.GetOrAddGuid(Guid.NewGuid()), default(GuidHandle), default(GuidHandle)); metadata.AddAssembly( metadata.GetOrAddString("ConsoleApplication"), version: new Version(0, 0, 0, 0), culture: default(StringHandle), publicKey: default(BlobHandle), flags: default(AssemblyFlags), hashAlgorithm: AssemblyHashAlgorithm.Sha1); var mscorlibAssemblyRef = metadata.AddAssemblyReference( name: metadata.GetOrAddString("mscorlib"), version: new Version(4, 0, 0, 0), culture: default(StringHandle), publicKeyOrToken: metadata.GetOrAddBlob(ImmutableArray.Create <byte>(0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89)), flags: default(AssemblyFlags), hashValue: default(BlobHandle)); var systemObjectTypeRef = metadata.AddTypeReference( mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Object")); var systemConsoleTypeRefHandle = metadata.AddTypeReference( mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Console")); var consoleWriteLineSignature = new BlobBuilder(); new BlobEncoder(consoleWriteLineSignature). MethodSignature(). Parameters(1, returnType => returnType.Void(), parameters => parameters.AddParameter().Type().String()); var consoleWriteLineMemberRef = metadata.AddMemberReference( systemConsoleTypeRefHandle, metadata.GetOrAddString("WriteLine"), metadata.GetOrAddBlob(consoleWriteLineSignature)); var parameterlessCtorSignature = new BlobBuilder(); new BlobEncoder(parameterlessCtorSignature). MethodSignature(isInstanceMethod: true). Parameters(0, returnType => returnType.Void(), parameters => { }); var parameterlessCtorBlobIndex = metadata.GetOrAddBlob(parameterlessCtorSignature); var objectCtorMemberRef = metadata.AddMemberReference( systemObjectTypeRef, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex); var mainSignature = new BlobBuilder(); new BlobEncoder(mainSignature). MethodSignature(). Parameters(0, returnType => returnType.Void(), parameters => { }); var methodBodies = new MethodBodiesEncoder(ilBuilder); var codeBuilder = new BlobBuilder(); var branchBuilder = new BranchBuilder(); InstructionEncoder il; // // Program::.ctor // int ctorBodyOffset; il = new InstructionEncoder(codeBuilder); // ldarg.0 il.LoadArgument(0); // call instance void [mscorlib]System.Object::.ctor() il.Call(objectCtorMemberRef); // ret il.OpCode(ILOpCode.Ret); methodBodies.AddMethodBody().WriteInstructions(codeBuilder, out ctorBodyOffset); codeBuilder.Clear(); // // Program::Main // int mainBodyOffset; il = new InstructionEncoder(codeBuilder, branchBuilder); var endLabel = il.DefineLabel(); // .try int tryOffset = il.Offset; // ldstr "hello" il.LoadString(metadata.GetOrAddUserString("hello")); // call void [mscorlib]System.Console::WriteLine(string) il.Call(consoleWriteLineMemberRef); // leave.s END il.Branch(ILOpCode.Leave, endLabel); // .finally int handlerOffset = il.Offset; // ldstr "world" il.LoadString(metadata.GetOrAddUserString("world")); // call void [mscorlib]System.Console::WriteLine(string) il.Call(consoleWriteLineMemberRef); // .endfinally il.OpCode(ILOpCode.Endfinally); int handlerEnd = il.Offset; // END: il.MarkLabel(endLabel); // ret il.OpCode(ILOpCode.Ret); var body = methodBodies.AddMethodBody(exceptionRegionCount: 1); var eh = body.WriteInstructions(codeBuilder, branchBuilder, out mainBodyOffset); eh.StartRegions(); eh.AddFinally(tryOffset, handlerOffset - tryOffset, handlerOffset, handlerEnd - handlerOffset); eh.EndRegions(); codeBuilder.Clear(); branchBuilder.Clear(); var mainMethodDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig, MethodImplAttributes.IL | MethodImplAttributes.Managed, metadata.GetOrAddString("Main"), metadata.GetOrAddBlob(mainSignature), mainBodyOffset, paramList: default(ParameterHandle)); var ctorDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, MethodImplAttributes.IL | MethodImplAttributes.Managed, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex, ctorBodyOffset, paramList: default(ParameterHandle)); metadata.AddTypeDefinition( default(TypeAttributes), default(StringHandle), metadata.GetOrAddString("<Module>"), baseType: default(EntityHandle), fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: mainMethodDef); metadata.AddTypeDefinition( TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit, metadata.GetOrAddString("ConsoleApplication"), metadata.GetOrAddString("Program"), systemObjectTypeRef, fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: mainMethodDef); return(mainMethodDef); }
public unsafe void TinyBody() { var bodyBuilder = new BlobBuilder(); var codeBuilder = new BlobBuilder(); var branchBuilder = new BranchBuilder(); var il = new InstructionEncoder(codeBuilder, branchBuilder); var bodyEncoder = new MethodBodyEncoder( bodyBuilder, maxStack: 2, exceptionRegionCount: 0, localVariablesSignature: default(StandaloneSignatureHandle), attributes: MethodBodyAttributes.None); Assert.True(bodyEncoder.IsTiny(10)); Assert.True(bodyEncoder.IsTiny(63)); Assert.False(bodyEncoder.IsTiny(64)); codeBuilder.WriteBytes(1, 61); var l1 = il.DefineLabel(); il.MarkLabel(l1); Assert.Equal(61, branchBuilder.Labels.Single()); il.Branch(ILOpCode.Br, l1); var brInfo = branchBuilder.Branches.Single(); Assert.Equal(61, brInfo.ILOffset); Assert.Equal(l1, brInfo.Label); Assert.Equal((byte)ILOpCode.Br_s, brInfo.ShortOpCode); AssertEx.Equal(new byte[] { 1, (byte)ILOpCode.Br_s, unchecked((byte)-1) }, codeBuilder.ToArray(60, 3)); int bodyOffset; bodyEncoder.WriteInstructions(codeBuilder, branchBuilder, out bodyOffset); var bodyBytes = bodyBuilder.ToArray(); AssertEx.Equal(new byte[] { 0xFE, // tiny header 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x2B, 0xFE }, bodyBytes); fixed (byte* bodyPtr = &bodyBytes[0]) { var body = MethodBodyBlock.Create(new BlobReader(bodyPtr, bodyBytes.Length)); Assert.Equal(0, body.ExceptionRegions.Length); Assert.Equal(default(StandaloneSignatureHandle), body.LocalSignature); Assert.Equal(8, body.MaxStack); Assert.Equal(bodyBytes.Length, body.Size); var ilBytes = body.GetILBytes(); AssertEx.Equal(new byte[] { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x2B, 0xFE }, ilBytes); } }
public void BranchErrors() { var codeBuilder = new BlobBuilder(); var il = new InstructionEncoder(codeBuilder); Assert.Throws<InvalidOperationException>(() => il.DefineLabel()); il = new InstructionEncoder(codeBuilder, new BranchBuilder()); il.DefineLabel(); il.DefineLabel(); var l2 = il.DefineLabel(); var branchBuilder = new BranchBuilder(); il = new InstructionEncoder(codeBuilder, branchBuilder); var l0 = il.DefineLabel(); Assert.Throws<ArgumentException>(() => il.Branch(ILOpCode.Nop, l0)); Assert.Throws<ArgumentNullException>(() => il.Branch(ILOpCode.Br, default(LabelHandle))); Assert.Throws<ArgumentException>(() => il.Branch(ILOpCode.Br, l2)); }
public void BranchErrors_UnmarkedLabel() { var streamBuilder = new BlobBuilder(); var codeBuilder = new BlobBuilder(); var flowBuilder = new ControlFlowBuilder(); var il = new InstructionEncoder(codeBuilder, flowBuilder); var l = il.DefineLabel(); il.Branch(ILOpCode.Br_s, l); il.OpCode(ILOpCode.Ret); Assert.Throws<InvalidOperationException>(() => new MethodBodyStreamEncoder(streamBuilder).AddMethodBody(il)); }
public unsafe void FatBody() { var streamBuilder = new BlobBuilder(); var codeBuilder = new BlobBuilder(); var flowBuilder = new ControlFlowBuilder(); var il = new InstructionEncoder(codeBuilder, flowBuilder); codeBuilder.WriteBytes(1, 62); var l1 = il.DefineLabel(); il.MarkLabel(l1); Assert.Equal(62, flowBuilder.Labels.Single()); il.Branch(ILOpCode.Br_s, l1); var brInfo = flowBuilder.Branches.Single(); Assert.Equal(62, brInfo.ILOffset); Assert.Equal(l1, brInfo.Label); Assert.Equal(ILOpCode.Br_s, brInfo.OpCode); AssertEx.Equal(new byte[] { 1, 1, (byte)ILOpCode.Br_s, unchecked((byte)-1) }, codeBuilder.ToArray(60, 4)); var streamEncoder = new MethodBodyStreamEncoder(streamBuilder); int bodyOffset = streamEncoder.AddMethodBody( il, maxStack: 2, localVariablesSignature: default(StandaloneSignatureHandle), attributes: MethodBodyAttributes.None); var bodyBytes = streamBuilder.ToArray(); AssertEx.Equal(new byte[] { 0x03, 0x30, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // fat header 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x2B, 0xFE }, bodyBytes); fixed (byte* bodyPtr = &bodyBytes[0]) { var body = MethodBodyBlock.Create(new BlobReader(bodyPtr, bodyBytes.Length)); Assert.Equal(0, body.ExceptionRegions.Length); Assert.Equal(default(StandaloneSignatureHandle), body.LocalSignature); Assert.Equal(2, body.MaxStack); Assert.Equal(bodyBytes.Length, body.Size); var ilBytes = body.GetILBytes(); AssertEx.Equal(new byte[] { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x2B, 0xFE }, ilBytes); } }
public void MarkLabel() { var code = new BlobBuilder(); var il = new InstructionEncoder(code, new ControlFlowBuilder()); var l = il.DefineLabel(); il.Branch(ILOpCode.Br_s, l); il.MarkLabel(l); il.OpCode(ILOpCode.Nop); il.OpCode(ILOpCode.Nop); il.MarkLabel(l); il.OpCode(ILOpCode.Ret); var builder = new BlobBuilder(); new MethodBodyStreamEncoder(builder).AddMethodBody(il); AssertEx.Equal(new byte[] { 0x16, // header (byte)ILOpCode.Br_s, 0x02, (byte)ILOpCode.Nop, (byte)ILOpCode.Nop, (byte)ILOpCode.Ret, }, builder.ToArray()); }
public void Branch() { var builder = new BlobBuilder(); var il = new InstructionEncoder(builder, new ControlFlowBuilder()); var l = il.DefineLabel(); il.Branch(ILOpCode.Br_s, l); il.Branch(ILOpCode.Brfalse_s, l); il.Branch(ILOpCode.Brtrue_s, l); il.Branch(ILOpCode.Beq_s, l); il.Branch(ILOpCode.Bge_s, l); il.Branch(ILOpCode.Bgt_s, l); il.Branch(ILOpCode.Ble_s, l); il.Branch(ILOpCode.Blt_s, l); il.Branch(ILOpCode.Bne_un_s, l); il.Branch(ILOpCode.Bge_un_s, l); il.Branch(ILOpCode.Bgt_un_s, l); il.Branch(ILOpCode.Ble_un_s, l); il.Branch(ILOpCode.Blt_un_s, l); il.Branch(ILOpCode.Leave_s, l); il.Branch(ILOpCode.Br, l); il.Branch(ILOpCode.Brfalse, l); il.Branch(ILOpCode.Brtrue, l); il.Branch(ILOpCode.Beq, l); il.Branch(ILOpCode.Bge, l); il.Branch(ILOpCode.Bgt, l); il.Branch(ILOpCode.Ble, l); il.Branch(ILOpCode.Blt, l); il.Branch(ILOpCode.Bne_un, l); il.Branch(ILOpCode.Bge_un, l); il.Branch(ILOpCode.Bgt_un, l); il.Branch(ILOpCode.Ble_un, l); il.Branch(ILOpCode.Blt_un, l); il.Branch(ILOpCode.Leave, l); AssertEx.Equal(new byte[] { (byte)ILOpCode.Br_s, 0xff, (byte)ILOpCode.Brfalse_s, 0xff, (byte)ILOpCode.Brtrue_s, 0xff, (byte)ILOpCode.Beq_s, 0xff, (byte)ILOpCode.Bge_s, 0xff, (byte)ILOpCode.Bgt_s, 0xff, (byte)ILOpCode.Ble_s, 0xff, (byte)ILOpCode.Blt_s, 0xff, (byte)ILOpCode.Bne_un_s, 0xff, (byte)ILOpCode.Bge_un_s, 0xff, (byte)ILOpCode.Bgt_un_s, 0xff, (byte)ILOpCode.Ble_un_s, 0xff, (byte)ILOpCode.Blt_un_s, 0xff, (byte)ILOpCode.Leave_s, 0xff, (byte)ILOpCode.Br, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Brfalse, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Brtrue, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Beq, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Bge, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Bgt, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Ble, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Blt, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Bne_un, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Bge_un, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Bgt_un, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Ble_un, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Blt_un, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Leave, 0xff, 0xff, 0xff, 0xff, }, builder.ToArray()); }
public void Branch() { var builder = new BlobBuilder(); var il = new InstructionEncoder(builder, new ControlFlowBuilder()); var l = il.DefineLabel(); il.Branch(ILOpCode.Br_s, l); il.Branch(ILOpCode.Brfalse_s, l); il.Branch(ILOpCode.Brtrue_s, l); il.Branch(ILOpCode.Beq_s, l); il.Branch(ILOpCode.Bge_s, l); il.Branch(ILOpCode.Bgt_s, l); il.Branch(ILOpCode.Ble_s, l); il.Branch(ILOpCode.Blt_s, l); il.Branch(ILOpCode.Bne_un_s, l); il.Branch(ILOpCode.Bge_un_s, l); il.Branch(ILOpCode.Bgt_un_s, l); il.Branch(ILOpCode.Ble_un_s, l); il.Branch(ILOpCode.Blt_un_s, l); il.Branch(ILOpCode.Leave_s, l); il.Branch(ILOpCode.Br, l); il.Branch(ILOpCode.Brfalse, l); il.Branch(ILOpCode.Brtrue, l); il.Branch(ILOpCode.Beq, l); il.Branch(ILOpCode.Bge, l); il.Branch(ILOpCode.Bgt, l); il.Branch(ILOpCode.Ble, l); il.Branch(ILOpCode.Blt, l); il.Branch(ILOpCode.Bne_un, l); il.Branch(ILOpCode.Bge_un, l); il.Branch(ILOpCode.Bgt_un, l); il.Branch(ILOpCode.Ble_un, l); il.Branch(ILOpCode.Blt_un, l); il.Branch(ILOpCode.Leave, l); AssertEx.Equal(new byte[] { (byte)ILOpCode.Br_s, 0xff, (byte)ILOpCode.Brfalse_s, 0xff, (byte)ILOpCode.Brtrue_s, 0xff, (byte)ILOpCode.Beq_s, 0xff, (byte)ILOpCode.Bge_s, 0xff, (byte)ILOpCode.Bgt_s, 0xff, (byte)ILOpCode.Ble_s, 0xff, (byte)ILOpCode.Blt_s, 0xff, (byte)ILOpCode.Bne_un_s, 0xff, (byte)ILOpCode.Bge_un_s, 0xff, (byte)ILOpCode.Bgt_un_s, 0xff, (byte)ILOpCode.Ble_un_s, 0xff, (byte)ILOpCode.Blt_un_s, 0xff, (byte)ILOpCode.Leave_s, 0xff, (byte)ILOpCode.Br, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Brfalse, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Brtrue, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Beq, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Bge, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Bgt, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Ble, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Blt, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Bne_un, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Bge_un, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Bgt_un, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Ble_un, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Blt_un, 0xff, 0xff, 0xff, 0xff, (byte)ILOpCode.Leave, 0xff, 0xff, 0xff, 0xff, }, builder.ToArray()); }
public unsafe void TinyBody() { var bodyBuilder = new BlobBuilder(); var codeBuilder = new BlobBuilder(); var branchBuilder = new BranchBuilder(); var il = new InstructionEncoder(codeBuilder, branchBuilder); var bodyEncoder = new MethodBodyEncoder( bodyBuilder, maxStack: 2, exceptionRegionCount: 0, localVariablesSignature: default(StandaloneSignatureHandle), attributes: MethodBodyAttributes.None); Assert.True(bodyEncoder.IsTiny(10)); Assert.True(bodyEncoder.IsTiny(63)); Assert.False(bodyEncoder.IsTiny(64)); codeBuilder.WriteBytes(1, 61); var l1 = il.DefineLabel(); il.MarkLabel(l1); Assert.Equal(61, branchBuilder.Labels.Single()); il.Branch(ILOpCode.Br, l1); var brInfo = branchBuilder.Branches.Single(); Assert.Equal(61, brInfo.ILOffset); Assert.Equal(l1, brInfo.Label); Assert.Equal((byte)ILOpCode.Br_s, brInfo.ShortOpCode); AssertEx.Equal(new byte[] { 1, (byte)ILOpCode.Br_s, unchecked ((byte)-1) }, codeBuilder.ToArray(60, 3)); int bodyOffset; bodyEncoder.WriteInstructions(codeBuilder, branchBuilder, out bodyOffset); var bodyBytes = bodyBuilder.ToArray(); AssertEx.Equal(new byte[] { 0xFE, // tiny header 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x2B, 0xFE }, bodyBytes); fixed(byte *bodyPtr = &bodyBytes[0]) { var body = MethodBodyBlock.Create(new BlobReader(bodyPtr, bodyBytes.Length)); Assert.Equal(0, body.ExceptionRegions.Length); Assert.Equal(default(StandaloneSignatureHandle), body.LocalSignature); Assert.Equal(8, body.MaxStack); Assert.Equal(bodyBytes.Length, body.Size); var ilBytes = body.GetILBytes(); AssertEx.Equal(new byte[] { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x2B, 0xFE }, ilBytes); } }