Пример #1
0
            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());
            }
        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,
Пример #3
0
        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());
        }
Пример #4
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());
        }
Пример #5
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));
        }
Пример #6
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));
        }
Пример #7
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));
        }
Пример #8
0
        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));
        }
Пример #9
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;
        }
Пример #10
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));
        }
Пример #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);
            }
        }
Пример #12
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 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);
            }
        }
        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 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 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);
            }
        }
Пример #17
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());
        }
Пример #18
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());
        }
Пример #19
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());
        }
Пример #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);
            }
        }