Example #1
0
        public void TypeOrMethodDef()
        {
            Assert.Equal(0, CodedIndex.TypeOrMethodDef(default(TypeDefinitionHandle)));
            Assert.Equal((0xffffff << 1) | 1, CodedIndex.TypeOrMethodDef(MetadataTokens.MethodDefinitionHandle(0xffffff)));

            Assert.Equal(0x02 | 0, CodedIndex.TypeOrMethodDef(MetadataTokens.TypeDefinitionHandle(1)));
            Assert.Equal(0x02 | 1, CodedIndex.TypeOrMethodDef(MetadataTokens.MethodDefinitionHandle(1)));
        }
Example #2
0
        public void Errors()
        {
            var badHandleKind = CustomAttributeHandle.FromRowId(1);

            AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.HasCustomAttribute(badHandleKind));
            AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.HasConstant(badHandleKind));
            AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.CustomAttributeType(badHandleKind));
            AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.HasDeclSecurity(badHandleKind));
            AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.HasFieldMarshal(badHandleKind));
            AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.HasSemantics(badHandleKind));
            AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.Implementation(badHandleKind));
            AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.MemberForwarded(badHandleKind));
            AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.MemberRefParent(badHandleKind));
            AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.MethodDefOrRef(badHandleKind));
            AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.ResolutionScope(badHandleKind));
            AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.TypeDefOrRef(badHandleKind));
            AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.TypeDefOrRefOrSpec(badHandleKind));
            AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.TypeOrMethodDef(badHandleKind));
            AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.HasCustomDebugInformation(badHandleKind));
        }
Example #3
0
        private void _sortAndWriteGenParamEntries(ref DynamicArray <GenericParameter> entriesList)
        {
            if (entriesList.length == 0)
            {
                return;
            }

            var entries = entriesList.asReadOnlyArrayView();

            var codedIndexKeys = new int[entries.length];

            for (int i = 0; i < entries.length; i++)
            {
                codedIndexKeys[i] = CodedIndex.TypeOrMethodDef(entries[i].ownerHandle);
            }

            Array.Sort(codedIndexKeys, entriesList.getUnderlyingArray(), 0, entriesList.length);

            using var mdBuilder = m_metadataContext.getMetadataBuilder();

            for (int i = 0; i < entries.length; i++)
            {
                ref readonly var genParam   = ref entries[i];
Example #4
0
        private void CreateMethod(MethodInfo method, List <DelayedWrite> genericParams)
        {
            if (!_metadata.TryGetMethodDefinition(method, out var metadata))
            {
                ThrowMetadataIsNotReserved("Method", method);
            }

            EnsureMetadataWasNotEmitted(metadata, method);

            var body = method.GetMethodBody();

            var localVariablesSignature = default(StandaloneSignatureHandle);

            if (body != null && body.LocalVariables.Count > 0)
            {
                localVariablesSignature = _metadata.Builder.AddStandaloneSignature(_metadata.GetOrAddBlob(
                                                                                       MetadataHelper.BuildSignature(x =>
                {
                    x.LocalVariableSignature(body.LocalVariables.Count).AddRange(body.LocalVariables, _metadata);
                })));
            }

            var offset = -1;

            // If body exists, we write it in IL body stream
            if (body != null && !method.IsAbstract)
            {
                var methodBodyWriter = new MethodBodyStreamWriter(_metadata);

                // offset can be aligned during serialization. So, override the correct offset.
                offset = methodBodyWriter.AddMethodBody(method, localVariablesSignature);
            }

            var parameters = CreateParameters(method.GetParameters());

            var handle = _metadata.Builder.AddMethodDefinition(
                method.Attributes,
                method.MethodImplementationFlags,
                _metadata.GetOrAddString(method.Name),
                _metadata.GetMethodOrConstructorSignature(method),
                offset,
                parameters);

            // The generation of interface method overrides has been moved to
            // AssemblyGenerator.DeclareInterfacesAndCreateInterfaceMap in
            // AssemblyGenerator.Types.cs.

            // Add generic parameters
            if (method.IsGenericMethodDefinition)
            {
                int index = 0;
                foreach (var arg in method.GetGenericArguments())
                {
                    genericParams.Add(new DelayedWrite(CodedIndex.TypeOrMethodDef(handle), () =>
                    {
                        // Add the argument
                        var gaHandle = _metadata.Builder.AddGenericParameter(handle, arg.GenericParameterAttributes, _metadata.GetOrAddString(arg.Name), index++);

                        // Add it's constraints
                        foreach (var constraint in arg.GetGenericParameterConstraints())
                        {
                            _metadata.Builder.AddGenericParameterConstraint(gaHandle, _metadata.GetTypeHandle(constraint));
                        }
                    }));
                }
            }
            else if (method.Attributes.HasFlag(MethodAttributes.PinvokeImpl))
            {
                ProcessPInvokeMapData(
                    method,
                    out string libraryName,
                    out string entryName,
                    out MethodImportAttributes attrs);

                var libraryNameHandle = _metadata.GetOrAddString(libraryName);
                var moduleRefHandle   = _metadata.Builder.AddModuleReference(libraryNameHandle);
                var entryNameHandle   = _metadata.GetOrAddString(entryName);

                // Add the ImplMap entry for the P/Invoke
                _metadata.Builder.AddMethodImport(
                    handle,
                    attrs,
                    entryNameHandle,
                    moduleRefHandle);
            }

            VerifyEmittedHandle(metadata, handle);
            metadata.MarkAsEmitted();

            CreateCustomAttributes(handle, method.GetCustomAttributesData());
        }
        private void CreateMethod(MethodInfo method, List <DelayedWrite> genericParams)
        {
            if (!_metadata.TryGetMethodDefinition(method, out var metadata))
            {
                ThrowMetadataIsNotReserved("Method", method);
            }

            EnsureMetadataWasNotEmitted(metadata, method);

            var body = method.GetMethodBody();

            var localVariablesSignature = default(StandaloneSignatureHandle);

            if (body != null && body.LocalVariables.Count > 0)
            {
                localVariablesSignature = _metadata.Builder.AddStandaloneSignature(_metadata.GetOrAddBlob(
                                                                                       MetadataHelper.BuildSignature(x =>
                {
                    x.LocalVariableSignature(body.LocalVariables.Count).AddRange(body.LocalVariables, _metadata);
                })));
            }

            var offset = -1;

            // If body exists, we write it in IL body stream
            if (body != null && !method.IsAbstract)
            {
                var methodBodyWriter = new MethodBodyStreamWriter(_metadata);

                // offset can be aligned during serialization. So, override the correct offset.
                offset = methodBodyWriter.AddMethodBody(method, localVariablesSignature);
            }

            var parameters = CreateParameters(method.GetParameters());

            var handle = _metadata.Builder.AddMethodDefinition(
                method.Attributes,
                method.MethodImplementationFlags,
                _metadata.GetOrAddString(method.Name),
                _metadata.GetMethodOrConstructorSignature(method),
                offset,
                parameters);

            // Explicit interface implementations need to be marked with method implementation
            // (This is the equivalent of .Override in msil)
            if (method.IsPrivate)
            {
                // Go through all the implemented interfaces and all their methods
                // looking for methods that this method implements and mark accordingly.

                // NB: This is not super efficient.  Should probably create a map somewhere
                //     for faster lookup, but this will do for now.

                var type = method.DeclaringType;
                foreach (var itf in type.GetInterfaces())
                {
                    var itfMap = type.GetInterfaceMap(itf);
                    for (int i = 0; i < itfMap.TargetMethods.Length; i++)
                    {
                        var m = itfMap.TargetMethods[i];
                        if (m == method)
                        {
                            var itfImpl = itfMap.InterfaceMethods[i];
                            _metadata.Builder.AddMethodImplementation((TypeDefinitionHandle)_metadata.GetTypeHandle(method.DeclaringType), handle, _metadata.GetMethodHandle(itfImpl));
                        }
                    }
                }
            }

            // Add generic parameters
            if (method.IsGenericMethodDefinition)
            {
                int index = 0;
                foreach (var arg in method.GetGenericArguments())
                {
                    genericParams.Add(new DelayedWrite(CodedIndex.TypeOrMethodDef(handle), () =>
                    {
                        // Add the argument
                        var gaHandle = _metadata.Builder.AddGenericParameter(handle, arg.GenericParameterAttributes, _metadata.GetOrAddString(arg.Name), index++);

                        // Add it's constraints
                        foreach (var constraint in arg.GetGenericParameterConstraints())
                        {
                            _metadata.Builder.AddGenericParameterConstraint(gaHandle, _metadata.GetTypeHandle(constraint));
                        }
                    }));
                }
            }

            VerifyEmittedHandle(metadata, handle);
            metadata.MarkAsEmitted();

            CreateCustomAttributes(handle, method.GetCustomAttributesData());
        }
Example #6
0
        private void CreateType(Type type, List <DelayedWrite> genericParams)
        {
            // Check reserved and not already emitted
            if (!_metadata.TryGetTypeDefinition(type, out var metadata))
            {
                ThrowMetadataIsNotReserved("Type", type);
            }
            EnsureMetadataWasNotEmitted(metadata, type);

            // Add the type definition
            var baseTypeHandle = type.BaseType != null?_metadata.GetTypeHandle(type.BaseType) : default;

            var handle = _metadata.Builder.AddTypeDefinition(
                type.Attributes,
                type.DeclaringType == null ? _metadata.GetOrAddString(ApplyNameChange(type.Namespace)) : default(StringHandle),
                _metadata.GetOrAddString(type.Name),
                baseTypeHandle,
                MetadataTokens.FieldDefinitionHandle(_metadata.Builder.GetRowCount(TableIndex.Field) + 1),
                MetadataTokens.MethodDefinitionHandle(_metadata.Builder.GetRowCount(TableIndex.MethodDef) + 1));

            // Verify and mark emitted
            VerifyEmittedHandle(metadata, handle);
            metadata.MarkAsEmitted();

            // Setup pack and size attributes (if explicit layout)
            if (type.IsExplicitLayout)
            {
                _metadata.Builder.AddTypeLayout(
                    handle,
                    (ushort)type.StructLayoutAttribute.Pack,
                    (uint)type.StructLayoutAttribute.Size
                    );
            }

            // Add implemented interfaces (not for enums though - eg: IComparable etc...)
            if (!type.IsEnum)
            {
                DeclareInterfacesAndCreateInterfaceMap(type, handle);
            }

            // Setup enclosing type
            if (type.DeclaringType != null)
            {
                _metadata.Builder.AddNestedType(handle, (TypeDefinitionHandle)_metadata.GetTypeHandle(type.DeclaringType));
            }

            // Create attributes
            CreateCustomAttributes(handle, type.GetCustomAttributesData());

            // Handle generics type
            if (type.IsGenericType)
            {
                if (type.IsGenericTypeDefinition)
                {
                    var genericType = type.GetGenericTypeDefinition();
                    var typeInfo    = genericType.GetTypeInfo();

                    int index = 0;
                    foreach (var arg in typeInfo.GenericTypeParameters)
                    {
                        var attr = arg.GenericParameterAttributes;

                        genericParams.Add(new DelayedWrite(CodedIndex.TypeOrMethodDef(handle), () =>
                        {
                            var gpHandle = _metadata.Builder.AddGenericParameter(handle, attr, _metadata.GetOrAddString(arg.Name), index++);

                            foreach (var constraint in arg.GetGenericParameterConstraints())
                            {
                                _metadata.Builder.AddGenericParameterConstraint(gpHandle,
                                                                                _metadata.GetTypeHandle(constraint));
                            }
                        }));
                    }
                }
            }

            // Create members...
            CreateFields(type.GetFields(AllFields));
            CreatePropertiesForType(type.GetProperties(AllProperties));
            CreateEventsForType(type.GetEvents(AllEvents));
            CreateConstructors(type.GetConstructors(AllMethods));
            CreateMethods(type.GetMethods(AllMethods), genericParams);
        }
Example #7
0
        public ReservedBlob <GuidHandle> Import()
        {
            if (_reader.IsAssembly)
            {
                var srcAssembly = _reader.GetAssemblyDefinition();

                _builder.AddAssembly(ImportValue(srcAssembly.Name), srcAssembly.Version,
                                     ImportValue(srcAssembly.Culture),
                                     ImportValue(srcAssembly.PublicKey), srcAssembly.Flags, srcAssembly.HashAlgorithm);
                Debug?.Invoke($"Imported assembly {_reader.ToString(srcAssembly)}");
            }

            var srcModule = _reader.GetModuleDefinition();

            var mvidBlob = _builder.ReserveGuid();

            _builder.AddModule(srcModule.Generation, ImportValue(srcModule.Name), mvidBlob.Handle,
                               ImportValue(srcModule.GenerationId),
                               ImportValue(srcModule.BaseGenerationId));
            Debug?.Invoke($"Imported module {_reader.ToString(srcModule)}");

            Debug?.Invoke($"Importing assembly files");
            foreach (var srcHandle in _reader.AssemblyFiles)
            {
                Import(srcHandle);
            }

            var index = 1;

            Debug?.Invoke($"Preparing type list for import");

            var checker = new CachedAttributeChecker();

            foreach (var srcHandle in _reader.TypeDefinitions)
            {
                bool shouldImport;

                var src = _reader.GetTypeDefinition(srcHandle);
                if (checker.HasAttribute(_reader, src, AttributeNames.Embedded) &&
                    checker.HasAttribute(_reader, src, AttributeNames.CompilerGenerated))
                {
                    Trace?.Invoke($"Embedded type found {_reader.ToString(srcHandle)}");
                    shouldImport = true;
                }
                else
                {
                    shouldImport = Filter?.AllowImport(_reader.GetTypeDefinition(srcHandle), _reader) != false;
                }

                if (shouldImport)
                {
                    _typeDefinitionCache[srcHandle] = MetadataTokens.TypeDefinitionHandle(index++);
                }
                else
                {
                    Trace?.Invoke($"Type filtered and will not be imported {_reader.ToString(srcHandle)}");
                }
            }

            Debug?.Invoke($"Importing type definitions");
            foreach (var srcHandle in _reader.TypeDefinitions.Where(_typeDefinitionCache.ContainsKey))
            {
                var dstHandle = ImportTypeDefinitionSkeleton(srcHandle);
                if (dstHandle != _typeDefinitionCache[srcHandle])
                {
                    throw new Exception("WTF: type handle mismatch");
                }
            }

            Debug?.Invoke($"Importing type definition accessories");
            foreach (var(srcHandle, dstHandle) in _typeDefinitionCache)
            {
                ImportTypeDefinitionAccessories(srcHandle, dstHandle);
            }

            Debug?.Invoke($"Importing method definition accessories");
            foreach (var(srcHandle, dstHandle) in _methodDefinitionCache)
            {
                ImportMethodDefinitionAccessories(srcHandle, dstHandle);
            }

            Debug?.Invoke($"Importing field definition accessories");
            foreach (var(srcHandle, dstHandle) in _fieldDefinitionCache)
            {
                ImportFieldDefinitionAccessories(srcHandle, dstHandle);
            }

            Debug?.Invoke($"Importing nested classes");
            var nestedTypes = _typeDefinitionCache
                              .Select(kv => Tuple.Create(kv.Value, _reader.GetTypeDefinition(kv.Key).GetNestedTypes()))
                              .SelectMany(x => x.Item2.Select(y => Tuple.Create(x.Item1, y, Import(y))))
                              .Where(x => !x.Item3.IsNil)
                              .OrderBy(x => RowId(x.Item3))
                              .ToList();

            foreach (var(dstHandle, srcNested, dstNested) in nestedTypes)
            {
                _builder.AddNestedType(dstNested, dstHandle);
                Trace?.Invoke($"Imported nested type {_reader.ToString(srcNested)} -> {RowId(dstNested):X}");
            }


            var generic = _typeDefinitionCache
                          .Select(kv => Tuple.Create((EntityHandle)kv.Value, _reader.GetTypeDefinition(kv.Key).GetGenericParameters()))
                          .Concat(_methodDefinitionCache
                                  .Select(kv => Tuple.Create((EntityHandle)kv.Value, _reader.GetMethodDefinition(kv.Key).GetGenericParameters())))
                          .OrderBy(x => CodedIndex.TypeOrMethodDef(x.Item1))
                          .ToList();

            Debug?.Invoke($"Importing generic constraints");
            foreach (var(dstHandle, genericParams) in generic)
            {
                ImportGenericConstraints(dstHandle, genericParams);
            }

            Debug?.Invoke($"Importing custom attributes");
            foreach (var src in _reader.CustomAttributes)
            {
                Import(src);
            }

            Debug?.Invoke($"Importing declarative security attributes");
            foreach (var src in _reader.DeclarativeSecurityAttributes)
            {
                Import(src);
            }

            Debug?.Invoke($"Importing exported types");
            foreach (var src in _reader.ExportedTypes)
            {
                Import(src);
            }

            Debug?.Invoke($"Importing done");

            return(mvidBlob);
        }