public void AddMethodBody_Reserved_Tiny1()
        {
            var streamBuilder = new BlobBuilder(32);
            var encoder = new MethodBodyStreamEncoder(streamBuilder);

            streamBuilder.WriteBytes(0x01, 3);

            var body = encoder.AddMethodBody(10);
            Assert.Equal(3, body.Offset);
         
            var segment = body.Instructions.GetBytes();
            Assert.Equal(4, segment.Offset); // +1 byte for the header
            Assert.Equal(10, segment.Count);

            Assert.Null(body.ExceptionRegions.Builder);

            new BlobWriter(body.Instructions).WriteBytes(0x02, 10);

            AssertEx.Equal(new byte[] 
            {
                0x01, 0x01, 0x01,
                0x2A, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02
            }, streamBuilder.ToArray());
        }
        public void AddMethodBody_Reserved_Tiny_AttributesIgnored()
        {
            var streamBuilder = new BlobBuilder();
            var encoder = new MethodBodyStreamEncoder(streamBuilder);

            var body = encoder.AddMethodBody(10, attributes: MethodBodyAttributes.None);
            new BlobWriter(body.Instructions).WriteBytes(0x02, 10);

            AssertEx.Equal(new byte[]
            {
                0x2A, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02
            }, streamBuilder.ToArray());
        }
        public void AddMethodBody_Reserved_Exceptions_Fat1()
        {
            var streamBuilder = new BlobBuilder(32);
            var encoder = new MethodBodyStreamEncoder(streamBuilder);

            streamBuilder.WriteBytes(0x01, 3);

            var body = encoder.AddMethodBody(10, exceptionRegionCount: 699050);
            Assert.Equal(4, body.Offset); // 4B aligned

            var segment = body.Instructions.GetBytes();
            Assert.Equal(16, segment.Offset); // +12 byte for the header
            Assert.Equal(10, segment.Count);

            Assert.Same(streamBuilder, body.ExceptionRegions.Builder);

            new BlobWriter(body.Instructions).WriteBytes(0x02, 10);

            AssertEx.Equal(new byte[]
            {
                0x01, 0x01, 0x01,
                0x00, // padding
                0x1B, 0x30, // flags
                0x08, 0x00, // max stack
                0x0A, 0x00, 0x00, 0x00, // code size
                0x00, 0x00, 0x00, 0x00, // local sig
                0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,

                // exception table

                0x00, 0x00,      // padding
                0x41,            // kind
                0xF4, 0xFF, 0xFF // size fo the table
            }, streamBuilder.ToArray());
        }
        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 AddMethodBody_Reserved_Fat1()
        {
            var streamBuilder = new BlobBuilder(32);
            var encoder = new MethodBodyStreamEncoder(streamBuilder);

            streamBuilder.WriteBytes(0x01, 3);

            var body = encoder.AddMethodBody(10, maxStack: 9);
            Assert.Equal(4, body.Offset); // 4B aligned

            var segment = body.Instructions.GetBytes();
            Assert.Equal(16, segment.Offset); // +12 byte for the header
            Assert.Equal(10, segment.Count);

            Assert.Null(body.ExceptionRegions.Builder);

            new BlobWriter(body.Instructions).WriteBytes(0x02, 10);

            AssertEx.Equal(new byte[] 
            {
                0x01, 0x01, 0x01,
                0x00, // padding
                0x13, 0x30,
                0x09, 0x00, // max stack
                0x0A, 0x00, 0x00, 0x00, // code size
                0x00, 0x00, 0x00, 0x00, // local sig
                0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 
            }, streamBuilder.ToArray());
        }
        public void AddMethodBody_Reserved_Fat2()
        {
            var streamBuilder = new BlobBuilder(32);
            var encoder = new MethodBodyStreamEncoder(streamBuilder);

            streamBuilder.WriteBytes(0x01, 3);

            var body = encoder.AddMethodBody(10, localVariablesSignature: MetadataTokens.StandaloneSignatureHandle(0xABCDEF));
            Assert.Equal(4, body.Offset); // 4B aligned

            var segment = body.Instructions.GetBytes();
            Assert.Equal(16, segment.Offset); // +12 byte for the header
            Assert.Equal(10, segment.Count);

            Assert.Null(body.ExceptionRegions.Builder);

            new BlobWriter(body.Instructions).WriteBytes(0x02, 10);

            AssertEx.Equal(new byte[]
            {
                0x01, 0x01, 0x01,
                0x00, // padding
                0x13, 0x30,
                0x08, 0x00, // max stack
                0x0A, 0x00, 0x00, 0x00, // code size
                0xEF, 0xCD, 0xAB, 0x11, // local sig
                0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02
            }, streamBuilder.ToArray());
        }
示例#7
0
        public void Branch_LongInstruction_LongDistance()
        {
            var code = new BlobBuilder();
            var flow = new ControlFlowBuilder();
            var il   = new InstructionEncoder(code, flow);

            var l1 = il.DefineLabel();

            il.Branch(ILOpCode.Br, l1);

            for (int i = 0; i < 256 / 5 + 1; i++)
            {
                il.Call(MetadataTokens.MethodDefinitionHandle(1));
            }

            il.MarkLabel(l1);
            il.OpCode(ILOpCode.Ret);

            var builder = new BlobBuilder();
            var encoder = new MethodBodyStreamEncoder(builder).AddMethodBody(il);

            AssertEx.Equal(new byte[]
            {
                0x13, 0x30, 0x08, 0x00, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// header
                (byte)ILOpCode.Br, 0x04, 0x01, 0x00, 0x00,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Call, 0x01, 0x00, 0x00, 0x06,
                (byte)ILOpCode.Ret
            }, builder.ToArray());
        }
        public void AddMethodBody_Reserved_Tiny_Empty()
        {
            var streamBuilder = new BlobBuilder();
            var encoder = new MethodBodyStreamEncoder(streamBuilder);

            var body = encoder.AddMethodBody(0);
            Assert.Equal(0, body.Offset);

            var segment = body.Instructions.GetBytes();
            Assert.Equal(1, segment.Offset); // +1 byte for the header
            Assert.Equal(0, segment.Count);

            Assert.Null(body.ExceptionRegions.Builder);

            AssertEx.Equal(new byte[]
            {
                0x02
            }, streamBuilder.ToArray());
        }
示例#9
0
        private static MethodDefinitionHandle ComplexEmit(MetadataBuilder metadata, BlobBuilder ilBuilder, out Blob mvidFixup)
        {
            var mvid = metadata.ReserveGuid();

            mvidFixup = mvid.Content;

            metadata.AddModule(
                0,
                metadata.GetOrAddString("ConsoleApplication.exe"),
                mvid.Handle,
                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));

            // TypeRefs:

            var systemObjectTypeRef              = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Object"));
            var dictionaryTypeRef                = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System.Collections.Generic"), metadata.GetOrAddString("Dictionary`2"));
            var strignBuilderTypeRef             = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System.Text"), metadata.GetOrAddString("StringBuilder"));
            var typeTypeRef                      = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Type"));
            var int32TypeRef                     = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Int32"));
            var runtimeTypeHandleRef             = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("RuntimeTypeHandle"));
            var invalidOperationExceptionTypeRef = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("InvalidOperationException"));

            // TypeDefs:

            metadata.AddTypeDefinition(
                default(TypeAttributes),
                default(StringHandle),
                metadata.GetOrAddString("<Module>"),
                baseType: default(EntityHandle),
                fieldList: MetadataTokens.FieldDefinitionHandle(1),
                methodList: MetadataTokens.MethodDefinitionHandle(1));

            var baseClassTypeDef = metadata.AddTypeDefinition(
                TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit | TypeAttributes.Abstract,
                metadata.GetOrAddString("Lib"),
                metadata.GetOrAddString("BaseClass"),
                systemObjectTypeRef,
                fieldList: MetadataTokens.FieldDefinitionHandle(1),
                methodList: MetadataTokens.MethodDefinitionHandle(1));

            var derivedClassTypeDef = metadata.AddTypeDefinition(
                TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit,
                metadata.GetOrAddString("Lib"),
                metadata.GetOrAddString("DerivedClass"),
                baseClassTypeDef,
                fieldList: MetadataTokens.FieldDefinitionHandle(4),
                methodList: MetadataTokens.MethodDefinitionHandle(1));

            // FieldDefs:

            // Field1
            var baseClassNumberFieldDef = metadata.AddFieldDefinition(
                FieldAttributes.Private,
                metadata.GetOrAddString("_number"),
                metadata.GetOrAddBlob(BuildSignature(e => e.FieldSignature().Int32())));

            // Field2
            var baseClassNegativeFieldDef = metadata.AddFieldDefinition(
                FieldAttributes.Assembly,
                metadata.GetOrAddString("negative"),
                metadata.GetOrAddBlob(BuildSignature(e => e.FieldSignature().Boolean())));

            // Field3
            var derivedClassSumCacheFieldDef = metadata.AddFieldDefinition(
                FieldAttributes.Assembly,
                metadata.GetOrAddString("_sumCache"),
                metadata.GetOrAddBlob(BuildSignature(e =>
            {
                var inst = e.FieldSignature().GenericInstantiation(genericType: dictionaryTypeRef, genericArgumentCount: 2, isValueType: false);
                inst.AddArgument().Int32();
                inst.AddArgument().Object();
            })));

            // Field4
            var derivedClassCountFieldDef = metadata.AddFieldDefinition(
                FieldAttributes.Assembly,
                metadata.GetOrAddString("_count"),
                metadata.GetOrAddBlob(BuildSignature(e => e.FieldSignature().SZArray().Int32())));

            // Field5
            var derivedClassBCFieldDef = metadata.AddFieldDefinition(
                FieldAttributes.Assembly,
                metadata.GetOrAddString("_bc"),
                metadata.GetOrAddBlob(BuildSignature(e => e.FieldSignature().Type(type: baseClassTypeDef, isValueType: false))));

            var methodBodyStream = new MethodBodyStreamEncoder(ilBuilder);

            var buffer = new BlobBuilder();
            var il     = new InstructionEncoder(buffer);

            //
            // Foo
            //
            il.LoadString(metadata.GetOrAddUserString("asdsad"));
            il.OpCode(ILOpCode.Newobj);
            il.Token(invalidOperationExceptionTypeRef);
            il.OpCode(ILOpCode.Throw);

            int fooBodyOffset = methodBodyStream.AddMethodBody(il);

            // Method1
            var derivedClassFooMethodDef = metadata.AddMethodDefinition(
                MethodAttributes.PrivateScope | MethodAttributes.Private | MethodAttributes.HideBySig,
                MethodImplAttributes.IL,
                metadata.GetOrAddString("Foo"),
                metadata.GetOrAddBlob(BuildSignature(e =>
                                                     e.MethodSignature(isInstanceMethod: true).Parameters(0, returnType => returnType.Void(), parameters => { }))),
                fooBodyOffset,
                default(ParameterHandle));

            return(default(MethodDefinitionHandle));
        }
示例#10
0
        private static MethodDefinitionHandle BasicValidationEmit(MetadataBuilder metadata, BlobBuilder ilBuilder)
        {
            metadata.AddModule(
                0,
                metadata.GetOrAddString("ConsoleApplication.exe"),
                metadata.GetOrAddGuid(s_guid),
                default(GuidHandle),
                default(GuidHandle));

            metadata.AddAssembly(
                metadata.GetOrAddString("ConsoleApplication"),
                version: new Version(1, 0, 0, 0),
                culture: default(StringHandle),
                publicKey: metadata.GetOrAddBlob(ImmutableArray.Create(Misc.KeyPair_PublicKey)),
                flags: AssemblyFlags.PublicKey,
                hashAlgorithm: AssemblyHashAlgorithm.Sha1);

            var mscorlibAssemblyRef = metadata.AddAssemblyReference(
                name: metadata.GetOrAddString("mscorlib"),
                version: new Version(4, 0, 0, 0),
                culture: default(StringHandle),
                publicKeyOrToken: metadata.GetOrAddBlob(ImmutableArray.Create <byte>(0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89)),
                flags: default(AssemblyFlags),
                hashValue: default(BlobHandle));

            var systemObjectTypeRef = metadata.AddTypeReference(
                mscorlibAssemblyRef,
                metadata.GetOrAddString("System"),
                metadata.GetOrAddString("Object"));

            var systemConsoleTypeRefHandle = metadata.AddTypeReference(
                mscorlibAssemblyRef,
                metadata.GetOrAddString("System"),
                metadata.GetOrAddString("Console"));

            var consoleWriteLineSignature = new BlobBuilder();

            new BlobEncoder(consoleWriteLineSignature).
            MethodSignature().
            Parameters(1,
                       returnType => returnType.Void(),
                       parameters => parameters.AddParameter().Type().String());

            var consoleWriteLineMemberRef = metadata.AddMemberReference(
                systemConsoleTypeRefHandle,
                metadata.GetOrAddString("WriteLine"),
                metadata.GetOrAddBlob(consoleWriteLineSignature));

            var parameterlessCtorSignature = new BlobBuilder();

            new BlobEncoder(parameterlessCtorSignature).
            MethodSignature(isInstanceMethod: true).
            Parameters(0, returnType => returnType.Void(), parameters => { });

            var parameterlessCtorBlobIndex = metadata.GetOrAddBlob(parameterlessCtorSignature);

            var objectCtorMemberRef = metadata.AddMemberReference(
                systemObjectTypeRef,
                metadata.GetOrAddString(".ctor"),
                parameterlessCtorBlobIndex);

            var mainSignature = new BlobBuilder();

            new BlobEncoder(mainSignature).
            MethodSignature().
            Parameters(0, returnType => returnType.Void(), parameters => { });

            var methodBodyStream = new MethodBodyStreamEncoder(ilBuilder);

            var codeBuilder = new BlobBuilder();
            InstructionEncoder il;

            //
            // Program::.ctor
            //
            il = new InstructionEncoder(codeBuilder);

            // ldarg.0
            il.LoadArgument(0);

            // call instance void [mscorlib]System.Object::.ctor()
            il.Call(objectCtorMemberRef);

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

            int ctorBodyOffset = methodBodyStream.AddMethodBody(il);

            codeBuilder.Clear();

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

            il = new InstructionEncoder(codeBuilder, flowBuilder);

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

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

            // .try
            il.MarkLabel(tryStart);

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

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

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

            // .finally
            il.MarkLabel(finallyStart);

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

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

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

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

            int mainBodyOffset = methodBodyStream.AddMethodBody(il);

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

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

            var ctorDef = metadata.AddMethodDefinition(
                MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
                MethodImplAttributes.IL | MethodImplAttributes.Managed,
                metadata.GetOrAddString(".ctor"),
                parameterlessCtorBlobIndex,
                ctorBodyOffset,
                parameterList: default(ParameterHandle));

            metadata.AddTypeDefinition(
                default(TypeAttributes),
                default(StringHandle),
                metadata.GetOrAddString("<Module>"),
                baseType: default(EntityHandle),
                fieldList: MetadataTokens.FieldDefinitionHandle(1),
                methodList: mainMethodDef);

            metadata.AddTypeDefinition(
                TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit,
                metadata.GetOrAddString("ConsoleApplication"),
                metadata.GetOrAddString("Program"),
                systemObjectTypeRef,
                fieldList: MetadataTokens.FieldDefinitionHandle(1),
                methodList: mainMethodDef);

            return(mainMethodDef);
        }
示例#11
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));
        }
        private static MethodDefinitionHandle EmitHelloWorld(MetadataBuilder metadata, BlobBuilder ilBuilder)
        {
            // Create module and assembly for a console application.

            metadata.AddModule(
                0,
                metadata.GetOrAddString("ConsoleApplication.dll"),
                metadata.GetOrAddGuid(s_guid),
                default(GuidHandle),
                default(GuidHandle));

            metadata.AddAssembly(
                metadata.GetOrAddString("ConsoleApplication"),
                version: new Version(1, 0, 0, 0),
                culture: default(StringHandle),
                publicKey: default(BlobHandle),
                flags: 0,
                hashAlgorithm: AssemblyHashAlgorithm.None);

            // Create references to System.Object and System.Console types.

            AssemblyReferenceHandle mscorlibAssemblyRef = metadata.AddAssemblyReference(
                name: metadata.GetOrAddString("System.Runtime"),
                version: new Version(4, 2, 2, 0), //.NET Core 3.1
                culture: default(StringHandle),
                publicKeyOrToken: metadata.GetOrAddBlob(
                    new byte[] { 0xB0, 0x3F, 0x5F, 0x7F, 0x11, 0xD5, 0x0A, 0x3A }
                    ),
                flags: default(AssemblyFlags),
                hashValue: default(BlobHandle));

            AssemblyReferenceHandle consoleAssemblyRef = metadata.AddAssemblyReference(
                name: metadata.GetOrAddString("System.Console"),
                version: new Version(4, 1, 2, 0),
                culture: default(StringHandle),
                publicKeyOrToken: metadata.GetOrAddBlob(
                    new byte[] { 0xB0, 0x3F, 0x5F, 0x7F, 0x11, 0xD5, 0x0A, 0x3A }
                    ),
                flags: default(AssemblyFlags),
                hashValue: default(BlobHandle));

            TypeReferenceHandle systemObjectTypeRef = metadata.AddTypeReference(
                mscorlibAssemblyRef,
                metadata.GetOrAddString("System"),
                metadata.GetOrAddString("Object"));

            TypeReferenceHandle systemConsoleTypeRefHandle = metadata.AddTypeReference(
                consoleAssemblyRef,
                metadata.GetOrAddString("System"),
                metadata.GetOrAddString("Console"));

            // Get reference to Console.WriteLine(string) method.

            var consoleWriteLineSignature = new BlobBuilder();

            new BlobEncoder(consoleWriteLineSignature).
            MethodSignature().
            Parameters(1,
                       returnType => returnType.Void(),
                       parameters => parameters.AddParameter().Type().String());

            MemberReferenceHandle consoleWriteLineMemberRef = metadata.AddMemberReference(
                systemConsoleTypeRefHandle,
                metadata.GetOrAddString("WriteLine"),
                metadata.GetOrAddBlob(consoleWriteLineSignature));

            // Get reference to Object's constructor.

            var parameterlessCtorSignature = new BlobBuilder();

            new BlobEncoder(parameterlessCtorSignature).
            MethodSignature(isInstanceMethod: true).
            Parameters(0, returnType => returnType.Void(), parameters => { });

            BlobHandle parameterlessCtorBlobIndex = metadata.GetOrAddBlob(parameterlessCtorSignature);

            MemberReferenceHandle objectCtorMemberRef = metadata.AddMemberReference(
                systemObjectTypeRef,
                metadata.GetOrAddString(".ctor"),
                parameterlessCtorBlobIndex);

            // Create signature for "void Main()" method.

            var mainSignature = new BlobBuilder();

            new BlobEncoder(mainSignature).
            MethodSignature().
            Parameters(0, returnType => returnType.Void(), parameters => { });

            var methodBodyStream = new MethodBodyStreamEncoder(ilBuilder);

            var codeBuilder = new BlobBuilder();
            InstructionEncoder il;

            // Emit IL for Program::.ctor

            il = new InstructionEncoder(codeBuilder);

            // ldarg.0
            il.LoadArgument(0);

            // call instance void [mscorlib]System.Object::.ctor()
            il.Call(objectCtorMemberRef);

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

            int ctorBodyOffset = methodBodyStream.AddMethodBody(il);

            codeBuilder.Clear();

            // Emit IL for Program::Main

            var flowBuilder = new ControlFlowBuilder();

            il = new InstructionEncoder(codeBuilder, flowBuilder);

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

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

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

            int mainBodyOffset = methodBodyStream.AddMethodBody(il);

            codeBuilder.Clear();

            // Create method definition for Program::Main

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

            // Create method definition for Program::.ctor

            MethodDefinitionHandle ctorDef = metadata.AddMethodDefinition(
                MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
                MethodImplAttributes.IL,
                metadata.GetOrAddString(".ctor"),
                parameterlessCtorBlobIndex,
                ctorBodyOffset,
                parameterList: default(ParameterHandle));

            // Create type definition for the special <Module> type that holds global functions

            metadata.AddTypeDefinition(
                default(TypeAttributes),
                default(StringHandle),
                metadata.GetOrAddString("<Module>"),
                baseType: default(EntityHandle),
                fieldList: MetadataTokens.FieldDefinitionHandle(1),
                methodList: mainMethodDef);

            // Create type definition for ConsoleApplication.Program

            metadata.AddTypeDefinition(
                TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit,
                metadata.GetOrAddString("ConsoleApplication"),
                metadata.GetOrAddString("Program"),
                baseType: systemObjectTypeRef,
                fieldList: MetadataTokens.FieldDefinitionHandle(1),
                methodList: mainMethodDef);

            return(mainMethodDef);
        }
        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);
            }
        }