Пример #1
0
        public void AddFinallyFaultFilterRegions()
        {
            var code = new BlobBuilder();
            var flow = new ControlFlowBuilder();
            var il   = new InstructionEncoder(code, flow);

            var l1 = il.DefineLabel();
            var l2 = il.DefineLabel();
            var l3 = il.DefineLabel();
            var l4 = il.DefineLabel();
            var l5 = il.DefineLabel();

            il.MarkLabel(l1);
            Assert.Equal(0, il.Offset);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l2);
            Assert.Equal(1, il.Offset);
            il.OpCode(ILOpCode.Nop);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l3);
            Assert.Equal(3, il.Offset);
            il.OpCode(ILOpCode.Nop);
            il.OpCode(ILOpCode.Nop);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l4);
            Assert.Equal(6, il.Offset);
            il.OpCode(ILOpCode.Nop);
            il.OpCode(ILOpCode.Nop);
            il.OpCode(ILOpCode.Nop);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l5);
            Assert.Equal(10, il.Offset);

            flow.AddFaultRegion(l1, l2, l3, l4);
            flow.AddFinallyRegion(l1, l2, l3, l4);
            flow.AddFilterRegion(l1, l2, l3, l4, l5);

            var builder = new BlobBuilder();

            builder.WriteByte(0xff);
            flow.SerializeExceptionTable(builder);

            AssertEx.Equal(new byte[]
            {
                0xFF, 0x00, 0x00, 0x00,    // padding
                0x01,                      // flag
                (byte)(builder.Count - 4), // size
                0x00, 0x00,                // reserved

                0x04, 0x00,                // kind
                0x00, 0x00,                // try offset
                0x01,                      // try length
                0x03, 0x00,                // handler offset
                0x03,                      // handler length

                0x00, 0x00, 0x00, 0x00,    // catch type or filter offset

                0x02, 0x00,                // kind
                0x00, 0x00,                // try offset
                0x01,                      // try length
                0x03, 0x00,                // handler offset
                0x03,                      // handler length

                0x00, 0x00, 0x00, 0x00,    // catch type or filter offset

                0x01, 0x00,                // kind
                0x00, 0x00,                // try offset
                0x01,                      // try length
                0x03, 0x00,                // handler offset
                0x03,                      // handler length

                0x0A, 0x00, 0x00, 0x00     // catch type or filter offset
            }, builder.ToArray());
        }
Пример #2
0
        private static MethodDefinitionHandle BasicValidationEmit(MetadataBuilder metadata, BlobBuilder ilBuilder)
        {
            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: metadata.GetOrAddBlob(ImmutableArray.Create(Misc.KeyPair_PublicKey)),
                flags: AssemblyFlags.PublicKey,
                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 methodBodyStream = new MethodBodyStreamEncoder(ilBuilder);

            var codeBuilder = new BlobBuilder();
            InstructionEncoder il;

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

            //
            // Program::Main
            //
            var flowBuilder = new ControlFlowBuilder();

            il = new InstructionEncoder(codeBuilder, flowBuilder);

            var tryStart     = il.DefineLabel();
            var tryEnd       = il.DefineLabel();
            var finallyStart = il.DefineLabel();
            var finallyEnd   = il.DefineLabel();

            flowBuilder.AddFinallyRegion(tryStart, tryEnd, finallyStart, finallyEnd);

            // .try
            il.MarkLabel(tryStart);

            //   ldstr "hello"
            il.LoadString(metadata.GetOrAddUserString("hello"));

            //   call void [mscorlib]System.Console::WriteLine(string)
            il.Call(consoleWriteLineMemberRef);

            //   leave.s END
            il.Branch(ILOpCode.Leave_s, finallyEnd);
            il.MarkLabel(tryEnd);

            // .finally
            il.MarkLabel(finallyStart);

            //   ldstr "world"
            il.LoadString(metadata.GetOrAddUserString("world"));

            //   call void [mscorlib]System.Console::WriteLine(string)
            il.Call(consoleWriteLineMemberRef);

            // .endfinally
            il.OpCode(ILOpCode.Endfinally);
            il.MarkLabel(finallyEnd);

            // ret
            il.OpCode(ILOpCode.Ret);

            int mainBodyOffset = methodBodyStream.AddMethodBody(il);

            codeBuilder.Clear();
            flowBuilder.Clear();

            var mainMethodDef = metadata.AddMethodDefinition(
                MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
                MethodImplAttributes.IL | MethodImplAttributes.Managed,
                metadata.GetOrAddString("Main"),
                metadata.GetOrAddBlob(mainSignature),
                mainBodyOffset,
                parameterList: default(ParameterHandle));

            var ctorDef = metadata.AddMethodDefinition(
                MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
                MethodImplAttributes.IL | MethodImplAttributes.Managed,
                metadata.GetOrAddString(".ctor"),
                parameterlessCtorBlobIndex,
                ctorBodyOffset,
                parameterList: 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);
        }
Пример #3
0
        public void AddFinallyFaultFilterRegions()
        {
            var code = new BlobBuilder();
            var flow = new ControlFlowBuilder();
            var il = new InstructionEncoder(code, flow);

            var l1 = il.DefineLabel();
            var l2 = il.DefineLabel();
            var l3 = il.DefineLabel();
            var l4 = il.DefineLabel();
            var l5 = il.DefineLabel();

            il.MarkLabel(l1);
            Assert.Equal(0, il.Offset);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l2);
            Assert.Equal(1, il.Offset);
            il.OpCode(ILOpCode.Nop);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l3);
            Assert.Equal(3, il.Offset);
            il.OpCode(ILOpCode.Nop);
            il.OpCode(ILOpCode.Nop);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l4);
            Assert.Equal(6, il.Offset);
            il.OpCode(ILOpCode.Nop);
            il.OpCode(ILOpCode.Nop);
            il.OpCode(ILOpCode.Nop);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l5);
            Assert.Equal(10, il.Offset);

            flow.AddFaultRegion(l1, l2, l3, l4);
            flow.AddFinallyRegion(l1, l2, l3, l4);
            flow.AddFilterRegion(l1, l2, l3, l4, l5);
            
            var builder = new BlobBuilder();
            builder.WriteByte(0xff);
            flow.SerializeExceptionTable(builder);

            AssertEx.Equal(new byte[] 
            {
                0xFF, 0x00, 0x00, 0x00,    // padding
                0x01,                      // flag
                (byte)(builder.Count - 4), // size
                0x00, 0x00,                // reserved

                0x04, 0x00,                // kind
                0x00, 0x00,                // try offset
                0x01,                      // try length
                0x03, 0x00,                // handler offset
                0x03,                      // handler length
                                           
                0x00, 0x00, 0x00, 0x00,    // catch type or filter offset
                                           
                0x02, 0x00,                // kind
                0x00, 0x00,                // try offset
                0x01,                      // try length
                0x03, 0x00,                // handler offset
                0x03,                      // handler length
                                           
                0x00, 0x00, 0x00, 0x00,    // catch type or filter offset

                0x01, 0x00,                // kind
                0x00, 0x00,                // try offset
                0x01,                      // try length
                0x03, 0x00,                // handler offset
                0x03,                      // handler length
                                           
                0x0A, 0x00, 0x00, 0x00     // catch type or filter offset
            }, builder.ToArray());
        }