Exemplo n.º 1
0
        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());
        }
Exemplo n.º 2
0
        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();
        }
Exemplo n.º 3
0
        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;
        }
Exemplo n.º 4
0
 public InstructionEncoder(BlobBuilder builder, BranchBuilder branchBuilder = null)
 {
     Builder = builder;
     _branchBuilderOpt = branchBuilder;
 }