private bool FindMatchingInterfaceSlot(IntPtr moduleHandle, NativeReader nativeLayoutReader, ref NativeParser entryParser, ref ExternalReferencesTable extRefs, ref RuntimeTypeHandle declaringType, ref MethodNameAndSignature methodNameAndSignature, RuntimeTypeHandle openTargetTypeHandle, RuntimeTypeHandle[] targetTypeInstantiation, bool variantDispatch)
        {
            uint numTargetImplementations = entryParser.GetUnsigned();

            for (uint j = 0; j < numTargetImplementations; j++)
            {
                uint nameAndSigToken = extRefs.GetRvaFromIndex(entryParser.GetUnsigned());
                MethodNameAndSignature targetMethodNameAndSignature = GetMethodNameAndSignatureFromNativeReader(nativeLayoutReader, nameAndSigToken);
                RuntimeTypeHandle targetTypeHandle = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());

#if REFLECTION_EXECUTION_TRACE
                ReflectionExecutionLogger.WriteLine("    Searching for GVM implementation on targe type = " + GetTypeNameDebug(targetTypeHandle));
#endif

                uint numIfaceImpls = entryParser.GetUnsigned();

                for (uint k = 0; k < numIfaceImpls; k++)
                {
                    RuntimeTypeHandle implementingTypeHandle = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());

                    uint numIfaceSigs = entryParser.GetUnsigned();

                    if (!openTargetTypeHandle.Equals(implementingTypeHandle))
                    {
                        // Skip over signatures data
                        for (uint l = 0; l < numIfaceSigs; l++)
                            entryParser.GetUnsigned();

                        continue;
                    }

                    for (uint l = 0; l < numIfaceSigs; l++)
                    {
                        RuntimeTypeHandle currentIfaceTypeHandle = default(RuntimeTypeHandle);

                        NativeParser ifaceSigParser = new NativeParser(nativeLayoutReader, extRefs.GetRvaFromIndex(entryParser.GetUnsigned()));
                        IntPtr currentIfaceSigPtr = ifaceSigParser.Reader.OffsetToAddress(ifaceSigParser.Offset);

                        if (TypeLoaderEnvironment.Instance.GetTypeFromSignatureAndContext(currentIfaceSigPtr, targetTypeInstantiation, null, out currentIfaceTypeHandle, out currentIfaceSigPtr))
                        {
                            Debug.Assert(!currentIfaceTypeHandle.IsNull());

                            if ((!variantDispatch && declaringType.Equals(currentIfaceTypeHandle)) ||
                                (variantDispatch && RuntimeAugments.IsAssignableFrom(declaringType, currentIfaceTypeHandle)))
                            {
#if REFLECTION_EXECUTION_TRACE
                                ReflectionExecutionLogger.WriteLine("    " + (declaringType.Equals(currentIfaceTypeHandle) ? "Exact" : "Variant-compatible") + " match found on this target type!");
#endif
                                // We found the GVM slot target for the input interface GVM call, so let's update the interface GVM slot and return success to the caller
                                declaringType = targetTypeHandle;
                                methodNameAndSignature = targetMethodNameAndSignature;
                                return true;
                            }
                        }
                    }
                }
            }

            return false;
        }
        private MethodNameAndSignature GetMethodNameAndSignatureFromNativeReader(NativeReader nativeLayoutReader, uint nativeLayoutOffset)
        {
            NativeParser parser = new NativeParser(nativeLayoutReader, nativeLayoutOffset);

            string methodName = parser.GetString();

            // Signatures are indirected to through a relative offset so that we don't have to parse them
            // when not comparing signatures (parsing them requires resolving types and is tremendously 
            // expensive).
            NativeParser sigParser = parser.GetParserFromRelativeOffset();
            IntPtr methodSigPtr = sigParser.Reader.OffsetToAddress(sigParser.Offset);

            return new MethodNameAndSignature(methodName, RuntimeMethodSignature.CreateFromNativeLayoutSignature(methodSigPtr));
        }
예제 #3
0
 public void Decode(NativeReader reader)
 {
     if (reader.ReadUInt32(0) != Signature)
         reader.ThrowBadImageFormatException();
     reader.Read(4, out ScopeDefinitions);
 }
예제 #4
0
        // Creates a metadata reader on a memory-mapped file block
        public unsafe MetadataReader(IntPtr pBuffer, int cbBuffer)
        {
            _streamReader = new NativeReader((byte*)pBuffer, (uint)cbBuffer);

            _header = new MetadataHeader();
            _header.Decode(_streamReader);
        }
예제 #5
0
        public NativeHashtable(NativeParser parser)
        {
            uint header = parser.GetUInt8();

            _reader = parser.Reader;
            _baseOffset = parser.Offset;

            int numberOfBucketsShift = (int)(header >> 2);
            if (numberOfBucketsShift > 31)
                _reader.ThrowBadImageFormatException();
            _bucketMask = (uint)((1 << numberOfBucketsShift) - 1);

            byte entryIndexSize = (byte)(header & 3);
            if (entryIndexSize > 2)
                _reader.ThrowBadImageFormatException();
            _entryIndexSize = entryIndexSize;
        }
        private unsafe static bool TryGetNativeReaderForBlob(IntPtr module, ReflectionMapBlob blob, out NativeReader reader)
        {
            byte* pBlob;
            uint cbBlob;

            if (RuntimeAugments.FindBlob(module, (int)blob, (IntPtr)(&pBlob), (IntPtr)(&cbBlob)))
            {
                reader = new NativeReader(pBlob, cbBlob);
                return true;
            }

            reader = default(NativeReader);
            return false;
        }
예제 #7
0
 public NativeParser(NativeReader reader, uint offset)
 {
     _reader = reader;
     _offset = offset;
 }
        // get the statics hash table, external references, and static info table for a module
        // TODO multi-file: consider whether we want to cache this info
        private unsafe bool GetStaticsInfoHashtable(IntPtr moduleHandle, out NativeHashtable staticsInfoHashtable, out ExternalReferencesTable externalReferencesLookup, out ExternalReferencesTable staticInfoLookup)
        {
            byte* pBlob;
            uint cbBlob;

            staticsInfoHashtable = default(NativeHashtable);
            externalReferencesLookup = default(ExternalReferencesTable);
            staticInfoLookup = default(ExternalReferencesTable);

            // Load statics info hashtable
            if (!RuntimeAugments.FindBlob(moduleHandle, (int)ReflectionMapBlob.StaticsInfoHashtable, new IntPtr(&pBlob), new IntPtr(&cbBlob)))
                return false;
            NativeReader reader = new NativeReader(pBlob, cbBlob);
            NativeParser parser = new NativeParser(reader, 0);

            if (!externalReferencesLookup.InitializeNativeReferences(moduleHandle))
                return false;

            if (!staticInfoLookup.InitializeNativeStatics(moduleHandle))
                return false;

            staticsInfoHashtable = new NativeHashtable(parser);

            return true;
        }
예제 #9
0
        // get the generics hash table and external references table for a module
        // TODO multi-file: consider whether we want to cache this info
        private unsafe bool GetHashtableFromBlob(IntPtr moduleHandle, ReflectionMapBlob blobId, out NativeHashtable hashtable, out ExternalReferencesTable externalReferencesLookup)
        {
            byte* pBlob;
            uint cbBlob;

            hashtable = default(NativeHashtable);
            externalReferencesLookup = default(ExternalReferencesTable);

            if (!RuntimeAugments.FindBlob(moduleHandle, (int)blobId, new IntPtr(&pBlob), new IntPtr(&cbBlob)))
                return false;

            NativeReader reader = new NativeReader(pBlob, cbBlob);
            NativeParser parser = new NativeParser(reader, 0);

            hashtable = new NativeHashtable(parser);

            return externalReferencesLookup.InitializeNativeReferences(moduleHandle);
        }
예제 #10
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;
        }
예제 #11
0
 public NativeParser(NativeReader reader, uint offset)
 {
     _reader = reader;
     _offset = offset;
 }
예제 #12
0
        // Lazy loadings of hashtables (load on-demand only)
        private unsafe NativeHashtable LoadHashtable(IntPtr moduleHandle, ReflectionMapBlob hashtableBlobId, out ExternalReferencesTable externalFixupsTable)
        {
            // Load the common fixups table
            externalFixupsTable = default(ExternalReferencesTable);
            if (!externalFixupsTable.InitializeCommonFixupsTable(moduleHandle))
                return default(NativeHashtable);

            // Load the hashtable
            byte* pBlob;
            uint cbBlob;
            if (!RuntimeAugments.FindBlob(moduleHandle, (int)hashtableBlobId, new IntPtr(&pBlob), new IntPtr(&cbBlob)))
                return default(NativeHashtable);

            NativeReader reader = new NativeReader(pBlob, cbBlob);
            NativeParser parser = new NativeParser(reader, 0);
            return new NativeHashtable(parser);
        }