コード例 #1
0
        public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaType type)
        {
            TypeDefinition typeDef = type.MetadataReader.GetTypeDefinition(type.Handle);

            AddDependenciesDueToCustomAttributes(ref dependencies, factory, type.EcmaModule, typeDef.GetCustomAttributes());
        }
コード例 #2
0
        private void EmitTypeToken(EcmaType type, SignatureContext context)
        {
            ModuleToken token = context.GetModuleTokenForType(type);

            EmitToken(token.Token);
        }
コード例 #3
0
        public MethodDesc ResolveMethodID(long handle, bool throwIfNotFound = true)
        {
            lock (_lock)
            {
                MethodDescInfo minfo;
                if (_methods.TryGetValue(handle, out minfo))
                {
                    if (minfo.Method != null)
                    {
                        return(minfo.Method);
                    }

                    TypeDesc owningType = ResolveTypeHandle(minfo.MethodDetailsTraceData.TypeID, throwIfNotFound);
                    if (owningType == null)
                    {
                        return(null);
                    }

                    MetadataType owningMDType = owningType as MetadataType;
                    if (owningMDType == null)
                    {
                        throw new Exception("Method not parented by MetadataType");
                    }

                    if ((minfo.MethodDetailsTraceData.MethodToken & 0xFF000000) != 0x06000000)
                    {
                        throw new Exception($"Invalid methoddef {minfo.MethodDetailsTraceData.MethodToken:4x}");
                    }

                    MethodDefinitionHandle methoddef = MetadataTokens.MethodDefinitionHandle(minfo.MethodDetailsTraceData.MethodToken & 0xFFFFFF);

                    MethodDesc uninstantiatedMethod = null;
                    foreach (MethodDesc m in owningMDType.GetMethods())
                    {
                        EcmaMethod ecmaMeth = m.GetTypicalMethodDefinition() as EcmaMethod;
                        if (ecmaMeth == null)
                        {
                            continue;
                        }

                        if (ecmaMeth.Handle == methoddef)
                        {
                            uninstantiatedMethod = m;
                            break;
                        }
                    }

                    if (uninstantiatedMethod == null)
                    {
                        if (throwIfNotFound)
                        {
                            EcmaType ecmaType = owningMDType.GetTypeDefinition() as EcmaType;

                            throw new Exception($"Unknown MethodID value finding MethodDef {minfo.MethodDetailsTraceData.MethodToken:x} on type {owningMDType} from module {ecmaType.Module.Assembly.GetName().Name}");
                        }
                        return(null);
                    }

                    // Instantiate the type if requested
                    if (minfo.MethodDetailsTraceData.TypeParameters.Length != 0)
                    {
                        if (uninstantiatedMethod.Instantiation.Length != minfo.MethodDetailsTraceData.TypeParameters.Length)
                        {
                            throw new Exception($"Invalid TypeParameterCount {minfo.MethodDetailsTraceData.TypeParameters.Length} expected {uninstantiatedMethod.Instantiation.Length} as needed by '{uninstantiatedMethod}'");
                        }

                        TypeDesc[] instantiation = new TypeDesc[minfo.MethodDetailsTraceData.TypeParameters.Length];
                        for (int i = 0; i < instantiation.Length; i++)
                        {
                            instantiation[i] = ResolveTypeHandle((long)minfo.MethodDetailsTraceData.TypeParameters[i], throwIfNotFound);
                            if (instantiation[i] == null)
                            {
                                return(null);
                            }
                        }

                        minfo.Method = _context.GetInstantiatedMethod(uninstantiatedMethod, new Instantiation(instantiation));

                        if (minfo.Method == null)
                        {
                            if (throwIfNotFound)
                            {
                                StringBuilder s = new StringBuilder();
                                foreach (TypeDesc type in instantiation)
                                {
                                    if (s.Length != 0)
                                    {
                                        s.Append(',');
                                    }
                                    s.Append(type);
                                }
                                throw new Exception("Unable to instantiate {uninstantiatedMethod} over <{s}>");
                            }
                            return(null);
                        }
                    }
                    else
                    {
                        minfo.Method = uninstantiatedMethod;
                    }

                    if (minfo.Method == null)
                    {
                        if (throwIfNotFound)
                        {
                            throw new Exception("Unknown MethodID value");
                        }
                        return(null);
                    }

                    return(minfo.Method);
                }
                else
                {
                    if (throwIfNotFound)
                    {
                        throw new Exception("Unknown MethodID value");
                    }
                    return(null);
                }
            }
        }
コード例 #4
0
        public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaType type)
        {
            MetadataReader reader  = type.MetadataReader;
            TypeDefinition typeDef = reader.GetTypeDefinition(type.Handle);

            AddDependenciesDueToCustomAttributes(ref dependencies, factory, type.EcmaModule, typeDef.GetCustomAttributes());

            // Handle custom attributes on generic type parameters
            foreach (GenericParameterHandle genericParameterHandle in typeDef.GetGenericParameters())
            {
                GenericParameter parameter = reader.GetGenericParameter(genericParameterHandle);
                AddDependenciesDueToCustomAttributes(ref dependencies, factory, type.EcmaModule, parameter.GetCustomAttributes());
            }
        }
コード例 #5
0
        /// <summary>
        /// If given <param name="type"/> is an <see cref="EcmaType"/> precompute its mangled type name
        /// along with all the other types from the same module as <param name="type"/>.
        /// Otherwise, it is a constructed type and to the EcmaType's mangled name we add a suffix to
        /// show what kind of constructed type it is (e.g. appending __Array for an array type).
        /// </summary>
        /// <param name="type">Type to mangled</param>
        /// <returns>Mangled name for <param name="type"/>.</returns>
        private string ComputeMangledTypeName(TypeDesc type)
        {
            if (type is EcmaType)
            {
                EcmaType ecmaType = (EcmaType)type;

                string assemblyName    = ((EcmaAssembly)ecmaType.EcmaModule).GetName().Name;
                bool   isSystemPrivate = assemblyName.StartsWith("System.Private.");

                // Abbreviate System.Private to S.P. This might conflict with user defined assembly names,
                // but we already have a problem due to running SanitizeName without disambiguating the result
                // This problem needs a better fix.
                if (isSystemPrivate && !_mangleForCplusPlus)
                {
                    assemblyName = "S.P." + assemblyName.Substring(15);
                }
                string prependAssemblyName = SanitizeName(assemblyName);

                var deduplicator = new HashSet <string>();

                // Add consistent names for all types in the module, independent on the order in which
                // they are compiled
                lock (this)
                {
                    bool isSystemModule = ecmaType.Module == ecmaType.Context.SystemModule;

                    if (!_mangledTypeNames.ContainsKey(type))
                    {
                        foreach (MetadataType t in ecmaType.EcmaModule.GetAllTypes())
                        {
                            string name = t.GetFullName();

                            // Include encapsulating type
                            DefType containingType = t.ContainingType;
                            while (containingType != null)
                            {
                                name           = containingType.GetFullName() + "_" + name;
                                containingType = containingType.ContainingType;
                            }

                            name = SanitizeName(name, true);

                            if (_mangleForCplusPlus)
                            {
                                // Always generate a fully qualified name
                                name = "::" + prependAssemblyName + "::" + name;
                            }
                            else
                            {
                                name = prependAssemblyName + "_" + name;

                                // If this is one of the well known types, use a shorter name
                                // We know this won't conflict because all the other types are
                                // prefixed by the assembly name.
                                if (isSystemModule)
                                {
                                    switch (t.Category)
                                    {
                                    case TypeFlags.Boolean: name = "Bool"; break;

                                    case TypeFlags.Byte: name = "UInt8"; break;

                                    case TypeFlags.SByte: name = "Int8"; break;

                                    case TypeFlags.UInt16: name = "UInt16"; break;

                                    case TypeFlags.Int16: name = "Int16"; break;

                                    case TypeFlags.UInt32: name = "UInt32"; break;

                                    case TypeFlags.Int32: name = "Int32"; break;

                                    case TypeFlags.UInt64: name = "UInt64"; break;

                                    case TypeFlags.Int64: name = "Int64"; break;

                                    case TypeFlags.Char: name = "Char"; break;

                                    case TypeFlags.Double: name = "Double"; break;

                                    case TypeFlags.Single: name = "Single"; break;

                                    case TypeFlags.IntPtr: name = "IntPtr"; break;

                                    case TypeFlags.UIntPtr: name = "UIntPtr"; break;

                                    default:
                                        if (t.IsObject)
                                        {
                                            name = "Object";
                                        }
                                        else if (t.IsString)
                                        {
                                            name = "String";
                                        }
                                        break;
                                    }
                                }
                            }

                            // Ensure that name is unique and update our tables accordingly.
                            name = DisambiguateName(name, deduplicator);
                            deduplicator.Add(name);
                            _mangledTypeNames.Add(t, name);
                        }
                    }
                    return(_mangledTypeNames[type]);
                }
            }

            string mangledName;

            switch (type.Category)
            {
            case TypeFlags.Array:
                mangledName = "__MDArray" +
                              EnterNameScopeSequence +
                              GetMangledTypeName(((ArrayType)type).ElementType) +
                              DelimitNameScopeSequence +
                              ((ArrayType)type).Rank.ToStringInvariant() +
                              ExitNameScopeSequence;
                break;

            case TypeFlags.SzArray:
                mangledName = "__Array" + NestMangledName(GetMangledTypeName(((ArrayType)type).ElementType));
                break;

            case TypeFlags.ByRef:
                mangledName = GetMangledTypeName(((ByRefType)type).ParameterType) + NestMangledName("ByRef");
                break;

            case TypeFlags.Pointer:
                mangledName = GetMangledTypeName(((PointerType)type).ParameterType) + NestMangledName("Pointer");
                break;

            default:
                // Case of a generic type. If `type' is a type definition we use the type name
                // for mangling, otherwise we use the mangling of the type and its generic type
                // parameters, e.g. A <B> becomes A_<___B_>_ in RyuJIT compilation, or A_A___B_V_
                // in C++ compilation.
                var typeDefinition = type.GetTypeDefinition();
                if (typeDefinition != type)
                {
                    mangledName = GetMangledTypeName(typeDefinition);

                    var    inst = type.Instantiation;
                    string mangledInstantiation = "";
                    for (int i = 0; i < inst.Length; i++)
                    {
                        string instArgName = GetMangledTypeName(inst[i]);
                        if (_mangleForCplusPlus)
                        {
                            instArgName = instArgName.Replace("::", "_");
                        }
                        if (i > 0)
                        {
                            mangledInstantiation += "__";
                        }

                        mangledInstantiation += instArgName;
                    }
                    mangledName += NestMangledName(mangledInstantiation);
                }
                else if (type is IPrefixMangledMethod)
                {
                    mangledName = GetPrefixMangledMethodName((IPrefixMangledMethod)type).ToString();
                }
                else if (type is IPrefixMangledType)
                {
                    mangledName = GetPrefixMangledTypeName((IPrefixMangledType)type).ToString();
                }
                else
                {
                    // This is a type definition. Since we didn't fall in the `is EcmaType` case above,
                    // it's likely a compiler-generated type.
                    mangledName = SanitizeName(((DefType)type).GetFullName(), true);

                    // Always generate a fully qualified name
                    if (_mangleForCplusPlus)
                    {
                        mangledName = "::" + mangledName;
                    }
                }
                break;
            }

            lock (this)
            {
                // Ensure that name is unique and update our tables accordingly.
                if (!_mangledTypeNames.ContainsKey(type))
                {
                    _mangledTypeNames.Add(type, mangledName);
                }
            }

            return(mangledName);
        }
コード例 #6
0
        /// <summary>
        /// If given <param name="type"/> is an <see cref="EcmaType"/> precompute its mangled type name
        /// along with all the other types from the same module as <param name="type"/>.
        /// Otherwise, it is a constructed type and to the EcmaType's mangled name we add a suffix to
        /// show what kind of constructed type it is (e.g. appending __Array for an array type).
        /// </summary>
        /// <param name="type">Type to mangled</param>
        /// <returns>Mangled name for <param name="type"/>.</returns>
        private string ComputeMangledTypeName(TypeDesc type)
        {
            if (type is EcmaType)
            {
                EcmaType ecmaType = (EcmaType)type;

                string prependAssemblyName = SanitizeName(((EcmaAssembly)ecmaType.EcmaModule).GetName().Name);

                var deduplicator = new HashSet <string>();

                // Add consistent names for all types in the module, independent on the order in which
                // they are compiled
                lock (this)
                {
                    if (!_mangledTypeNames.ContainsKey(type))
                    {
                        foreach (MetadataType t in ((EcmaType)type).EcmaModule.GetAllTypes())
                        {
                            string name = t.GetFullName();

                            // Include encapsulating type
                            DefType containingType = t.ContainingType;
                            while (containingType != null)
                            {
                                name           = containingType.GetFullName() + "_" + name;
                                containingType = containingType.ContainingType;
                            }

                            name = SanitizeName(name, true);

                            if (_mangleForCplusPlus)
                            {
                                // Always generate a fully qualified name
                                name = "::" + prependAssemblyName + "::" + name;
                            }
                            else
                            {
                                name = prependAssemblyName + "_" + name;
                            }

                            // Ensure that name is unique and update our tables accordingly.
                            name = DisambiguateName(name, deduplicator);
                            deduplicator.Add(name);
                            _mangledTypeNames = _mangledTypeNames.Add(t, name);
                        }
                    }
                }

                return(_mangledTypeNames[type]);
            }

            string mangledName;

            switch (type.Category)
            {
            case TypeFlags.Array:
            case TypeFlags.SzArray:
                mangledName = GetMangledTypeName(((ArrayType)type).ElementType) + "__";

                if (type.IsMdArray)
                {
                    mangledName += NestMangledName("ArrayRank" + ((ArrayType)type).Rank.ToStringInvariant());
                }
                else
                {
                    mangledName += NestMangledName("Array");
                }
                break;

            case TypeFlags.ByRef:
                mangledName = GetMangledTypeName(((ByRefType)type).ParameterType) + NestMangledName("ByRef");
                break;

            case TypeFlags.Pointer:
                mangledName = GetMangledTypeName(((PointerType)type).ParameterType) + NestMangledName("Pointer");
                break;

            default:
                // Case of a generic type. If `type' is a type definition we use the type name
                // for mangling, otherwise we use the mangling of the type and its generic type
                // parameters, e.g. A <B> becomes A_<___B_>_ in RyuJIT compilation, or A_A___B_V_
                // in C++ compilation.
                var typeDefinition = type.GetTypeDefinition();
                if (typeDefinition != type)
                {
                    mangledName = GetMangledTypeName(typeDefinition);

                    var    inst = type.Instantiation;
                    string mangledInstantiation = "";
                    for (int i = 0; i < inst.Length; i++)
                    {
                        string instArgName = GetMangledTypeName(inst[i]);
                        if (_mangleForCplusPlus)
                        {
                            instArgName = instArgName.Replace("::", "_");
                        }
                        if (i > 0)
                        {
                            mangledInstantiation += "__";
                        }

                        mangledInstantiation += instArgName;
                    }
                    mangledName += NestMangledName(mangledInstantiation);
                }
                else
                {
                    mangledName = SanitizeName(((DefType)type).GetFullName(), true);
                }
                break;
            }

            lock (this)
            {
                // Ensure that name is unique and update our tables accordingly.
                if (!_mangledTypeNames.ContainsKey(type))
                {
                    _mangledTypeNames = _mangledTypeNames.Add(type, mangledName);
                }
            }

            return(mangledName);
        }
コード例 #7
0
        // LookupIbcTypeToken and (possibly) find the module associated with it.
        // externalModule may be null if the exact assembly isn't known
        private uint LookupIbcTypeToken(ref EcmaModule externalModule, uint ibcToken, Dictionary <IBCBlobKey, BlobEntry> blobs)
        {
            if (!blobs.TryGetValue(new IBCBlobKey(ibcToken, BlobType.ExternalTypeDef), out BlobEntry externalTypeDefBlob))
            {
                if (_logger.IsVerbose)
                {
                    _logger.Writer.WriteLine($"Ibc TypeToken {ibcToken:x} unable to find external typedef");
                }
                return(Cor.Macros.RidToToken(0, CorTokenType.mdtTypeDef)); // Nil TypeDef token
            }

            var typeEntry = (BlobEntry.ExternalTypeEntry)externalTypeDefBlob;

            string typeNamespace = "";
            string typeName      = Encoding.UTF8.GetString(typeEntry.Name, 0, typeEntry.Name.Length - 1 /* these strings are null terminated */);
            TypeDefinitionHandle enclosingType = default;

            if (!Cor.Macros.IsNilToken(typeEntry.NamespaceToken))
            {
                if (!Cor.Macros.IsNilToken(typeEntry.NestedClassToken))
                {
                    // Do not support typedef with namespace that is nested
                    throw new Exception($"Ibc TypeToken {ibcToken:x} has both Namespace and NestedClass tokens");
                }

                uint nameSpaceToken = typeEntry.NamespaceToken;
                if (Cor.Macros.TypeFromToken(nameSpaceToken) != CorTokenType.ibcExternalNamespace)
                {
                    throw new Exception($"Ibc TypeToken {ibcToken:x} has Namespace tokens that is not a ibcExternalNamespace");
                }


                if (!blobs.TryGetValue(new IBCBlobKey(nameSpaceToken, BlobType.ExternalNamespaceDef), out BlobEntry namespaceEntryBlob))
                {
                    if (_logger.IsVerbose)
                    {
                        _logger.Writer.WriteLine($"Ibc TypeToken {ibcToken:x} unable to find external namespace blob '{nameSpaceToken:x}");
                    }
                    return(Cor.Macros.RidToToken(0, CorTokenType.mdtTypeDef)); // Nil TypeDef token
                }

                var namespaceEntry = (BlobEntry.ExternalNamespaceEntry)namespaceEntryBlob;
                typeNamespace = Encoding.UTF8.GetString(namespaceEntry.Name, 0, namespaceEntry.Name.Length - 1 /* these strings are null terminated */);
            }
            else if (!Cor.Macros.IsNilToken(typeEntry.NestedClassToken))
            {
                uint enclosingTypeTokenValue = LookupIbcTypeToken(ref externalModule, typeEntry.NestedClassToken, blobs);
                if (Cor.Macros.TypeFromToken(enclosingTypeTokenValue) != CorTokenType.mdtTypeDef)
                {
                    throw new Exception($"Ibc TypeToken {ibcToken:x} has NestedClass token which does not resolve to a type definition");
                }

                enclosingType = MetadataTokens.TypeDefinitionHandle((int)Cor.Macros.RidFromToken(enclosingTypeTokenValue));
                if (enclosingType.IsNil && _logger.IsVerbose)
                {
                    _logger.Writer.WriteLine($"Ibc TypeToken {ibcToken:x} has NestedClass token which resolves to a nil token");
                }
            }

            if (enclosingType.IsNil)
            {
                EcmaType foundType = null;
                if (externalModule == null)
                {
                    // Lookup actual module scenario.
                    foreach (ModuleDesc m in _possibleReferenceModules)
                    {
                        if (!(m is EcmaModule))
                        {
                            continue;
                        }

                        foundType = (EcmaType)m.GetType(typeNamespace, typeName, throwIfNotFound: false);
                        if (foundType != null)
                        {
                            externalModule = foundType.EcmaModule;
                            break;
                        }
                    }
                }
                else
                {
                    foundType = (EcmaType)externalModule.GetType(typeNamespace, typeName, throwIfNotFound: false);
                }

                if (foundType == null)
                {
                    if (_logger.IsVerbose)
                    {
                        _logger.Writer.WriteLine($"Ibc TypeToken {ibcToken:x} has type token which resolves to a nil token");
                    }
                    return(Cor.Macros.RidToToken(0, CorTokenType.mdtTypeDef)); // Nil TypeDef token
                }

                return((uint)externalModule.MetadataReader.GetToken(foundType.Handle));
            }
            else
            {
                TypeDefinition         nestedClassDefinition = externalModule.MetadataReader.GetTypeDefinition(enclosingType);
                MetadataStringComparer stringComparer        = externalModule.MetadataReader.StringComparer;
                foreach (TypeDefinitionHandle tdNested in nestedClassDefinition.GetNestedTypes())
                {
                    TypeDefinition candidateClassDefinition = externalModule.MetadataReader.GetTypeDefinition(tdNested);
                    if (stringComparer.Equals(candidateClassDefinition.Name, typeName))
                    {
                        return((uint)externalModule.MetadataReader.GetToken(tdNested));
                    }
                }

                if (_logger.IsVerbose)
                {
                    _logger.Writer.WriteLine($"Ibc TypeToken {ibcToken:x} unable to find nested type '{typeName}' on type '{externalModule.MetadataReader.GetToken(enclosingType):x}'");
                }
                return(Cor.Macros.RidToToken(0, CorTokenType.mdtTypeDef)); // Nil TypeDef token
            }
        }
コード例 #8
0
ファイル: SignatureContext.cs プロジェクト: Maximys/runtime
 public ModuleToken GetModuleTokenForType(EcmaType type, bool throwIfNotFound = true)
 {
     return(Resolver.GetModuleTokenForType(type, allowDynamicallyCreatedReference: true, throwIfNotFound: throwIfNotFound));
 }
コード例 #9
0
        public void VerifyInterfaces()
        {
            TypeDefinition typeDefinition = _module.MetadataReader.GetTypeDefinition(_typeDefinitionHandle);
            EcmaType       type           = (EcmaType)_module.GetType(_typeDefinitionHandle);

            if (type.IsInterface)
            {
                return;
            }

            InterfaceImplementationHandleCollection interfaceHandles = typeDefinition.GetInterfaceImplementations();
            int count = interfaceHandles.Count;

            if (count == 0)
            {
                return;
            }

            // Look for duplicates and prepare distinct list of implemented interfaces to avoid
            // subsequent error duplication
            List <InterfaceMetadataObjects> implementedInterfaces = new List <InterfaceMetadataObjects>();

            foreach (InterfaceImplementationHandle interfaceHandle in interfaceHandles)
            {
                InterfaceImplementation interfaceImplementation = _module.MetadataReader.GetInterfaceImplementation(interfaceHandle);
                TypeDesc interfaceTypeDesc = _module.GetType(interfaceImplementation.Interface) as TypeDesc;
                if (interfaceTypeDesc == null)
                {
                    ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadBadFormat, type);
                }

                InterfaceMetadataObjects imo = new InterfaceMetadataObjects
                {
                    InterfaceType           = interfaceTypeDesc,
                    InterfaceImplementation = interfaceImplementation
                };

                if (!implementedInterfaces.Contains(imo))
                {
                    implementedInterfaces.Add(imo);
                }
                else
                {
                    VerificationError(VerifierError.InterfaceImplHasDuplicate, Format(type), Format(imo.InterfaceType, _module, imo.InterfaceImplementation));
                }
            }

            foreach (InterfaceMetadataObjects implementedInterface in implementedInterfaces)
            {
                if (!type.IsAbstract)
                {
                    // Look for missing method implementation
                    foreach (MethodDesc method in implementedInterface.InterfaceType.GetAllMethods())
                    {
                        if (method.Signature.IsStatic)
                        {
                            continue;
                        }

                        MethodDesc resolvedMethod = type.ResolveInterfaceMethodTarget(method);
                        if (resolvedMethod is null)
                        {
                            VerificationError(VerifierError.InterfaceMethodNotImplemented, Format(type), Format(implementedInterface.InterfaceType, _module, implementedInterface.InterfaceImplementation), Format(method));
                        }
                    }
                }
            }
        }
 public BlockingState(EcmaType type, bool isBlocked)
 {
     Type      = type;
     IsBlocked = isBlocked;
 }