public void TokenInstructions() { var builder = new BlobBuilder(); var il = new InstructionEncoder(builder); Assert.Equal(0, il.Offset); il.Token(MetadataTokens.TypeDefinitionHandle(0x123456)); Assert.Equal(4, il.Offset); il.Token(0x7F7E7D7C); Assert.Equal(8, il.Offset); il.LoadString(MetadataTokens.UserStringHandle(0x010203)); Assert.Equal(13, il.Offset); il.Call(MetadataTokens.MethodDefinitionHandle(0xA0A1A2)); Assert.Equal(18, il.Offset); il.Call(MetadataTokens.MethodSpecificationHandle(0xB0B1B2)); Assert.Equal(23, il.Offset); il.Call(MetadataTokens.MemberReferenceHandle(0xC0C1C2)); Assert.Equal(28, il.Offset); il.Call((EntityHandle)MetadataTokens.MethodDefinitionHandle(0xD0D1D2)); Assert.Equal(33, il.Offset); il.Call((EntityHandle)MetadataTokens.MethodSpecificationHandle(0xE0E1E2)); Assert.Equal(38, il.Offset); il.Call((EntityHandle)MetadataTokens.MemberReferenceHandle(0xF0F1F2)); Assert.Equal(43, il.Offset); il.CallIndirect(MetadataTokens.StandaloneSignatureHandle(0x001122)); Assert.Equal(48, il.Offset); AssertEx.Equal(new byte[] { 0x56, 0x34, 0x12, 0x02, 0x7C, 0x7D, 0x7E, 0x7F, (byte)ILOpCode.Ldstr, 0x03, 0x02, 0x01, 0x70, (byte)ILOpCode.Call, 0xA2, 0xA1, 0xA0, 0x06, (byte)ILOpCode.Call, 0xB2, 0xB1, 0xB0, 0x2B, (byte)ILOpCode.Call, 0xC2, 0xC1, 0xC0, 0x0A, (byte)ILOpCode.Call, 0xD2, 0xD1, 0xD0, 0x06, (byte)ILOpCode.Call, 0xE2, 0xE1, 0xE0, 0x2B, (byte)ILOpCode.Call, 0xF2, 0xF1, 0xF0, 0x0A, (byte)ILOpCode.Calli, 0x22, 0x11, 0x00, 0x11 }, builder.ToArray()); }
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 TokenInstructions() { var builder = new BlobBuilder(); var il = new InstructionEncoder(builder); Assert.Equal(0, il.Offset); il.Token(MetadataTokens.TypeDefinitionHandle(0x123456)); Assert.Equal(4, il.Offset); il.Token(0x7F7E7D7C); Assert.Equal(8, il.Offset); il.LoadString(MetadataTokens.UserStringHandle(0x010203)); Assert.Equal(13, il.Offset); il.Call(MetadataTokens.MethodDefinitionHandle(0xA0A1A2)); Assert.Equal(18, il.Offset); il.Call(MetadataTokens.MethodSpecificationHandle(0xB0B1B2)); Assert.Equal(23, il.Offset); il.Call(MetadataTokens.MemberReferenceHandle(0xC0C1C2)); Assert.Equal(28, il.Offset); il.Call((EntityHandle)MetadataTokens.MethodDefinitionHandle(0xD0D1D2)); Assert.Equal(33, il.Offset); il.Call((EntityHandle)MetadataTokens.MethodSpecificationHandle(0xE0E1E2)); Assert.Equal(38, il.Offset); il.Call((EntityHandle)MetadataTokens.MemberReferenceHandle(0xF0F1F2)); Assert.Equal(43, il.Offset); il.CallIndirect(MetadataTokens.StandaloneSignatureHandle(0x001122)); Assert.Equal(48, il.Offset); AssertEx.Equal(new byte[] { 0x56, 0x34, 0x12, 0x02, 0x7C, 0x7D, 0x7E, 0x7F, (byte)ILOpCode.Ldstr, 0x03, 0x02, 0x01, 0x70, (byte)ILOpCode.Call, 0xA2, 0xA1, 0xA0, 0x06, (byte)ILOpCode.Call, 0xB2, 0xB1, 0xB0, 0x2B, (byte)ILOpCode.Call, 0xC2, 0xC1, 0xC0, 0x0A, (byte)ILOpCode.Call, 0xD2, 0xD1, 0xD0, 0x06, (byte)ILOpCode.Call, 0xE2, 0xE1, 0xE0, 0x2B, (byte)ILOpCode.Call, 0xF2, 0xF1, 0xF0, 0x0A, (byte)ILOpCode.Calli, 0x22, 0x11, 0x00, 0x11 }, builder.ToArray()); }
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()); 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); }
private static MethodDefinitionHandle EmitMethod(string assemblyName, MetadataBuilder metadata, BlobBuilder ilBuilder, string name, Func <MetadataBuilder, BlobBuilder> signatureCallback, string[] paramNames) { BlobBuilder methodSignature = signatureCallback(metadata); // Create module and assembly metadata.AddModule( 0, metadata.GetOrAddString(assemblyName + ".dll"), metadata.GetOrAddGuid(s_guid), default(GuidHandle), default(GuidHandle)); metadata.AddAssembly( metadata.GetOrAddString(assemblyName), version: new Version(1, 0, 0, 0), culture: default(StringHandle), publicKey: default(BlobHandle), flags: 0, hashAlgorithm: AssemblyHashAlgorithm.None); // Create references to System.Object and System.Console types. AssemblyReferenceHandle mscorlibAssemblyRef = metadata.AddAssemblyReference( name: metadata.GetOrAddString("System.Runtime"), version: new Version(4, 0, 0, 0), culture: default(StringHandle), publicKeyOrToken: default(BlobHandle), flags: default(AssemblyFlags), hashValue: default(BlobHandle)); TypeReferenceHandle systemObjectTypeRef = metadata.AddTypeReference( mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Object")); // Get reference to Object's constructor. var parameterlessCtorSignature = new BlobBuilder(); new BlobEncoder(parameterlessCtorSignature). MethodSignature(isInstanceMethod: true). Parameters(0, returnType => returnType.Void(), parameters => { }); BlobHandle parameterlessCtorBlobIndex = metadata.GetOrAddBlob(parameterlessCtorSignature); MemberReferenceHandle objectCtorMemberRef = metadata.AddMemberReference( systemObjectTypeRef, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex); var methodBodyStream = new MethodBodyStreamEncoder(ilBuilder); var codeBuilder = new BlobBuilder(); InstructionEncoder il; // Emit IL for Program::.ctor il = new InstructionEncoder(codeBuilder); // ldarg.0 il.LoadArgument(0); // call instance void [mscorlib]System.Object::.ctor() il.Call(objectCtorMemberRef); // ret il.OpCode(ILOpCode.Ret); int ctorBodyOffset = methodBodyStream.AddMethodBody(il); codeBuilder.Clear(); // Emit IL for a method il = new InstructionEncoder(codeBuilder); il.OpCode(ILOpCode.Ldnull); il.OpCode(ILOpCode.Throw); int methodBodyOffset = methodBodyStream.AddMethodBody(il); codeBuilder.Clear(); // Create parameters for a method definition int nextParameterIndex = 1; ParameterHandle pFirst = default(ParameterHandle); for (int i = 0; i < paramNames.Length; i++) { ParameterHandle p = metadata.AddParameter( ParameterAttributes.None, metadata.GetOrAddString(paramNames[i]), i + 1); nextParameterIndex++; if (i == 0) { pFirst = p; } } // Create method definition MethodDefinitionHandle methodDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig, MethodImplAttributes.IL, metadata.GetOrAddString(name), metadata.GetOrAddBlob(methodSignature), methodBodyOffset, parameterList: pFirst); // Create method definition for Program::.ctor MethodDefinitionHandle ctorDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, MethodImplAttributes.IL, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex, ctorBodyOffset, parameterList: MetadataTokens.ParameterHandle(nextParameterIndex)); // Create type definition for the special <Module> type that holds global functions metadata.AddTypeDefinition( default(TypeAttributes), default(StringHandle), metadata.GetOrAddString("<Module>"), baseType: default(EntityHandle), fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: MetadataTokens.MethodDefinitionHandle(1)); // Create type definition for ConsoleApplication.Program metadata.AddTypeDefinition( TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit, metadata.GetOrAddString(assemblyName), metadata.GetOrAddString("Program"), baseType: systemObjectTypeRef, fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: methodDef); return(methodDef); }
private static void EmitHelperLibraryMetadata(string assemblyName, string rootNamespace, MetadataBuilder metadata, BlobBuilder ilBuilder) { // Dynamically get mscorlib assembly information for executing runtime var mscorlibName = typeof(object).GetTypeInfo().Assembly.GetName(); // Create module version identifier var mvid = Guid.NewGuid(); metadata.AddModule( 0, metadata.GetOrAddString($"{assemblyName}.dll"), metadata.GetOrAddGuid(mvid), default(GuidHandle), default(GuidHandle)); metadata.AddAssembly( metadata.GetOrAddString(assemblyName), new Version(1, 0, 0, 0), default(StringHandle), default(BlobHandle), default(AssemblyFlags), AssemblyHashAlgorithm.Sha1); // Add mscorlib assembly reference and related type references var mscorlibRef = metadata.AddAssemblyReference( metadata.GetOrAddString("mscorlib"), mscorlibName.Version, default(StringHandle), metadata.GetOrAddBlob(mscorlibName.GetPublicKeyToken()), default(AssemblyFlags), default(BlobHandle)); var objectTypeRef = metadata.AddTypeReference( mscorlibRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Object")); var consoleTypeRef = metadata.AddTypeReference( mscorlibRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Console")); // Create method signature of System.Console.WriteLine reference var consoleWriteLineSignature = new BlobBuilder(); new BlobEncoder(consoleWriteLineSignature).MethodSignature().Parameters(1, returnType => returnType.Void(), parameters => parameters.AddParameter().Type().String()); var consoleWriteLineMemberRef = metadata.AddMemberReference( consoleTypeRef, metadata.GetOrAddString("WriteLine"), metadata.GetOrAddBlob(consoleWriteLineSignature)); // Create constructor signature for TestClass var parameterlessCtorSignature = new BlobBuilder(); new BlobEncoder(parameterlessCtorSignature).MethodSignature(isInstanceMethod: true) .Parameters(0, returnType => returnType.Void(), parameters => { }); var parameterlessCtorBlobIndex = metadata.GetOrAddBlob(parameterlessCtorSignature); // Create constructor of TestClass var objectCtorMemberRef = metadata.AddMemberReference( objectTypeRef, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex); // Create TestClass.TestMethod signature var testMethodSignature = new BlobBuilder(); new BlobEncoder(testMethodSignature).MethodSignature(isInstanceMethod: true) .Parameters(0, returnType => returnType.Void(), parameters => { }); // Create an IL stream and serialize each methods var methodBodyStream = new MethodBodyStreamEncoder(ilBuilder); var codeBuilder = new BlobBuilder(); InstructionEncoder il; // Create constructor body by composing IL codes // TestClass::.ctor il = new InstructionEncoder(codeBuilder); // ldarg.0 il.LoadArgument(0); // call instance void [mscorlib]System.Object::.ctor() il.Call(objectCtorMemberRef); // ret il.OpCode(ILOpCode.Ret); var ctorBodyOffset = methodBodyStream.AddMethodBody(il); codeBuilder.Clear(); // Create TestClass.TestMethod body by composing IL codes // TestClass::TestMethod il = new InstructionEncoder(codeBuilder); // ldstr "hello" il.LoadString(metadata.GetOrAddUserString("Hello world from serialized assembly!")); // call void [mscorlib]System.Console::WriteLine(string) il.Call(consoleWriteLineMemberRef); // ret il.OpCode(ILOpCode.Ret); var testMethodBodyOffset = methodBodyStream.AddMethodBody(il); // Create TestClass.TestMethod method definition var testMethodDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.HideBySig, MethodImplAttributes.IL | MethodImplAttributes.Managed, metadata.GetOrAddString("TestMethod"), metadata.GetOrAddBlob(testMethodSignature), testMethodBodyOffset, default(ParameterHandle)); // Create TestClass constructor definition var ctorDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, MethodImplAttributes.IL | MethodImplAttributes.Managed, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex, ctorBodyOffset, default(ParameterHandle)); metadata.AddTypeDefinition( default(TypeAttributes), default(StringHandle), metadata.GetOrAddString("<Module>"), default(EntityHandle), MetadataTokens.FieldDefinitionHandle(1), MetadataTokens.MethodDefinitionHandle(1)); metadata.AddTypeDefinition( TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit, metadata.GetOrAddString(rootNamespace), metadata.GetOrAddString("TestClass"), objectTypeRef, MetadataTokens.FieldDefinitionHandle(1), testMethodDef); }
private static MethodDefinitionHandle EmitHelloWorld(MetadataBuilder metadata, BlobBuilder ilBuilder) { // Create module and assembly for a console application. metadata.AddModule( 0, metadata.GetOrAddString("ConsoleApplication.exe"), metadata.GetOrAddGuid(s_guid), default(GuidHandle), default(GuidHandle)); metadata.AddAssembly( metadata.GetOrAddString("ConsoleApplication"), version: new Version(1, 0, 0, 0), culture: default(StringHandle), publicKey: default(BlobHandle), flags: 0, hashAlgorithm: AssemblyHashAlgorithm.None); // Create references to System.Object and System.Console types. AssemblyReferenceHandle mscorlibAssemblyRef = metadata.AddAssemblyReference( name: metadata.GetOrAddString("mscorlib"), version: new Version(4, 0, 0, 0), culture: default(StringHandle), publicKeyOrToken: metadata.GetOrAddBlob( new byte[] { 0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89 } ), flags: default(AssemblyFlags), hashValue: default(BlobHandle)); TypeReferenceHandle systemObjectTypeRef = metadata.AddTypeReference( mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Object")); TypeReferenceHandle systemConsoleTypeRefHandle = metadata.AddTypeReference( mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Console")); // Get reference to Console.WriteLine(string) method. var consoleWriteLineSignature = new BlobBuilder(); new BlobEncoder(consoleWriteLineSignature). MethodSignature(). Parameters(1, returnType => returnType.Void(), parameters => parameters.AddParameter().Type().String()); MemberReferenceHandle consoleWriteLineMemberRef = metadata.AddMemberReference( systemConsoleTypeRefHandle, metadata.GetOrAddString("WriteLine"), metadata.GetOrAddBlob(consoleWriteLineSignature)); // Get reference to Object's constructor. var parameterlessCtorSignature = new BlobBuilder(); new BlobEncoder(parameterlessCtorSignature). MethodSignature(isInstanceMethod: true). Parameters(0, returnType => returnType.Void(), parameters => { }); BlobHandle parameterlessCtorBlobIndex = metadata.GetOrAddBlob(parameterlessCtorSignature); MemberReferenceHandle objectCtorMemberRef = metadata.AddMemberReference( systemObjectTypeRef, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex); // Create signature for "void Main()" method. var mainSignature = new BlobBuilder(); new BlobEncoder(mainSignature). MethodSignature(). Parameters(0, returnType => returnType.Void(), parameters => { }); var methodBodyStream = new MethodBodyStreamEncoder(ilBuilder); var codeBuilder = new BlobBuilder(); InstructionEncoder il; // Emit IL for Program::.ctor il = new InstructionEncoder(codeBuilder); // ldarg.0 il.LoadArgument(0); // call instance void [mscorlib]System.Object::.ctor() il.Call(objectCtorMemberRef); // ret il.OpCode(ILOpCode.Ret); int ctorBodyOffset = methodBodyStream.AddMethodBody(il); codeBuilder.Clear(); // Emit IL for Program::Main var flowBuilder = new ControlFlowBuilder(); il = new InstructionEncoder(codeBuilder, flowBuilder); // ldstr "hello" il.LoadString(metadata.GetOrAddUserString("Hello, world")); // call void [mscorlib]System.Console::WriteLine(string) il.Call(consoleWriteLineMemberRef); // ret il.OpCode(ILOpCode.Ret); int mainBodyOffset = methodBodyStream.AddMethodBody(il); codeBuilder.Clear(); // Create method definition for Program::Main MethodDefinitionHandle mainMethodDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig, MethodImplAttributes.IL, metadata.GetOrAddString("Main"), metadata.GetOrAddBlob(mainSignature), mainBodyOffset, parameterList: default(ParameterHandle)); // Create method definition for Program::.ctor MethodDefinitionHandle ctorDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, MethodImplAttributes.IL, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex, ctorBodyOffset, parameterList: default(ParameterHandle)); // Create type definition for the special <Module> type that holds global functions metadata.AddTypeDefinition( default(TypeAttributes), default(StringHandle), metadata.GetOrAddString("<Module>"), baseType: default(EntityHandle), fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: mainMethodDef); // Create type definition for ConsoleApplication.Program metadata.AddTypeDefinition( TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit, metadata.GetOrAddString("ConsoleApplication"), metadata.GetOrAddString("Program"), baseType: systemObjectTypeRef, fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: mainMethodDef); return(mainMethodDef); }
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; }