/// <summary>
        /// From a string, get a pointer to an allocated memory location that holds a NativeFormat encoded string.
        /// This is used for the creation of RuntimeFieldHandles from metadata.
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public IntPtr GetNativeFormatStringForString(string str)
        {
            using (LockHolder.Hold(_typeLoaderLock))
            {
                IntPtr result;
                if (s_nativeFormatStrings.TryGetValue(str, out result))
                {
                    return(result);
                }

                NativePrimitiveEncoder stringEncoder = new NativePrimitiveEncoder();
                stringEncoder.Init();
                byte[] utf8Bytes = Encoding.UTF8.GetBytes(str);
                stringEncoder.WriteUnsigned(checked ((uint)utf8Bytes.Length));
                foreach (byte b in utf8Bytes)
                {
                    stringEncoder.WriteByte(b);
                }

                IntPtr allocatedNativeFormatString = MemoryHelpers.AllocateMemory(stringEncoder.Size);
                unsafe
                {
                    stringEncoder.Save((byte *)allocatedNativeFormatString.ToPointer(), stringEncoder.Size);
                }
                s_nativeFormatStrings.Add(str, allocatedNativeFormatString);
                return(allocatedNativeFormatString);
            }
        }
Example #2
0
            public static char Lookup(string entity)
            {
                char theChar;

                s_lookupTable.TryGetValue(entity, out theChar);
                return(theChar);
            }
Example #3
0
        private bool TryGetCategoryFlagsForPrimitiveType(out TypeFlags categoryFlags)
        {
            categoryFlags = 0;
            if (_module != _metadataUnit.Context.SystemModule)
            {
                // Primitive types reside in the system module
                return(false);
            }
            NamespaceDefinition namespaceDef = MetadataReader.GetNamespaceDefinition(_typeDefinition.NamespaceDefinition);

            if (namespaceDef.ParentScopeOrNamespace.HandleType != HandleType.NamespaceDefinition)
            {
                // Primitive types are in the System namespace the parent of which is the root namespace
                return(false);
            }
            if (!namespaceDef.Name.StringEquals("System", MetadataReader))
            {
                // Namespace name must be 'System'
                return(false);
            }
            NamespaceDefinitionHandle parentNamespaceDefHandle =
                namespaceDef.ParentScopeOrNamespace.ToNamespaceDefinitionHandle(MetadataReader);
            NamespaceDefinition parentDef = MetadataReader.GetNamespaceDefinition(parentNamespaceDefHandle);

            if (parentDef.ParentScopeOrNamespace.HandleType != HandleType.ScopeDefinition)
            {
                // The root parent namespace should have scope (assembly) handle as its parent
                return(false);
            }
            return(s_primitiveTypes.TryGetValue(Name, out categoryFlags));
        }
Example #4
0
        public unsafe RuntimeFieldHandle GetRuntimeFieldHandleForComponents(RuntimeTypeHandle declaringTypeHandle, IntPtr fieldName)
        {
            string fieldNameStr = GetStringFromMemoryInNativeFormat(fieldName);

            RuntimeFieldHandleKey key = new RuntimeFieldHandleKey(declaringTypeHandle, fieldNameStr);
            RuntimeFieldHandle    runtimeFieldHandle = default(RuntimeFieldHandle);

            lock (_runtimeFieldHandles)
            {
                if (!_runtimeFieldHandles.TryGetValue(key, out runtimeFieldHandle))
                {
                    IntPtr runtimeFieldHandleValue = MemoryHelpers.AllocateMemory(sizeof(DynamicFieldHandleInfo));
                    if (runtimeFieldHandleValue == IntPtr.Zero)
                    {
                        throw new OutOfMemoryException();
                    }

                    DynamicFieldHandleInfo *fieldData = (DynamicFieldHandleInfo *)runtimeFieldHandleValue.ToPointer();
                    fieldData->DeclaringType = *(IntPtr *)&declaringTypeHandle;
                    fieldData->FieldName     = fieldName;

                    // Special flag (lowest bit set) in the handle value to indicate it was dynamically allocated
                    runtimeFieldHandleValue = runtimeFieldHandleValue + 1;
                    runtimeFieldHandle      = *(RuntimeFieldHandle *)&runtimeFieldHandleValue;

                    _runtimeFieldHandles.Add(key, runtimeFieldHandle);
                }

                return(runtimeFieldHandle);
            }
        }
Example #5
0
        private static IntPtr GetThunkThatDereferencesThisPointerAndTailCallsTarget(IntPtr target)
        {
            IntPtr result = IntPtr.Zero;

            lock (s_deferenceAndCallThunks)
            {
                if (!s_deferenceAndCallThunks.TryGetValue(target, out result))
                {
                    if (s_DerefThisAndCall_ThunkPoolHeap == null)
                    {
                        s_DerefThisAndCall_ThunkPoolHeap = RuntimeAugments.CreateThunksHeap(s_constrainedCallSupport_DerefThisAndCall_CommonCallingStub);
                        Debug.Assert(s_DerefThisAndCall_ThunkPoolHeap != null);
                    }

                    IntPtr thunk = RuntimeAugments.AllocateThunk(s_DerefThisAndCall_ThunkPoolHeap);
                    Debug.Assert(thunk != IntPtr.Zero);

                    RuntimeAugments.SetThunkData(s_DerefThisAndCall_ThunkPoolHeap, thunk, target, IntPtr.Zero);

                    result = thunk;
                    s_deferenceAndCallThunks.Add(target, result);
                }
            }

            return(result);
        }
Example #6
0
        public void RegisterDynamicThreadStaticsInfo(RuntimeTypeHandle runtimeTypeHandle, uint offsetValue, int storageSize)
        {
            bool registered = false;

            Debug.Assert(offsetValue != 0 && storageSize > 0 && runtimeTypeHandle.IsDynamicType());

            _threadStaticsLock.Acquire();
            try
            {
                // Sanity check to make sure we do not register thread statics for the same type more than once
                uint temp;
                Debug.Assert(!_dynamicGenericsThreadStatics.TryGetValue(runtimeTypeHandle, out temp) && storageSize > 0);

                _dynamicGenericsThreadStatics.Add(runtimeTypeHandle, offsetValue);
                _dynamicGenericsThreadStaticSizes.Add(offsetValue, storageSize);
                registered = true;
            }
            finally
            {
                if (!registered)
                {
                    _dynamicGenericsThreadStatics.Remove(runtimeTypeHandle);
                    _dynamicGenericsThreadStaticSizes.Remove(offsetValue);
                }

                _threadStaticsLock.Release();
            }
        }
 public bool TryLookupConstructedLazyDictionaryForContext(IntPtr context, IntPtr signature, out IntPtr dictionary)
 {
     Debug.Assert(_typeLoaderLock.IsAcquired);
     return(_lazyGenericDictionaries.TryGetValue(new LazyDictionaryContext {
         _context = context, _signature = signature
     }, out dictionary));
 }
Example #8
0
        public static void FreeThunk(IntPtr commonStubAddress, IntPtr thunkAddress)
        {
            thunkAddress = ClearThumbBit(thunkAddress);

            lock (s_Lock)
            {
                LowLevelList <ThunksTemplateMap> mappings;
                if (s_ThunkMaps.TryGetValue(commonStubAddress, out mappings))
                {
                    for (int i = 0; i < mappings.Count; i++)
                    {
                        mappings[i].FreeThunk(thunkAddress);
                    }
                }
            }
        }
        /// <summary>
        /// Get a DefType that is the generic instantiation of an open generic type over instantiation arguments
        /// This looks like a rename of GetInstantiatedType, but isn't because the corert GetInstantiatedType
        /// relies on typeDef being a MetadataType, whereas this permits non-metadata types.
        /// </summary>
        public DefType ResolveGenericInstantiation(DefType typeDef, Instantiation arguments)
        {
            Debug.Assert(typeDef.Instantiation.IsNull || typeDef.Instantiation.Length == arguments.Length);

            MetadataType typeAsMetadataType = typeDef as MetadataType;

            if (typeAsMetadataType != null)
            {
                return(GetInstantiatedType(typeAsMetadataType, arguments));
            }

            if (_genericTypeInstances == null)
            {
                _genericTypeInstances = new LowLevelDictionary <GenericTypeInstanceKey, DefType>();
            }

            GenericTypeInstanceKey key = new GenericTypeInstanceKey(typeDef, arguments);

            DefType result;

            if (!_genericTypeInstances.TryGetValue(key, out result))
            {
                NoMetadataType nmTypeDef = (NoMetadataType)typeDef;
                Debug.Assert(RuntimeAugments.IsGenericTypeDefinition(nmTypeDef.RuntimeTypeHandle));
                result = new NoMetadataType(this, nmTypeDef.RuntimeTypeHandle, nmTypeDef, arguments, key.GetHashCode());

                _genericTypeInstances.Add(key, result);
            }

            return(result.WithDebugName());
        }
Example #10
0
        //
        // Returns the native layout info reader
        //
        internal static unsafe NativeReader GetNativeLayoutInfoReader(TypeManagerHandle moduleHandle)
        {
            Debug.Assert(!moduleHandle.IsNull);

            if (t_moduleNativeReaders == null)
            {
                t_moduleNativeReaders = new LowLevelDictionary <TypeManagerHandle, NativeReader>();
            }

            NativeReader result;

            if (t_moduleNativeReaders.TryGetValue(moduleHandle, out result))
            {
                return(result);
            }

            byte *pBlob;
            uint  cbBlob;

            if (RuntimeAugments.FindBlob(moduleHandle, (int)ReflectionMapBlob.NativeLayoutInfo, new IntPtr(&pBlob), new IntPtr(&cbBlob)))
            {
                result = new NativeReader(pBlob, cbBlob);
            }

            t_moduleNativeReaders.Add(moduleHandle, result);
            return(result);
        }
Example #11
0
        public static unsafe IntPtr GetGenericMethodFunctionPointer(IntPtr canonFunctionPointer, IntPtr instantiationArgument)
        {
            if (instantiationArgument == IntPtr.Zero)
            {
                return(canonFunctionPointer);
            }

            lock (s_genericFunctionPointerDictionary)
            {
                GenericMethodDescriptorInfo key;
                key.MethodFunctionPointer = canonFunctionPointer;
                key.InstantiationArgument = instantiationArgument;

                uint index = 0;
                if (!s_genericFunctionPointerDictionary.TryGetValue(key, out index))
                {
                    // Capture new index value
                    index = s_genericFunctionPointerNextIndex;

                    int  newChunkIndex    = (int)(index / c_genericDictionaryChunkSize);
                    uint newSubChunkIndex = index % c_genericDictionaryChunkSize;

                    // Generate new chunk if existing chunks are insufficient
                    if (s_genericFunctionPointerCollection.Count <= newChunkIndex)
                    {
                        System.Diagnostics.Debug.Assert(newSubChunkIndex == 0);

                        // New generic descriptors are allocated on the native heap and not tracked in the GC.
                        UIntPtr allocationSize = new UIntPtr((uint)(c_genericDictionaryChunkSize * sizeof(RuntimeGeneratedGenericMethodDescriptor)));
                        IntPtr  pNewMem        = Interop.MemAlloc(allocationSize);
                        s_genericFunctionPointerCollection.Add(pNewMem);
                    }

                    RuntimeGeneratedGenericMethodDescriptor *newDescriptor = &((RuntimeGeneratedGenericMethodDescriptor *)s_genericFunctionPointerCollection[newChunkIndex])[newSubChunkIndex];

                    newDescriptor->Set(canonFunctionPointer, instantiationArgument);

                    s_genericFunctionPointerDictionary.LookupOrAdd(key, index);

                    // Now that we can no longer have failed, update the next index.
                    s_genericFunctionPointerNextIndex++;
                }

                // Lookup within list
                int  chunkIndex    = (int)(index / c_genericDictionaryChunkSize);
                uint subChunkIndex = index % c_genericDictionaryChunkSize;
                RuntimeGeneratedGenericMethodDescriptor *genericRuntimeFunctionPointer = &((RuntimeGeneratedGenericMethodDescriptor *)s_genericFunctionPointerCollection[chunkIndex])[subChunkIndex];

                GenericMethodDescriptor *genericFunctionPointer = &genericRuntimeFunctionPointer->Descriptor;
                System.Diagnostics.Debug.Assert(canonFunctionPointer == genericFunctionPointer->MethodFunctionPointer);
                System.Diagnostics.Debug.Assert(instantiationArgument == genericFunctionPointer->InstantiationArgument);

                return((IntPtr)((byte *)genericFunctionPointer + FatFunctionPointerOffset));
            }
        }
        public uint GetNextThreadStaticsOffsetValue(TypeManagerHandle typeManagerHandle)
        {
            if (!_maxThreadLocalIndex.TryGetValue(typeManagerHandle.GetIntPtrUNSAFE(), out uint result))
            {
                result = (uint)RuntimeAugments.GetHighestStaticThreadStaticIndex(typeManagerHandle);
            }

            _maxThreadLocalIndex[typeManagerHandle.GetIntPtrUNSAFE()] = checked (++result);

            return(result);
        }
        private LowLevelDictionary<string, QHandle> CreateCaseInsensitiveTypeDictionary()
        {
            //
            // Collect all of the *non-nested* types and type-forwards.
            //
            //   The keys are full typenames in lower-cased form.
            //   The value is a tuple containing either a TypeDefinitionHandle or TypeForwarderHandle and the associated Reader
            //      for that handle.
            //
            // We do not store nested types here. The container type is resolved and chosen first, then the nested type chosen from
            // that. If we chose the wrong container type and fail the match as a result, that's too bad. (The desktop CLR has the
            // same issue.)
            //

            LowLevelDictionary<string, QHandle> dict = new LowLevelDictionary<string, QHandle>();

            foreach (QScopeDefinition scope in AllScopes)
            {
                MetadataReader reader = scope.Reader;
                ScopeDefinition scopeDefinition = scope.ScopeDefinition;
                IEnumerable<NamespaceDefinitionHandle> topLevelNamespaceHandles = new NamespaceDefinitionHandle[] { scopeDefinition.RootNamespaceDefinition };
                IEnumerable<NamespaceDefinitionHandle> allNamespaceHandles = reader.GetTransitiveNamespaces(topLevelNamespaceHandles);
                foreach (NamespaceDefinitionHandle namespaceHandle in allNamespaceHandles)
                {
                    string ns = namespaceHandle.ToNamespaceName(reader);
                    if (ns.Length != 0)
                        ns = ns + ".";
                    ns = ns.ToLower();

                    NamespaceDefinition namespaceDefinition = namespaceHandle.GetNamespaceDefinition(reader);
                    foreach (TypeDefinitionHandle typeDefinitionHandle in namespaceDefinition.TypeDefinitions)
                    {
                        string fullName = ns + typeDefinitionHandle.GetTypeDefinition(reader).Name.GetString(reader).ToLower();
                        QHandle existingValue;
                        if (!dict.TryGetValue(fullName, out existingValue))
                        {
                            dict.Add(fullName, new QHandle(reader, typeDefinitionHandle));
                        }
                    }

                    foreach (TypeForwarderHandle typeForwarderHandle in namespaceDefinition.TypeForwarders)
                    {
                        string fullName = ns + typeForwarderHandle.GetTypeForwarder(reader).Name.GetString(reader).ToLower();
                        QHandle existingValue;
                        if (!dict.TryGetValue(fullName, out existingValue))
                        {
                            dict.Add(fullName, new QHandle(reader, typeForwarderHandle));
                        }
                    }
                }
            }

            return dict;
        }
        private LowLevelList <ResourceInfo> GetExtractedResources(Assembly assembly)
        {
            LowLevelDictionary <String, LowLevelList <ResourceInfo> > extractedResourceDictionary = this.ExtractedResourceDictionary;
            String assemblyName = assembly.GetName().FullName;
            LowLevelList <ResourceInfo> resourceInfos;

            if (!extractedResourceDictionary.TryGetValue(assemblyName, out resourceInfos))
            {
                return(new LowLevelList <ResourceInfo>());
            }
            return(resourceInfos);
        }
Example #15
0
            public static unsafe IntPtr Get(RuntimeTypeHandle constraintType, RuntimeMethodHandle constrainedMethod)
            {
                lock (s_genericConstrainedCallDescs)
                {
                    // Get list of constrained call descs associated with a given type
                    LowLevelList <IntPtr> associatedCallDescs;
                    if (!s_genericConstrainedCallDescs.TryGetValue(constraintType, out associatedCallDescs))
                    {
                        associatedCallDescs = new LowLevelList <IntPtr>();
                        s_genericConstrainedCallDescs.Add(constraintType, associatedCallDescs);
                    }

                    // Perform linear scan of associated call descs to see if one matches
                    for (int i = 0; i < associatedCallDescs.Count; i++)
                    {
                        GenericConstrainedCallDesc *callDesc = (GenericConstrainedCallDesc *)associatedCallDescs[i];

                        Debug.Assert(constraintType.Equals(callDesc->_constraintType));

                        if (callDesc->_constrainedMethod != constrainedMethod)
                        {
                            continue;
                        }

                        // Found matching entry.
                        return(associatedCallDescs[i]);
                    }

                    // Did not find match, allocate a new one and add it to the lookup list
                    IntPtr newCallDescPtr = MemoryHelpers.AllocateMemory(sizeof(GenericConstrainedCallDesc));
                    GenericConstrainedCallDesc *newCallDesc = (GenericConstrainedCallDesc *)newCallDescPtr;
                    newCallDesc->_exactTarget = IntPtr.Zero;
                    if (RuntimeAugments.IsValueType(constraintType))
                    {
                        newCallDesc->_lookupFunc = s_resolveCallOnValueTypeFuncPtr;
                    }
                    else
                    {
                        newCallDesc->_lookupFunc = s_resolveCallOnReferenceTypeFuncPtr;
                    }

                    newCallDesc->_constraintType    = constraintType;
                    newCallDesc->_constrainedMethod = constrainedMethod;

                    associatedCallDescs.Add(newCallDescPtr);

                    return(newCallDescPtr);
                }
            }
        private LowLevelDictionary <string, Handle> CreateCaseInsensitiveTypeDictionary()
        {
            //
            // Collect all of the *non-nested* types and type-forwards.
            //
            //   The keys are full typenames in lower-cased form.
            //   The value is a tuple containing either a TypeDefinitionHandle or TypeForwarderHandle and the associated Reader
            //      for that handle.
            //
            // We do not store nested types here. The container type is resolved and chosen first, then the nested type chosen from
            // that. If we chose the wrong container type and fail the match as a result, that's too bad. (The desktop CLR has the
            // same issue.)
            //

            LowLevelDictionary <string, Handle> dict = new LowLevelDictionary <string, Handle>();

            foreach (TypeDefinitionHandle typeDefinitionHandle in MetadataReader.TypeDefinitions)
            {
                TypeDefinition typeDefinition = MetadataReader.GetTypeDefinition(typeDefinitionHandle);
                string         typeName       = MetadataReader.GetString(typeDefinition.Name);
                string         typeNamespace  = MetadataReader.GetString(typeDefinition.NamespaceDefinition);
                string         fullName       = typeName;
                if (!String.IsNullOrEmpty(typeNamespace))
                {
                    fullName = typeNamespace + "." + typeName;
                }
                Handle existingValue;
                if (!dict.TryGetValue(fullName, out existingValue))
                {
                    dict.Add(fullName, typeDefinitionHandle);
                }
            }

            // TODO! Implement type forwarding logic.

            /*
             *      foreach (TypeForwarderHandle typeForwarderHandle in namespaceDefinition.TypeForwarders)
             *      {
             *          string fullName = ns + typeForwarderHandle.GetTypeForwarder(reader).Name.GetString(reader).ToLowerInvariant();
             *          QHandle existingValue;
             *          if (!dict.TryGetValue(fullName, out existingValue))
             *          {
             *              dict.Add(fullName, new QHandle(reader, typeForwarderHandle));
             *          }
             *      }
             *  }*/

            return(dict);
        }
Example #17
0
 public unsafe IntPtr ToIntPtr()
 {
     lock (s_internedResolverHash)
     {
         IntPtr returnValue;
         if (s_internedResolverHash.TryGetValue(this, out returnValue))
         {
             return(returnValue);
         }
         returnValue = Marshal.AllocHGlobal(sizeof(OpenMethodResolver));
         *((OpenMethodResolver *)returnValue) = this;
         s_internedResolverHash.Add(this, returnValue);
         return(returnValue);
     }
 }
 public unsafe IntPtr GetMemoryBlockForValue(IntPtr value)
 {
     using (LockHolder.Hold(_lock))
     {
         IntPtr result;
         if (_allocatedBlocks.TryGetValue(value, out result))
         {
             return(result);
         }
         result = MemoryHelpers.AllocateMemory(IntPtr.Size);
         *(IntPtr *)(result.ToPointer()) = value;
         _allocatedBlocks.Add(value, result);
         return(result);
     }
 }
Example #19
0
 public unsafe IntPtr ToIntPtr()
 {
     lock (s_internedResolverHash)
     {
         IntPtr returnValue;
         if (s_internedResolverHash.TryGetValue(this, out returnValue))
         {
             return(returnValue);
         }
         returnValue = (IntPtr)NativeMemory.Alloc((nuint)sizeof(OpenMethodResolver));
         *((OpenMethodResolver *)returnValue) = this;
         s_internedResolverHash.Add(this, returnValue);
         return(returnValue);
     }
 }
 public unsafe IntPtr GetMemoryBlockForValue(ThreadStaticFieldOffsets value)
 {
     using (LockHolder.Hold(_lock))
     {
         IntPtr result;
         if (_allocatedBlocks.TryGetValue(value, out result))
         {
             return(result);
         }
         result = MemoryHelpers.AllocateMemory(sizeof(ThreadStaticFieldOffsets));
         *(ThreadStaticFieldOffsets *)(result.ToPointer()) = value;
         _allocatedBlocks.Add(value, result);
         return(result);
     }
 }
 unsafe public IntPtr ToIntPtr()
 {
     lock (s_internedResolverHash)
     {
         IntPtr returnValue;
         if (s_internedResolverHash.TryGetValue(this, out returnValue))
         {
             return(returnValue);
         }
         returnValue = Interop.MemAlloc(new UIntPtr((uint)sizeof(OpenMethodResolver)));
         *((OpenMethodResolver *)returnValue) = this;
         s_internedResolverHash.Add(this, returnValue);
         return(returnValue);
     }
 }
Example #22
0
        private Exception TryResolveCaseInsensitive(ReflectionDomain reflectionDomain, RuntimeAssembly currentAssembly, out RuntimeType result)
        {
            String fullName = this.ToString().ToLower();

            LowLevelDictionary <String, QHandle> dict = GetCaseInsensitiveTypeDictionary(currentAssembly);
            QHandle qualifiedHandle;

            if (!dict.TryGetValue(fullName, out qualifiedHandle))
            {
                result = null;
                return(new TypeLoadException(SR.Format(SR.TypeLoad_TypeNotFound, this.ToString(), currentAssembly.FullName)));
            }

            MetadataReader reader = qualifiedHandle.Reader;
            Handle         typeDefOrForwarderHandle = qualifiedHandle.Handle;

            HandleType handleType = typeDefOrForwarderHandle.HandleType;

            switch (handleType)
            {
            case HandleType.TypeDefinition:
            {
                TypeDefinitionHandle typeDefinitionHandle = typeDefOrForwarderHandle.ToTypeDefinitionHandle(reader);
                result = reflectionDomain.ResolveTypeDefinition(reader, typeDefinitionHandle);
                return(null);
            }

            case HandleType.TypeForwarder:
            {
                TypeForwarder        typeForwarder           = typeDefOrForwarderHandle.ToTypeForwarderHandle(reader).GetTypeForwarder(reader);
                ScopeReferenceHandle destinationScope        = typeForwarder.Scope;
                RuntimeAssemblyName  destinationAssemblyName = destinationScope.ToRuntimeAssemblyName(reader);
                RuntimeAssembly      destinationAssembly;
                Exception            exception = RuntimeAssembly.TryGetRuntimeAssembly(reflectionDomain, destinationAssemblyName, out destinationAssembly);
                if (exception != null)
                {
                    result = null;
                    return(exception);
                }
                return(TryResolveCaseInsensitive(reflectionDomain, destinationAssembly, out result));
            }

            default:
                throw new InvalidOperationException();
            }
        }
Example #23
0
        public int TryGetThreadStaticsSizeForDynamicType(int index, out int numTlsCells)
        {
            Debug.Assert((index & DynamicTypeTlsOffsetFlag) == DynamicTypeTlsOffsetFlag);

            numTlsCells = _maxTlsCells;

            using (LockHolder.Hold(_threadStaticsLock))
            {
                int storageSize;
                if (_dynamicGenericsThreadStaticSizes.TryGetValue((uint)index, out storageSize))
                {
                    return(storageSize);
                }
            }

            Debug.Assert(false);
            return(0);
        }
Example #24
0
        //
        // Returns the native layout info reader
        //
        internal unsafe NativeReader GetNativeLayoutInfoReader(IntPtr moduleHandle)
        {
            Debug.Assert(moduleHandle != IntPtr.Zero);

            if (t_moduleNativeReaders == null)
                t_moduleNativeReaders = new LowLevelDictionary<IntPtr, NativeReader>();

            NativeReader result = null;
            if (t_moduleNativeReaders.TryGetValue(moduleHandle, out result))
                return result;

            byte* pBlob;
            uint cbBlob;
            if (RuntimeAugments.FindBlob(moduleHandle, (int)ReflectionMapBlob.NativeLayoutInfo, new IntPtr(&pBlob), new IntPtr(&cbBlob)))
                result = new NativeReader(pBlob, cbBlob);

            t_moduleNativeReaders.Add(moduleHandle, result);
            return result;
        }
Example #25
0
        /// <summary>
        /// Create a runtime method handle from name, signature and generic arguments. If the methodSignature
        /// is constructed from a metadata token, the methodName should be IntPtr.Zero, as it already encodes the method
        /// name.
        /// </summary>
        public unsafe RuntimeMethodHandle GetRuntimeMethodHandleForComponents(RuntimeTypeHandle declaringTypeHandle, IntPtr methodName, RuntimeSignature methodSignature, RuntimeTypeHandle[] genericMethodArgs)
        {
            string methodNameStr = methodName == IntPtr.Zero ? null : GetStringFromMemoryInNativeFormat(methodName);

            RuntimeMethodHandleKey key = new RuntimeMethodHandleKey(declaringTypeHandle, methodNameStr, methodSignature, genericMethodArgs);
            RuntimeMethodHandle    runtimeMethodHandle = default(RuntimeMethodHandle);

            lock (_runtimeMethodHandles)
            {
                if (!_runtimeMethodHandles.TryGetValue(key, out runtimeMethodHandle))
                {
                    int sizeToAllocate       = sizeof(DynamicMethodHandleInfo);
                    int numGenericMethodArgs = genericMethodArgs == null ? 0 : genericMethodArgs.Length;
                    // Use checked arithmetics to ensure there aren't any overflows/truncations
                    sizeToAllocate = checked (sizeToAllocate + (numGenericMethodArgs > 0 ? sizeof(IntPtr) * (numGenericMethodArgs - 1) : 0));
                    IntPtr runtimeMethodHandleValue = MemoryHelpers.AllocateMemory(sizeToAllocate);
                    if (runtimeMethodHandleValue == IntPtr.Zero)
                    {
                        throw new OutOfMemoryException();
                    }

                    DynamicMethodHandleInfo *methodData = (DynamicMethodHandleInfo *)runtimeMethodHandleValue.ToPointer();
                    methodData->DeclaringType   = *(IntPtr *)&declaringTypeHandle;
                    methodData->MethodName      = methodName;
                    methodData->MethodSignature = methodSignature;
                    methodData->NumGenericArgs  = numGenericMethodArgs;
                    IntPtr *genericArgPtr = &(methodData->GenericArgsArray);
                    for (int i = 0; i < numGenericMethodArgs; i++)
                    {
                        RuntimeTypeHandle currentArg = genericMethodArgs[i];
                        genericArgPtr[i] = *(IntPtr *)&currentArg;
                    }

                    // Special flag in the handle value to indicate it was dynamically allocated, and doesn't point into the InvokeMap blob
                    runtimeMethodHandleValue = runtimeMethodHandleValue + 1;
                    runtimeMethodHandle      = *(RuntimeMethodHandle *)&runtimeMethodHandleValue;

                    _runtimeMethodHandles.Add(key, runtimeMethodHandle);
                }

                return(runtimeMethodHandle);
            }
        }
        internal sealed override RuntimeTypeInfo GetTypeCoreCaseInsensitive(string fullName)
        {
            LowLevelDictionary <string, QHandle> dict = CaseInsensitiveTypeDictionary;
            QHandle qualifiedHandle;

            if (!dict.TryGetValue(fullName.ToLowerInvariant(), out qualifiedHandle))
            {
                return(null);
            }

            MetadataReader reader = qualifiedHandle.Reader;
            Handle         typeDefOrForwarderHandle = qualifiedHandle.Handle;

            HandleType handleType = typeDefOrForwarderHandle.HandleType;

            switch (handleType)
            {
            case HandleType.TypeDefinition:
            {
                TypeDefinitionHandle typeDefinitionHandle = typeDefOrForwarderHandle.ToTypeDefinitionHandle(reader);
                return(typeDefinitionHandle.ResolveTypeDefinition(reader));
            }

            case HandleType.TypeForwarder:
            {
                TypeForwarder        typeForwarder           = typeDefOrForwarderHandle.ToTypeForwarderHandle(reader).GetTypeForwarder(reader);
                ScopeReferenceHandle destinationScope        = typeForwarder.Scope;
                RuntimeAssemblyName  destinationAssemblyName = destinationScope.ToRuntimeAssemblyName(reader);
                RuntimeAssemblyInfo  destinationAssembly     = RuntimeAssemblyInfo.GetRuntimeAssemblyIfExists(destinationAssemblyName);
                if (destinationAssembly == null)
                {
                    return(null);
                }
                return(destinationAssembly.GetTypeCoreCaseInsensitive(fullName));
            }

            default:
                throw new InvalidOperationException();
            }
        }
        internal sealed override RuntimeTypeInfo GetTypeCoreCaseInsensitive(string fullName)
        {
            LowLevelDictionary <string, Handle> dict = CaseInsensitiveTypeDictionary;
            Handle typeDefOrForwarderHandle;

            if (!dict.TryGetValue(fullName.ToLowerInvariant(), out typeDefOrForwarderHandle))
            {
                return(null);
            }

            MetadataReader reader = MetadataReader;

            HandleKind handleType = typeDefOrForwarderHandle.Kind;

            switch (handleType)
            {
            case HandleKind.TypeDefinition:
            {
                TypeDefinitionHandle typeDefinitionHandle = (TypeDefinitionHandle)typeDefOrForwarderHandle;
                throw new NotImplementedException();
//                        return typeDefinitionHandle.ResolveTypeDefinition(reader);
            }

            case HandleKind.ExportedType:
            {
                throw new NotImplementedException();

                /*TypeForwarder typeForwarder = typeDefOrForwarderHandle.ToTypeForwarderHandle(reader).GetTypeForwarder(reader);
                 * ScopeReferenceHandle destinationScope = typeForwarder.Scope;
                 * RuntimeAssemblyName destinationAssemblyName = destinationScope.ToRuntimeAssemblyName(reader);
                 * RuntimeAssembly destinationAssembly = RuntimeAssembly.GetRuntimeAssemblyIfExists(destinationAssemblyName);
                 * if (destinationAssembly == null)
                 *  return null;
                 * return destinationAssembly.GetTypeCoreCaseInsensitive(fullName);*/
            }

            default:
                throw new InvalidOperationException();
            }
        }
        private static int AddConverter(CallConversionInfo newConversionInfo)
        {
            using (LockHolder.Hold(s_callConvertersCacheLock))
            {
                int converterId;
                if (s_callConvertersCache.TryGetValue(newConversionInfo, out converterId))
                {
                    Debug.Assert(converterId < s_callConvertersCount && s_callConverters[converterId].Equals(newConversionInfo));
                    return(converterId);
                }

                if (s_callConvertersCount >= s_callConverters.Length)
                {
                    CallConversionInfo[] newArray = new CallConversionInfo[s_callConverters.Length * 2];
                    Array.Copy(s_callConverters, newArray, s_callConvertersCount);
                    s_callConverters = newArray;
                }

                s_callConverters[s_callConvertersCount++] = newConversionInfo;
                s_callConvertersCache[newConversionInfo]  = s_callConvertersCount - 1;
                return(s_callConvertersCount - 1);
            }
        }
        //
        // Main iterator.
        //
        private IEnumerable <CustomAttributeData> GetMatchingCustomAttributesIterator(E element, Func <Type, bool> rawPassesFilter, bool inherit)
        {
            Func <Type, bool> passesFilter =
                delegate(Type attributeType)
            {
                // Windows prohibits instantiating WinRT custom attributes. Filter them from the search as the desktop CLR does.
                TypeAttributes typeAttributes = attributeType.Attributes;
                if (0 != (typeAttributes & TypeAttributes.WindowsRuntime))
                {
                    return(false);
                }
                return(rawPassesFilter(attributeType));
            };

            LowLevelList <CustomAttributeData> immediateResults = new LowLevelList <CustomAttributeData>();

            foreach (CustomAttributeData cad in GetDeclaredCustomAttributes(element))
            {
                if (passesFilter(cad.AttributeType))
                {
                    yield return(cad);

                    immediateResults.Add(cad);
                }
            }
            if (inherit)
            {
                // Because the "inherit" parameter defaults to "true", we probably get here for a lot of elements that
                // don't actually have any inheritance chains. Try to avoid doing any unnecessary setup for the inheritance walk
                // unless we have to.
                element = GetParent(element);
                if (element != null)
                {
                    // This dictionary serves two purposes:
                    //   - Let us know which attribute types we've encountered at lower levels so we can block them from appearing twice in the results
                    //     if appropriate.
                    //
                    //   - Cache the results of retrieving the usage attribute.
                    //
                    LowLevelDictionary <TypeUnificationKey, AttributeUsageAttribute> encounteredTypes = new LowLevelDictionary <TypeUnificationKey, AttributeUsageAttribute>(11);

                    for (int i = 0; i < immediateResults.Count; i++)
                    {
                        Type attributeType = immediateResults[i].AttributeType;
                        AttributeUsageAttribute usage;
                        TypeUnificationKey      attributeTypeKey = new TypeUnificationKey(attributeType);
                        if (!encounteredTypes.TryGetValue(attributeTypeKey, out usage))
                        {
                            encounteredTypes.Add(attributeTypeKey, null);
                        }
                    }

                    do
                    {
                        foreach (CustomAttributeData cad in GetDeclaredCustomAttributes(element))
                        {
                            Type attributeType = cad.AttributeType;
                            if (!passesFilter(attributeType))
                            {
                                continue;
                            }
                            AttributeUsageAttribute usage;
                            TypeUnificationKey      attributeTypeKey = new TypeUnificationKey(attributeType);
                            if (!encounteredTypes.TryGetValue(attributeTypeKey, out usage))
                            {
                                // Type was not encountered before. Only include it if it is inheritable.
                                usage = GetAttributeUsage(attributeType);
                                encounteredTypes.Add(attributeTypeKey, usage);
                                if (usage.Inherited)
                                {
                                    yield return(cad);
                                }
                            }
                            else
                            {
                                if (usage == null)
                                {
                                    usage = GetAttributeUsage(attributeType);
                                }
                                encounteredTypes[attributeTypeKey] = usage;
                                // Type was encountered at a lower level. Only include it if its inheritable AND allowMultiple.
                                if (usage.Inherited && usage.AllowMultiple)
                                {
                                    yield return(cad);
                                }
                            }
                        }
                    }while ((element = GetParent(element)) != null);
                }
            }
        }
Example #30
0
            public static unsafe IntPtr Get(RuntimeTypeHandle constraintType, RuntimeTypeHandle constrainedMethodType, int constrainedMethodSlot, bool directConstrainedCall = false)
            {
                LowLevelDictionary <RuntimeTypeHandle, LowLevelList <IntPtr> > nonGenericConstrainedCallDescsDirect = directConstrainedCall ? s_nonGenericConstrainedCallDescsDirect : s_nonGenericConstrainedCallDescs;

                lock (nonGenericConstrainedCallDescsDirect)
                {
                    // Get list of constrained call descs associated with a given type
                    LowLevelList <IntPtr> associatedCallDescs;
                    if (!nonGenericConstrainedCallDescsDirect.TryGetValue(constraintType, out associatedCallDescs))
                    {
                        associatedCallDescs = new LowLevelList <IntPtr>();
                        nonGenericConstrainedCallDescsDirect.Add(constraintType, associatedCallDescs);
                    }

                    // Perform linear scan of associated call descs to see if one matches
                    for (int i = 0; i < associatedCallDescs.Count; i++)
                    {
                        NonGenericConstrainedCallDesc *callDesc = (NonGenericConstrainedCallDesc *)associatedCallDescs[i];

                        Debug.Assert(constraintType.Equals(callDesc->_constraintType));

                        if (callDesc->_constrainedMethodSlot != constrainedMethodSlot)
                        {
                            continue;
                        }

                        if (!callDesc->_constrainedMethodType.Equals(constrainedMethodType))
                        {
                            continue;
                        }

                        // Found matching entry.
                        return(associatedCallDescs[i]);
                    }

                    // Did not find match, allocate a new one and add it to the lookup list
                    IntPtr newCallDescPtr = MemoryHelpers.AllocateMemory(sizeof(NonGenericConstrainedCallDesc));
                    NonGenericConstrainedCallDesc *newCallDesc = (NonGenericConstrainedCallDesc *)newCallDescPtr;
                    newCallDesc->_exactTarget = IntPtr.Zero;
                    if (directConstrainedCall)
                    {
                        newCallDesc->_lookupFunc = RuntimeAugments.GetUniversalTransitionThunk();
                    }
                    else
                    {
                        if (RuntimeAugments.IsValueType(constraintType))
                        {
                            newCallDesc->_lookupFunc = s_resolveCallOnValueTypeFuncPtr;
                        }
                        else
                        {
                            newCallDesc->_lookupFunc = s_resolveCallOnReferenceTypeFuncPtr;
                        }
                    }


                    newCallDesc->_constraintType        = constraintType;
                    newCallDesc->_constrainedMethodSlot = constrainedMethodSlot;
                    newCallDesc->_constrainedMethodType = constrainedMethodType;

                    associatedCallDescs.Add(newCallDescPtr);

                    return(newCallDescPtr);
                }
            }
        public TypeDesc ResolveRuntimeTypeHandle(RuntimeTypeHandle rtth)
        {
            TypeDesc returnedType;

            if (_runtimeTypeHandleResolutionCache.TryGetValue(rtth, out returnedType))
            {
                return(returnedType);
            }

            if (rtth.Equals(CanonType.RuntimeTypeHandle))
            {
                returnedType = CanonType;
            }
            else if (rtth.Equals(UniversalCanonType.RuntimeTypeHandle))
            {
                returnedType = UniversalCanonType;
            }
            else if (RuntimeAugments.IsGenericTypeDefinition(rtth))
            {
                returnedType = TryGetMetadataBasedTypeFromRuntimeTypeHandle_Uncached(rtth);
                if (returnedType == null)
                {
                    unsafe
                    {
                        TypeDesc[] genericParameters = new TypeDesc[rtth.ToEETypePtr()->GenericArgumentCount];
                        for (int i = 0; i < genericParameters.Length; i++)
                        {
                            genericParameters[i] = GetSignatureVariable(i, false);
                        }

                        returnedType = new NoMetadataType(this, rtth, null, new Instantiation(genericParameters), rtth.GetHashCode());
                    }
                }
            }
            else if (RuntimeAugments.IsGenericType(rtth))
            {
                RuntimeTypeHandle   typeDefRuntimeTypeHandle;
                RuntimeTypeHandle[] genericArgRuntimeTypeHandles;
                typeDefRuntimeTypeHandle = RuntimeAugments.GetGenericInstantiation(rtth, out genericArgRuntimeTypeHandles);

                DefType       typeDef     = (DefType)ResolveRuntimeTypeHandle(typeDefRuntimeTypeHandle);
                Instantiation genericArgs = ResolveRuntimeTypeHandles(genericArgRuntimeTypeHandles);
                returnedType = ResolveGenericInstantiation(typeDef, genericArgs);
            }
            else if (RuntimeAugments.IsArrayType(rtth))
            {
                RuntimeTypeHandle elementTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(rtth);
                TypeDesc          elementType       = ResolveRuntimeTypeHandle(elementTypeHandle);
                unsafe
                {
                    if (rtth.ToEETypePtr()->IsSzArray)
                    {
                        returnedType = GetArrayType(elementType);
                    }
                    else
                    {
                        returnedType = GetArrayType(elementType, rtth.ToEETypePtr()->ArrayRank);
                    }
                }
            }
            else if (RuntimeAugments.IsUnmanagedPointerType(rtth))
            {
                RuntimeTypeHandle targetTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(rtth);
                TypeDesc          targetType       = ResolveRuntimeTypeHandle(targetTypeHandle);
                returnedType = GetPointerType(targetType);
            }
            else if (RuntimeAugments.IsByRefType(rtth))
            {
                RuntimeTypeHandle targetTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(rtth);
                TypeDesc          targetType       = ResolveRuntimeTypeHandle(targetTypeHandle);
                returnedType = GetByRefType(targetType);
            }
            else
            {
                returnedType = TryGetMetadataBasedTypeFromRuntimeTypeHandle_Uncached(rtth);
                if (returnedType == null)
                {
                    returnedType = new NoMetadataType(this, rtth, null, Instantiation.Empty, rtth.GetHashCode());
                }
            }

            // We either retrieved an existing DefType that is already registered with the runtime
            // or one that is not associated with an MethodTable yet. If it's not associated, associate it.
            if (returnedType.RuntimeTypeHandle.IsNull())
            {
                TypeBuilderState state = returnedType.GetTypeBuilderStateIfExist();
                bool             skipStoringRuntimeTypeHandle = false;

                // If we've already attempted to lookup and failed to retrieve this type handle, we
                // may have already decided to create a new one. In that case, do not attempt to abort
                // that creation process as it may have already begun the process of type creation
                if (state != null && state.AttemptedAndFailedToRetrieveTypeHandle)
                {
                    skipStoringRuntimeTypeHandle = true;
                }

                if (!skipStoringRuntimeTypeHandle)
                {
                    returnedType.SetRuntimeTypeHandleUnsafe(rtth);
                }
            }

            _runtimeTypeHandleResolutionCache.Add(rtth, returnedType);

            return(returnedType.WithDebugName());
        }