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 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(); }
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 InstructionEncoder(BlobBuilder builder, BranchBuilder branchBuilder = null) { Builder = builder; _branchBuilderOpt = branchBuilder; }