Beispiel #1
0
        public void AddRegion_Errors3()
        {
            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);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l2);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l3);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l4);

            var streamBuilder = new BlobBuilder();
            var encoder       = new MethodBodyStreamEncoder(streamBuilder);

            flow.AddFaultRegion(l1, l2, l4, l3);
            Assert.Throws <InvalidOperationException>(() => encoder.AddMethodBody(il));
        }
            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());
            }
Beispiel #3
0
        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 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());
        }
Beispiel #6
0
        public void AddRegion_Errors1()
        {
            var code = new BlobBuilder();
            var flow = new ControlFlowBuilder();
            var il   = new InstructionEncoder(code, flow);
            var ilx  = new InstructionEncoder(code, new ControlFlowBuilder());

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

            ilx.DefineLabel();
            ilx.DefineLabel();
            ilx.DefineLabel();
            ilx.DefineLabel();
            ilx.DefineLabel();
            ilx.DefineLabel();
            var lx = ilx.DefineLabel();

            il.MarkLabel(l1);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l2);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l3);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l4);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l5);

            Assert.Throws <ArgumentException>(() => flow.AddCatchRegion(l1, l2, l3, l4, default(TypeDefinitionHandle)));
            Assert.Throws <ArgumentException>(() => flow.AddCatchRegion(l1, l2, l3, l4, MetadataTokens.MethodDefinitionHandle(1)));

            Assert.Throws <ArgumentNullException>(() => flow.AddCatchRegion(default(LabelHandle), l2, l3, l4, MetadataTokens.TypeReferenceHandle(1)));
            Assert.Throws <ArgumentNullException>(() => flow.AddCatchRegion(l1, default(LabelHandle), l3, l4, MetadataTokens.TypeReferenceHandle(1)));
            Assert.Throws <ArgumentNullException>(() => flow.AddCatchRegion(l1, l2, default(LabelHandle), l4, MetadataTokens.TypeReferenceHandle(1)));
            Assert.Throws <ArgumentNullException>(() => flow.AddCatchRegion(l1, l2, l3, default(LabelHandle), MetadataTokens.TypeReferenceHandle(1)));

            Assert.Throws <ArgumentException>(() => flow.AddCatchRegion(lx, l2, l3, l4, MetadataTokens.TypeReferenceHandle(1)));
            Assert.Throws <ArgumentException>(() => flow.AddCatchRegion(l1, lx, l3, l4, MetadataTokens.TypeReferenceHandle(1)));
            Assert.Throws <ArgumentException>(() => flow.AddCatchRegion(l1, l2, lx, l4, MetadataTokens.TypeReferenceHandle(1)));
            Assert.Throws <ArgumentException>(() => flow.AddCatchRegion(l1, l2, l3, lx, MetadataTokens.TypeReferenceHandle(1)));
        }
Beispiel #7
0
        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));
        }
Beispiel #8
0
        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));
        }
Beispiel #9
0
        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));
        }
Beispiel #11
0
        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 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);
            }
        }
Beispiel #13
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);
        }
        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 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 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);
            }
        }
        public void AddCatchRegions()
        {
            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.AddCatchRegion(l1, l2, l3, l4, MetadataTokens.TypeDefinitionHandle(1));
            flow.AddCatchRegion(l1, l2, l3, l4, MetadataTokens.TypeSpecificationHandle(2));
            flow.AddCatchRegion(l1, l2, l3, l4, MetadataTokens.TypeReferenceHandle(3));

            var builder = new BlobBuilder();
            flow.SerializeExceptionTable(builder);

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

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

                0x00, 0x00,                // kind
                0x00, 0x00,                // try offset
                0x01,                      // try length
                0x03, 0x00,                // handler offset
                0x03,                      // handler length
                                           
                0x03, 0x00, 0x00, 0x01,    // catch type or filter offset
            }, 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());
        }
Beispiel #20
0
        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);
            }
        }
Beispiel #21
0
        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 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());
        }
        public void AddRegion_Errors1()
        {
            var code = new BlobBuilder();
            var flow = new ControlFlowBuilder();
            var il = new InstructionEncoder(code, flow);
            var ilx = new InstructionEncoder(code, new ControlFlowBuilder());

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

            ilx.DefineLabel();
            ilx.DefineLabel();
            ilx.DefineLabel();
            ilx.DefineLabel();
            ilx.DefineLabel();
            ilx.DefineLabel();
            var lx = ilx.DefineLabel();

            il.MarkLabel(l1);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l2);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l3);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l4);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l5);

            Assert.Throws<ArgumentException>(() => flow.AddCatchRegion(l1, l2, l3, l4, default(TypeDefinitionHandle)));
            Assert.Throws<ArgumentException>(() => flow.AddCatchRegion(l1, l2, l3, l4, MetadataTokens.MethodDefinitionHandle(1)));
            
            Assert.Throws<ArgumentNullException>(() => flow.AddCatchRegion(default(LabelHandle), l2, l3, l4, MetadataTokens.TypeReferenceHandle(1)));
            Assert.Throws<ArgumentNullException>(() => flow.AddCatchRegion(l1, default(LabelHandle), l3, l4, MetadataTokens.TypeReferenceHandle(1)));
            Assert.Throws<ArgumentNullException>(() => flow.AddCatchRegion(l1, l2, default(LabelHandle), l4, MetadataTokens.TypeReferenceHandle(1)));
            Assert.Throws<ArgumentNullException>(() => flow.AddCatchRegion(l1, l2, l3, default(LabelHandle), MetadataTokens.TypeReferenceHandle(1)));

            Assert.Throws<ArgumentException>(() => flow.AddCatchRegion(lx, l2, l3, l4, MetadataTokens.TypeReferenceHandle(1)));
            Assert.Throws<ArgumentException>(() => flow.AddCatchRegion(l1, lx, l3, l4, MetadataTokens.TypeReferenceHandle(1)));
            Assert.Throws<ArgumentException>(() => flow.AddCatchRegion(l1, l2, lx, l4, MetadataTokens.TypeReferenceHandle(1)));
            Assert.Throws<ArgumentException>(() => flow.AddCatchRegion(l1, l2, l3, lx, MetadataTokens.TypeReferenceHandle(1)));
        }
Beispiel #25
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());
        }
        public void AddRegion_Errors3()
        {
            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);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l2);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l3);
            il.OpCode(ILOpCode.Nop);
            il.MarkLabel(l4);

            var streamBuilder = new BlobBuilder();
            var encoder = new MethodBodyStreamEncoder(streamBuilder);

            flow.AddFaultRegion(l1, l2, l4, l3);
            Assert.Throws<InvalidOperationException>(() => encoder.AddMethodBody(il));
        }
Beispiel #27
0
        public void AddCatchRegions()
        {
            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.AddCatchRegion(l1, l2, l3, l4, MetadataTokens.TypeDefinitionHandle(1));
            flow.AddCatchRegion(l1, l2, l3, l4, MetadataTokens.TypeSpecificationHandle(2));
            flow.AddCatchRegion(l1, l2, l3, l4, MetadataTokens.TypeReferenceHandle(3));

            var builder = new BlobBuilder();

            flow.SerializeExceptionTable(builder);

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

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

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

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

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

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

                0x03, 0x00, 0x00, 0x01,    // catch type or filter offset
            }, builder.ToArray());
        }
Beispiel #28
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();
                        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;
        }