Exemplo n.º 1
0
        private static MethodDefinitionHandle ComplexEmit(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));

            // 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(isValueType: false, typeRefDefSpec: dictionaryTypeRef, genericArgumentCount: 2);
                    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().TypeDefOrRefOrSpec(isValueType: false, typeRefDefSpec: baseClassTypeDef))));

            var methodBodies = new MethodBodiesEncoder(ilBuilder);

            var buffer = new BlobBuilder();
            InstructionEncoder il;

            //
            // Foo
            //
            int fooBodyOffset;
            il = new InstructionEncoder(buffer);

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

            methodBodies.AddMethodBody().WriteInstructions(buffer, out fooBodyOffset);
            buffer.Clear();

            // 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);
        }
        public void FieldRva()
        {
            var mdBuilder = new MetadataBuilder();

            mdBuilder.SetCapacity(TableIndex.Field, 0x10000);
            mdBuilder.SetCapacity(TableIndex.FieldRva, 0x10000);

            for (int i = 0; i < 0x10000; i++)
            {
                var f = mdBuilder.AddFieldDefinition(0, default(StringHandle), default(BlobHandle));
                mdBuilder.AddFieldRelativeVirtualAddress(f, 0);
            }

            mdBuilder.AddModule(0, default(StringHandle), default(GuidHandle), default(GuidHandle), default(GuidHandle));

            var rootBuilder = new MetadataRootBuilder(mdBuilder);
            var mdBlob = new BlobBuilder();
            rootBuilder.Serialize(mdBlob, 0, 0);

            // validate sizes table rows that reference guids:
            using (var mdProvider = MetadataReaderProvider.FromMetadataImage(mdBlob.ToImmutableArray()))
            {
                const int LARGE = 4;

                var mdReader = mdProvider.GetMetadataReader();

                Assert.Equal(2 + 3 * 2 + 2, mdReader.ModuleTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.TypeRefTable.RowSize);
                Assert.Equal(4 + 2 + 2 + 2 + LARGE + 2, mdReader.TypeDefTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.FieldTable.RowSize);
                Assert.Equal(8 + 2 + 2 + 2, mdReader.MethodDefTable.RowSize);
                Assert.Equal(4 + 2, mdReader.ParamTable.RowSize);
                Assert.Equal(2 + 2, mdReader.InterfaceImplTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.MemberRefTable.RowSize);
                Assert.Equal(2 + LARGE + 2, mdReader.ConstantTable.RowSize);
                Assert.Equal(LARGE + 2 + 2, mdReader.CustomAttributeTable.RowSize);
                Assert.Equal(LARGE + 2, mdReader.FieldMarshalTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.DeclSecurityTable.RowSize);
                Assert.Equal(6 + 2, mdReader.ClassLayoutTable.RowSize);
                Assert.Equal(4 + LARGE, mdReader.FieldLayoutTable.RowSize);
                Assert.Equal(2, mdReader.StandAloneSigTable.RowSize);
                Assert.Equal(2 + 2, mdReader.EventMapTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.EventTable.RowSize);
                Assert.Equal(2 + 2, mdReader.PropertyMapTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.PropertyTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.MethodSemanticsTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.MethodImplTable.RowSize);
                Assert.Equal(2, mdReader.ModuleRefTable.RowSize);
                Assert.Equal(2, mdReader.TypeSpecTable.RowSize);
                Assert.Equal(2 + LARGE + 2 + 2, mdReader.ImplMapTable.RowSize);
                Assert.Equal(4 + LARGE, mdReader.FieldRvaTable.RowSize);
                Assert.Equal(16 + 2 + 2 + 2, mdReader.AssemblyTable.RowSize);
                Assert.Equal(12 + 2 + 2 + 2 + 2, mdReader.AssemblyRefTable.RowSize);
                Assert.Equal(4 + 2 + 2, mdReader.FileTable.RowSize);
                Assert.Equal(8 + 2 + 2 + 2, mdReader.ExportedTypeTable.RowSize);
                Assert.Equal(8 + 2 + 2, mdReader.ManifestResourceTable.RowSize);
                Assert.Equal(2 + 2, mdReader.NestedClassTable.RowSize);
                Assert.Equal(4 + 2 + 2, mdReader.GenericParamTable.RowSize);
                Assert.Equal(2 + 2, mdReader.MethodSpecTable.RowSize);
                Assert.Equal(2 + 2, mdReader.GenericParamConstraintTable.RowSize);
                Assert.Equal(2 + 2 + 2 + 2, mdReader.DocumentTable.RowSize);
                Assert.Equal(2 + 2, mdReader.MethodDebugInformationTable.RowSize);
                Assert.Equal(2 + 2 + 2 + 2 + 4 + 4, mdReader.LocalScopeTable.RowSize);
                Assert.Equal(2 + 2 + 2, mdReader.LocalVariableTable.RowSize);
                Assert.Equal(2 + 2, mdReader.LocalConstantTable.RowSize);
                Assert.Equal(2 + 2, mdReader.ImportScopeTable.RowSize);
                Assert.Equal(2 + 2, mdReader.StateMachineMethodTable.RowSize);
                Assert.Equal(LARGE + 2 + 2, mdReader.CustomDebugInformationTable.RowSize);
            }
        }
        public void Add()
        {
            var builder = new MetadataBuilder();

            builder.AddModule(default(Int32), default(StringHandle), default(GuidHandle), default(GuidHandle), default(GuidHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.Module]);

            builder.AddAssembly(default(StringHandle), default(Version), default(StringHandle), default(BlobHandle), default(AssemblyFlags), default(AssemblyHashAlgorithm));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.Assembly]);

            var assemblyReference = builder.AddAssemblyReference(default(StringHandle), default(Version), default(StringHandle), default(BlobHandle), default(AssemblyFlags), default(BlobHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.AssemblyRef]);
            Assert.Equal(1, MetadataTokens.GetRowNumber(assemblyReference));

            var typeDefinition = builder.AddTypeDefinition(default(TypeAttributes), default(StringHandle), default(StringHandle), default(EntityHandle), default(FieldDefinitionHandle), default(MethodDefinitionHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.TypeDef]);
            Assert.Equal(1, MetadataTokens.GetRowNumber(typeDefinition));

            builder.AddTypeLayout(default(TypeDefinitionHandle), default(UInt16), default(UInt32));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.ClassLayout]);

            builder.AddInterfaceImplementation(MetadataTokens.TypeDefinitionHandle(1), MetadataTokens.TypeDefinitionHandle(1));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.InterfaceImpl]);

            builder.AddNestedType(default(TypeDefinitionHandle), default(TypeDefinitionHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.NestedClass]);

            var typeReference = builder.AddTypeReference(EntityHandle.ModuleDefinition, default(StringHandle), default(StringHandle));
            Assert.Equal(1, MetadataTokens.GetRowNumber(typeReference));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.TypeRef]);

            builder.AddTypeSpecification(default(BlobHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.TypeSpec]);

            builder.AddStandaloneSignature(default(BlobHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.StandAloneSig]);

            builder.AddProperty(default(PropertyAttributes), default(StringHandle), default(BlobHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.Property]);

            builder.AddPropertyMap(default(TypeDefinitionHandle), default(PropertyDefinitionHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.PropertyMap]);

            builder.AddEvent(default(EventAttributes), default(StringHandle), MetadataTokens.TypeDefinitionHandle(1));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.Event]);

            builder.AddEventMap(default(TypeDefinitionHandle), default(EventDefinitionHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.EventMap]);

            builder.AddConstant(MetadataTokens.FieldDefinitionHandle(1), default(Object));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.Constant]);

            builder.AddMethodSemantics(MetadataTokens.EventDefinitionHandle(1), default(UInt16), default(MethodDefinitionHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.MethodSemantics]);

            builder.AddCustomAttribute(MetadataTokens.TypeDefinitionHandle(1), MetadataTokens.MethodDefinitionHandle(1), default(BlobHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.CustomAttribute]);

            builder.AddMethodSpecification(MetadataTokens.MethodDefinitionHandle(1), default(BlobHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.MethodSpec]);

            builder.AddModuleReference(default(StringHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.ModuleRef]);

            builder.AddParameter(default(ParameterAttributes), default(StringHandle), default(Int32));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.Param]);

            var genericParameter = builder.AddGenericParameter(MetadataTokens.MethodDefinitionHandle(1), default(GenericParameterAttributes), default(StringHandle), default(Int32));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.GenericParam]);
            Assert.Equal(1, MetadataTokens.GetRowNumber(genericParameter));

            builder.AddGenericParameterConstraint(default(GenericParameterHandle), MetadataTokens.TypeDefinitionHandle(1));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.GenericParamConstraint]);

            builder.AddFieldDefinition(default(FieldAttributes), default(StringHandle), default(BlobHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.Field]);

            builder.AddFieldLayout(default(FieldDefinitionHandle), default(Int32));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.FieldLayout]);

            builder.AddMarshallingDescriptor(MetadataTokens.FieldDefinitionHandle(1), default(BlobHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.FieldMarshal]);

            builder.AddFieldRelativeVirtualAddress(default(FieldDefinitionHandle), default(Int32));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.FieldRva]);

            var methodDefinition = builder.AddMethodDefinition(default(MethodAttributes), default(MethodImplAttributes), default(StringHandle), default(BlobHandle), default(Int32), default(ParameterHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.MethodDef]);
            Assert.Equal(1, MetadataTokens.GetRowNumber(methodDefinition));

            builder.AddMethodImport(MetadataTokens.MethodDefinitionHandle(1), default(MethodImportAttributes), default(StringHandle), default(ModuleReferenceHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.ImplMap]);

            builder.AddMethodImplementation(default(TypeDefinitionHandle), MetadataTokens.MethodDefinitionHandle(1), MetadataTokens.MethodDefinitionHandle(1));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.MethodImpl]);

            var memberReference = builder.AddMemberReference(MetadataTokens.TypeDefinitionHandle(1), default(StringHandle), default(BlobHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.MemberRef]);
            Assert.Equal(1, MetadataTokens.GetRowNumber(memberReference));

            builder.AddManifestResource(default(ManifestResourceAttributes), default(StringHandle), MetadataTokens.AssemblyFileHandle(1), default(Int64));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.ManifestResource]);

            builder.AddAssemblyFile(default(StringHandle), default(BlobHandle), default(Boolean));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.File]);

            builder.AddExportedType(default(TypeAttributes), default(StringHandle), default(StringHandle), MetadataTokens.AssemblyFileHandle(1), default(Int32));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.ExportedType]);

            builder.AddDeclarativeSecurityAttribute(MetadataTokens.TypeDefinitionHandle(1), default(DeclarativeSecurityAction), default(BlobHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.DeclSecurity]);

            builder.AddEncLogEntry(MetadataTokens.TypeDefinitionHandle(1), default(EditAndContinueOperation));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.EncLog]);

            builder.AddEncMapEntry(MetadataTokens.TypeDefinitionHandle(1));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.EncMap]);

            var document = builder.AddDocument(default(BlobHandle), default(GuidHandle), default(BlobHandle), default(GuidHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.Document]);
            Assert.Equal(1, MetadataTokens.GetRowNumber(document));

            builder.AddMethodDebugInformation(default(DocumentHandle), default(BlobHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.MethodDebugInformation]);

            var localScope = builder.AddLocalScope(default(MethodDefinitionHandle), default(ImportScopeHandle), default(LocalVariableHandle), default(LocalConstantHandle), default(Int32), default(Int32));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.LocalScope]);
            Assert.Equal(1, MetadataTokens.GetRowNumber(localScope));

            var localVariable = builder.AddLocalVariable(default(LocalVariableAttributes), default(Int32), default(StringHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.LocalVariable]);
            Assert.Equal(1, MetadataTokens.GetRowNumber(localVariable));

            var localConstant = builder.AddLocalConstant(default(StringHandle), default(BlobHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.LocalConstant]);
            Assert.Equal(1, MetadataTokens.GetRowNumber(localConstant));

            var importScope = builder.AddImportScope(default(ImportScopeHandle), default(BlobHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.ImportScope]);
            Assert.Equal(1, MetadataTokens.GetRowNumber(importScope));

            builder.AddStateMachineMethod(default(MethodDefinitionHandle), default(MethodDefinitionHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.StateMachineMethod]);

            builder.AddCustomDebugInformation(default(EntityHandle), default(GuidHandle), default(BlobHandle));
            Assert.Equal(1, builder.GetRowCounts()[(int)TableIndex.CustomDebugInformation]);
        }