Beispiel #1
0
        /// <summary>
        /// Try to resolve a virtual call to targetMethod to its implementation on instanceType.
        /// </summary>
        /// <param name="instanceType">non-interface type</param>
        /// <param name="targetMethod">non-generic virtual or interface method</param>
        /// <param name="methodAddress">function pointer resolved</param>
        /// <returns>true if successful</returns>
        public static bool TryDispatchMethodOnTarget(TypeDesc instanceType, MethodDesc targetMethod, out IntPtr methodAddress)
        {
            methodAddress = IntPtr.Zero;

            if (targetMethod == null)
            {
                return(false);
            }

            if (IsPregeneratedOrTemplateTypeLoaded(instanceType))
            {
                if (targetMethod.OwningType.IsInterface)
                {
                    ushort interfaceSlot;
                    if (!TryGetInterfaceSlotNumberFromMethod(targetMethod, out interfaceSlot))
                    {
                        return(false);
                    }
                    methodAddress = RuntimeAugments.ResolveDispatchOnType(instanceType.GetRuntimeTypeHandle(),
                                                                          targetMethod.OwningType.GetRuntimeTypeHandle(),
                                                                          interfaceSlot);
                    Debug.Assert(methodAddress != IntPtr.Zero); // TODO! This should happen for ICastable dispatch...
                    return(true);
                }
                else
                {
                    unsafe
                    {
                        int     vtableSlotIndex = LazyVTableResolver.VirtualMethodToSlotIndex(targetMethod);
                        EEType *eeType          = instanceType.GetRuntimeTypeHandle().ToEETypePtr();
                        IntPtr *vtableStart     = (IntPtr *)(((byte *)eeType) + sizeof(EEType));

                        methodAddress = vtableStart[vtableSlotIndex];
                        return(true);
                    }
                }
            }

            MethodDesc targetVirtualMethod = targetMethod;
            DefType    instanceDefType     = instanceType.GetClosestDefType();

            // For interface resolution, its a two step process, first get the virtual slot
            if (targetVirtualMethod.OwningType.IsInterface)
            {
                TypeDesc   instanceDefTypeToExamine;
                MethodDesc newlyFoundVirtualMethod = ResolveInterfaceMethodToVirtualMethod(instanceType, out instanceDefTypeToExamine, targetVirtualMethod);

                targetVirtualMethod = newlyFoundVirtualMethod;

                // The pregenerated type must be the one that implements the interface method
                // Call into Redhawk to deal with this.
                if ((newlyFoundVirtualMethod == null) && (instanceDefTypeToExamine != null))
                {
                    ushort interfaceSlot;
                    if (!TryGetInterfaceSlotNumberFromMethod(targetMethod, out interfaceSlot))
                    {
                        return(false);
                    }
                    methodAddress = RuntimeAugments.ResolveDispatchOnType(instanceDefTypeToExamine.GetRuntimeTypeHandle(),
                                                                          targetMethod.OwningType.GetRuntimeTypeHandle(),
                                                                          interfaceSlot);

                    Debug.Assert(methodAddress != IntPtr.Zero); // TODO! This should happen for ICastable dispatch...
                    return(true);
                }
            }

            // VirtualSlot can be null if the interface method isn't really implemented. This should never happen, but since our
            // type loader doesn't check all interface overloads at load time, it could happen
            if (targetVirtualMethod == null)
            {
                return(false);
            }

            // Resolve virtual method to exact method
            MethodDesc dispatchMethod = instanceDefType.FindVirtualFunctionTargetMethodOnObjectType(targetVirtualMethod);

            return(TryGetVTableCallableAddress(dispatchMethod, out methodAddress));
        }
Beispiel #2
0
            private static unsafe IntPtr ResolveCallOnValueType(IntPtr unused, IntPtr callDescIntPtr)
#endif
            {
                NonGenericConstrainedCallDesc *callDesc = (NonGenericConstrainedCallDesc *)callDescIntPtr;
                IntPtr exactTarget        = IntPtr.Zero;
                IntPtr targetOnTypeVtable = RuntimeAugments.ResolveDispatchOnType(callDesc->_constraintType, callDesc->_constrainedMethodType, callDesc->_constrainedMethodSlot);
                bool   decodeUnboxing     = true;

                if (!RuntimeAugments.IsInterface(callDesc->_constrainedMethodType))
                {
                    // Non-interface constrained call on a valuetype to a method that isn't GetHashCode/Equals/ToString?!?!
                    if (callDesc->_constrainedMethodSlot > s_MaxObjectVTableSlot)
                    {
                        throw new NotSupportedException();
                    }

                    RuntimeTypeHandle baseTypeHandle;
                    bool gotBaseType = RuntimeAugments.TryGetBaseType(callDesc->_constraintType, out baseTypeHandle);
                    Debug.Assert(gotBaseType);
                    if (targetOnTypeVtable == RuntimeAugments.ResolveDispatchOnType(baseTypeHandle, callDesc->_constrainedMethodType, callDesc->_constrainedMethodSlot))
                    {
                        // In this case, the valuetype does not override the base types implementation of ToString(), GetHashCode(), or Equals(object)
                        decodeUnboxing = false;
                    }
                }

                if (decodeUnboxing)
                {
                    exactTarget = TypeLoaderEnvironment.ConvertUnboxingFunctionPointerToUnderlyingNonUnboxingPointer(targetOnTypeVtable, callDesc->_constraintType);
                }
                else
                {
                    // Create a fat function pointer, where the instantiation argument is ConstraintType, and the target is BoxAndToString, BoxAndGetHashCode, or BoxAndEquals
                    IntPtr realTarget;

                    switch (callDesc->_constrainedMethodSlot)
                    {
                    case s_ToStringSlot:
                        realTarget = s_boxAndToStringFuncPtr;
                        break;

                    case s_GetHashCodeSlot:
                        realTarget = s_boxAndGetHashCodeFuncPtr;
                        break;

                    case s_EqualsSlot:
                        realTarget = s_boxAndEqualsFuncPtr;
                        break;

                    default:
                        throw new NotSupportedException();
                    }

                    exactTarget = FunctionPointerOps.GetGenericMethodFunctionPointer(realTarget, callDesc->_constraintType.ToIntPtr());
                }

                // Ensure that all threads will have their function pointers completely published before updating callDesc.
                // as the ExactTarget is read from callDesc by binder generated code without a barrier, we need a barrier here
                // to ensure that the new function pointer data is valid on all threads
                Interlocked.MemoryBarrier();

                // Its possible for multiple threads to race to set exact target. Check to see we always set the same value
                if (callDesc->_exactTarget != IntPtr.Zero)
                {
                    Debug.Assert(callDesc->_exactTarget == exactTarget);
                }

                callDesc->_exactTarget = exactTarget;
                return(exactTarget);
            }
        protected sealed override Object GetFieldBypassCctor()
        {
            IntPtr fieldAddress = RuntimeAugments.GetThreadStaticFieldAddress(DeclaringTypeHandle, ThreadStaticsBlockOffset, FieldOffset);

            return(RuntimeAugments.LoadReferenceTypeField(fieldAddress));
        }
Beispiel #4
0
        //
        // Lazily parse the method signature, and construct the call converter data
        //
        private void EnsureCallConversionInfoLoaded()
        {
            if (_signatureParsed)
            {
                return;
            }

            lock (this)
            {
                // Check if race was won by another thread and the signature got parsed
                if (_signatureParsed)
                {
                    return;
                }

                TypeSystemContext context = TypeSystemContextFactory.Create();
                {
                    NativeLayoutInfoLoadContext nativeLayoutContext = new NativeLayoutInfoLoadContext();

                    if (_methodSignature.IsNativeLayoutSignature)
                    {
                        nativeLayoutContext._moduleHandle = RuntimeAugments.GetModuleFromPointer(_methodSignature.NativeLayoutSignature);
                    }
                    else
                    {
                        nativeLayoutContext._moduleHandle = _methodSignature.ModuleHandle;
                    }

                    nativeLayoutContext._typeSystemContext     = context;
                    nativeLayoutContext._typeArgumentHandles   = Instantiation.Empty;
                    nativeLayoutContext._methodArgumentHandles = Instantiation.Empty;

                    if (_typeArgs != null && _typeArgs.Length > 0)
                    {
                        nativeLayoutContext._typeArgumentHandles = context.ResolveRuntimeTypeHandles(_typeArgs);
                    }
                    if (_methodArgs != null && _methodArgs.Length > 0)
                    {
                        nativeLayoutContext._methodArgumentHandles = context.ResolveRuntimeTypeHandles(_methodArgs);
                    }

                    bool       hasThis;
                    TypeDesc[] parameters;
                    bool[]     paramsByRefForced;
                    if (!TypeLoaderEnvironment.Instance.GetCallingConverterDataFromMethodSignature(context, _methodSignature, nativeLayoutContext, out hasThis, out parameters, out paramsByRefForced))
                    {
                        Debug.Assert(false);
                        Environment.FailFast("Failed to get type handles for parameters in method signature");
                    }
                    Debug.Assert(parameters != null && parameters.Length >= 1);

                    bool[] byRefParameters = new bool[parameters.Length];
                    RuntimeTypeHandle[] parameterHandles = new RuntimeTypeHandle[parameters.Length];

                    for (int j = 0; j < parameters.Length; j++)
                    {
                        ByRefType parameterAsByRefType = parameters[j] as ByRefType;
                        if (parameterAsByRefType != null)
                        {
                            parameterAsByRefType.ParameterType.RetrieveRuntimeTypeHandleIfPossible();
                            parameterHandles[j] = parameterAsByRefType.ParameterType.RuntimeTypeHandle;
                            byRefParameters[j]  = true;
                        }
                        else
                        {
                            parameters[j].RetrieveRuntimeTypeHandleIfPossible();
                            parameterHandles[j] = parameters[j].RuntimeTypeHandle;
                            byRefParameters[j]  = false;
                        }

                        Debug.Assert(!parameterHandles[j].IsNull());
                    }

                    // Build thunk data
                    TypeHandle   thReturnType = new TypeHandle(CallConverterThunk.GetByRefIndicatorAtIndex(0, byRefParameters), parameterHandles[0]);
                    TypeHandle[] thParameters = null;
                    if (parameters.Length > 1)
                    {
                        thParameters = new TypeHandle[parameters.Length - 1];
                        for (int i = 1; i < parameters.Length; i++)
                        {
                            thParameters[i - 1] = new TypeHandle(CallConverterThunk.GetByRefIndicatorAtIndex(i, byRefParameters), parameterHandles[i]);
                        }
                    }

                    _argIteratorData = new ArgIteratorData(hasThis, false, thParameters, thReturnType);

                    // StandardToStandard thunks don't actually need any parameters to change their ABI
                    // so don't force any params to be adjusted
                    if (!StandardToStandardThunk)
                    {
                        _paramsByRefForced = paramsByRefForced;
                    }
                }
                TypeSystemContextFactory.Recycle(context);

                _signatureParsed = true;
            }
        }
Beispiel #5
0
        /// <summary>
        /// Register all modules which were added (Registered) to the runtime and are not already registered with the TypeLoader.
        /// </summary>
        /// <param name="moduleType">Type to assign to all new modules.</param>
        public void RegisterNewModules(ModuleType moduleType)
        {
            // prevent multiple threads from registering modules concurrently
            using (LockHolder.Hold(_moduleRegistrationLock))
            {
                // Fetch modules that have already been registered with the runtime
                int loadedModuleCount = RuntimeAugments.GetLoadedModules(null);
                TypeManagerHandle[] loadedModuleHandles = new TypeManagerHandle[loadedModuleCount];
                int loadedModuleCountUpdated            = RuntimeAugments.GetLoadedModules(loadedModuleHandles);
                Debug.Assert(loadedModuleCount == loadedModuleCountUpdated);

                LowLevelList <TypeManagerHandle> newModuleHandles = new LowLevelList <TypeManagerHandle>(loadedModuleHandles.Length);
                foreach (TypeManagerHandle moduleHandle in loadedModuleHandles)
                {
                    // Skip already registered modules.
                    int oldModuleIndex;
                    if (_loadedModuleMap.HandleToModuleIndex.TryGetValue(moduleHandle, out oldModuleIndex))
                    {
                        continue;
                    }

                    newModuleHandles.Add(moduleHandle);
                }

                // Copy existing modules to new dictionary
                int          oldModuleCount = _loadedModuleMap.Modules.Length;
                ModuleInfo[] updatedModules = new ModuleInfo[oldModuleCount + newModuleHandles.Count];
                if (oldModuleCount > 0)
                {
                    Array.Copy(_loadedModuleMap.Modules, 0, updatedModules, 0, oldModuleCount);
                }

                for (int newModuleIndex = 0; newModuleIndex < newModuleHandles.Count; newModuleIndex++)
                {
                    ModuleInfo newModuleInfo;

                    unsafe
                    {
                        byte *pBlob;
                        uint  cbBlob;

                        if (RuntimeAugments.FindBlob(newModuleHandles[newModuleIndex], (int)ReflectionMapBlob.EmbeddedMetadata, new IntPtr(&pBlob), new IntPtr(&cbBlob)))
                        {
                            newModuleInfo = new NativeFormatModuleInfo(newModuleHandles[newModuleIndex], moduleType, (IntPtr)pBlob, (int)cbBlob);
                        }
                        else
                        {
                            newModuleInfo = new ModuleInfo(newModuleHandles[newModuleIndex], moduleType);
                        }
                    }

                    updatedModules[oldModuleCount + newModuleIndex] = newModuleInfo;

                    if (_moduleRegistrationCallbacks != null)
                    {
                        _moduleRegistrationCallbacks(newModuleInfo);
                    }
                }

                // Atomically update the module map
                _loadedModuleMap = new ModuleMap(updatedModules);
            }
        }
Beispiel #6
0
 protected override bool IsValueTypeImpl()
 {
     return(RuntimeAugments.IsValueType(_typeHandle));
 }
Beispiel #7
0
        public override Type GetElementType()
        {
            if (RuntimeAugments.IsArrayType(_typeHandle) || RuntimeAugments.IsUnmanagedPointerType(_typeHandle) || RuntimeAugments.IsByRefType(_typeHandle))
            {
                return(GetRuntimeTypeInfo(RuntimeAugments.GetRelatedParameterTypeHandle(_typeHandle)));
            }

            return(null);
        }
Beispiel #8
0
        partial void BindEcmaAssemblyName(RuntimeAssemblyName refName, ref AssemblyBindResult result, ref Exception exception, ref bool foundMatch)
        {
            lock (s_ecmaLoadedAssemblies)
            {
                for (int i = 0; i < s_ecmaLoadedAssemblies.Count; i++)
                {
                    PEInfo info = s_ecmaLoadedAssemblies[i];
                    if (AssemblyNameMatches(refName, info.Name))
                    {
                        if (foundMatch)
                        {
                            exception = new AmbiguousMatchException();
                            return;
                        }

                        result.EcmaMetadataReader = info.Reader;
                        foundMatch = result.EcmaMetadataReader != null;

                        // For failed matches, we will never be able to succeed, so return now
                        if (!foundMatch)
                        {
                            return;
                        }
                    }
                }

                if (!foundMatch)
                {
                    try
                    {
                        // Not found in already loaded list, attempt to source assembly from disk
                        foreach (string filePath in FilePathsForAssembly(refName))
                        {
                            FileStream ownedFileStream = null;
                            PEReader   ownedPEReader   = null;
                            try
                            {
                                if (!RuntimeAugments.FileExists(filePath))
                                {
                                    continue;
                                }

                                try
                                {
                                    ownedFileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                                }
                                catch (System.IO.IOException)
                                {
                                    // Failure to open a file is not fundamentally an assembly load error, but it does indicate this file cannot be used
                                    continue;
                                }

                                ownedPEReader = new PEReader(ownedFileStream);
                                // FileStream ownership transferred to ownedPEReader
                                ownedFileStream = null;

                                if (!ownedPEReader.HasMetadata)
                                {
                                    continue;
                                }

                                MetadataReader reader = ownedPEReader.GetMetadataReader();
                                // Create AssemblyName from MetadataReader
                                RuntimeAssemblyName runtimeAssemblyName = reader.GetAssemblyDefinition().ToRuntimeAssemblyName(reader).CanonicalizePublicKeyToken();

                                // If assembly name doesn't match, it isn't the one we're looking for. Continue to look for more assemblies
                                if (!AssemblyNameMatches(refName, runtimeAssemblyName))
                                {
                                    continue;
                                }

                                // This is the one we are looking for, add it to the list of loaded assemblies
                                PEInfo peinfo = new PEInfo(runtimeAssemblyName, reader, ownedPEReader);

                                s_ecmaLoadedAssemblies.Add(peinfo);

                                // At this point the PE reader is no longer owned by this code, but is owned by the s_ecmaLoadedAssemblies list
                                PEReader pe = ownedPEReader;
                                ownedPEReader = null;

                                ModuleList moduleList    = ModuleList.Instance;
                                ModuleInfo newModuleInfo = new EcmaModuleInfo(moduleList.SystemModule.Handle, pe, reader);
                                moduleList.RegisterModule(newModuleInfo);

                                foundMatch = true;
                                result.EcmaMetadataReader = peinfo.Reader;
                                break;
                            }
                            finally
                            {
                                if (ownedFileStream != null)
                                {
                                    ownedFileStream.Dispose();
                                }

                                if (ownedPEReader != null)
                                {
                                    ownedPEReader.Dispose();
                                }
                            }
                        }
                    }
                    catch (System.IO.IOException)
                    { }
                    catch (System.ArgumentException)
                    { }
                    catch (System.BadImageFormatException badImageFormat)
                    {
                        exception = badImageFormat;
                    }

                    // Cache missed lookups
                    if (!foundMatch)
                    {
                        PEInfo peinfo = new PEInfo(refName, null, null);
                        s_ecmaLoadedAssemblies.Add(peinfo);
                    }
                }
            }
        }
Beispiel #9
0
 protected sealed override Object UncheckedGetField(Object obj)
 {
     return(RuntimeAugments.LoadReferenceTypeField(obj, _offset));
 }
Beispiel #10
0
        public unsafe static IntPtr AllocateThunk(IntPtr commonStubAddress)
        {
            lock (s_Lock)
            {
                LowLevelList <ThunksTemplateMap> mappings;
                if (!s_ThunkMaps.TryGetValue(commonStubAddress, out mappings))
                {
                    s_ThunkMaps[commonStubAddress] = mappings = new LowLevelList <ThunksTemplateMap>();
                }

                IntPtr thunkStub = GetThunkFromAllocatedPool(mappings, commonStubAddress);

                if (thunkStub == IntPtr.Zero)
                {
                    // No available thunks, so we need a new mapping of the thunks template page

                    IntPtr thunkBase = AsmCode.GetThunksBase();
                    Debug.Assert(thunkBase != IntPtr.Zero);

                    IntPtr moduleHandle = RuntimeAugments.GetModuleFromTypeHandle(typeof(ThunkPool).TypeHandle);
                    Debug.Assert(moduleHandle != IntPtr.Zero);

                    int templateRva = (int)((long)thunkBase - (long)moduleHandle);
                    Debug.Assert(templateRva % ALLOCATION_GRANULARITY == 0);

                    IntPtr thunkMap = IntPtr.Zero;
                    if (s_ThunksTemplate == IntPtr.Zero)
                    {
                        // First, we use the thunks directly from the thunks template sections in the module until all
                        // thunks in that template are used up.
                        thunkMap         = moduleHandle + templateRva;
                        s_ThunksTemplate = thunkMap;
                    }
                    else
                    {
                        // We've already used the thunks tempate in the module for some previous thunks, and we
                        // cannot reuse it here. Now we need to create a new mapping of the thunks section in order to have
                        // more thunks
                        thunkMap = RuntimeImports.RhAllocateThunksFromTemplate(moduleHandle, templateRva, NUM_THUNK_BLOCKS * PAGE_SIZE * 2);

                        if (thunkMap == IntPtr.Zero)
                        {
                            // We either ran out of memory and can't do anymore mappings of the thunks templates sections,
                            // or we are using the managed runtime services fallback, which doesn't provide the
                            // file mapping feature (ex: older version of mrt100.dll, or no mrt100.dll at all).

                            // The only option is for the caller to attempt and recycle unused thunks to be able to
                            // find some free entries.
                            return(IntPtr.Zero);
                        }
                    }
                    Debug.Assert(thunkMap != IntPtr.Zero && (long)thunkMap % ALLOCATION_GRANULARITY == 0);

                    // Each mapping consists of multiple blocks of thunk stubs/data pairs. Keep track of those
                    // so that we do not create a new mapping until all blocks in the sections we just mapped are consumed
                    for (int i = 0; i < NUM_THUNK_BLOCKS; i++)
                    {
                        s_RecentlyMappedThunksBlock[i] = thunkMap + (PAGE_SIZE * i * 2);
                    }
                    s_RecentlyMappedThunksBlockIndex = 1;

                    thunkStub = AllocateThunksTemplateMapFromMapping(thunkMap, commonStubAddress, mappings);
                }

                return(SetThumbBit(thunkStub));
            }
        }
Beispiel #11
0
 // Eager initialization called from LibraryInitializer for the assembly.
 internal static void Initialize()
 {
     Instance = new TypeLoaderEnvironment();
     RuntimeAugments.InitializeLookups(new Callbacks());
     NoStaticsData = (IntPtr)1;
 }
Beispiel #12
0
        /// <summary>
        /// Locate and lazily load debug info for the native app module overlapping given
        /// virtual address.
        /// </summary>
        /// <param name="ip">Instruction pointer address (code address for the lookup)</param>
        /// <param name="rva">Output VA relative to module base</param>
        private static IDiaSession GetDiaSession(IntPtr ip, out int rva)
        {
            if (ip == IntPtr.Zero)
            {
                rva = -1;
                return(null);
            }

            IntPtr moduleBase = RuntimeAugments.GetModuleFromPointer(ip);

            if (moduleBase == IntPtr.Zero)
            {
                rva = -1;
                return(null);
            }

            rva = (int)(ip.ToInt64() - moduleBase.ToInt64());

            if (s_loadedModules == null)
            {
                // Lazily create the parallel arrays s_loadedModules and s_perModuleDebugInfo
                int moduleCount = RuntimeAugments.GetLoadedModules(null);

                s_loadedModules      = new IntPtr[moduleCount];
                s_perModuleDebugInfo = new IDiaSession[moduleCount];

                // Actually read the module addresses into the array
                RuntimeAugments.GetLoadedModules(s_loadedModules);
            }

            // Locate module index based on base address
            int moduleIndex = s_loadedModules.Length;

            do
            {
                if (--moduleIndex < 0)
                {
                    return(null);
                }
            }while(s_loadedModules[moduleIndex] != moduleBase);

            IDiaSession diaSession = s_perModuleDebugInfo[moduleIndex];

            if (diaSession != null)
            {
                return(diaSession);
            }

            string modulePath = RuntimeAugments.TryGetFullPathToApplicationModule(moduleBase);

            if (modulePath == null)
            {
                return(null);
            }

            int indexOfLastDot = modulePath.LastIndexOf('.');

            if (indexOfLastDot == -1)
            {
                return(null);
            }

            IDiaDataSource diaDataSource = GetDiaDataSource();

            if (diaDataSource == null)
            {
                return(null);
            }

            // Look for .pdb next to .exe / dll - if it's not there, bail.
            String pdbPath = modulePath.Substring(0, indexOfLastDot) + ".pdb";
            int    hr      = diaDataSource.LoadDataFromPdb(pdbPath);

            if (hr != S_OK)
            {
                return(null);
            }

            hr = diaDataSource.OpenSession(out diaSession);
            if (hr != S_OK)
            {
                return(null);
            }

            s_perModuleDebugInfo[moduleIndex] = diaSession;
            return(diaSession);
        }
        private unsafe bool ResolveGenericVirtualMethodTarget_Static(RuntimeTypeHandle targetTypeHandle, RuntimeTypeHandle declaringType, RuntimeTypeHandle[] genericArguments, MethodNameAndSignature callingMethodNameAndSignature, out IntPtr methodPointer, out IntPtr dictionaryPointer)
        {
            methodPointer = dictionaryPointer = IntPtr.Zero;

            // Get the open type definition of the containing type of the generic virtual method being resolved
            RuntimeTypeHandle openCallingTypeHandle = GetTypeDefinition(declaringType);

            // Get the open type definition of the current type of the object instance on which the GVM is being resolved
            RuntimeTypeHandle openTargetTypeHandle = GetTypeDefinition(targetTypeHandle);

            int hashCode = openCallingTypeHandle.GetHashCode();

            hashCode = ((hashCode << 13) ^ hashCode) ^ openTargetTypeHandle.GetHashCode();

#if GVM_RESOLUTION_TRACE
            Debug.WriteLine("GVM Target Resolution = " + GetTypeNameDebug(targetTypeHandle) + "." + callingMethodNameAndSignature.Name);
#endif

            foreach (NativeFormatModuleInfo module in ModuleList.EnumerateModules(RuntimeAugments.GetModuleFromTypeHandle(openTargetTypeHandle)))
            {
                NativeReader gvmTableReader;
                if (!TryGetNativeReaderForBlob(module, ReflectionMapBlob.GenericVirtualMethodTable, out gvmTableReader))
                {
                    continue;
                }

                NativeReader nativeLayoutReader;
                if (!TryGetNativeReaderForBlob(module, ReflectionMapBlob.NativeLayoutInfo, out nativeLayoutReader))
                {
                    continue;
                }

                NativeParser            gvmTableParser = new NativeParser(gvmTableReader, 0);
                NativeHashtable         gvmHashtable   = new NativeHashtable(gvmTableParser);
                ExternalReferencesTable extRefs        = default(ExternalReferencesTable);
                extRefs.InitializeCommonFixupsTable(module);

                var lookup = gvmHashtable.Lookup(hashCode);

                NativeParser entryParser;
                while (!(entryParser = lookup.GetNext()).IsNull)
                {
                    RuntimeTypeHandle parsedCallingTypeHandle = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());
                    if (!parsedCallingTypeHandle.Equals(openCallingTypeHandle))
                    {
                        continue;
                    }

                    RuntimeTypeHandle parsedTargetTypeHandle = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());
                    if (!parsedTargetTypeHandle.Equals(openTargetTypeHandle))
                    {
                        continue;
                    }

                    uint parsedCallingNameAndSigToken = entryParser.GetUnsigned();
                    MethodNameAndSignature parsedCallingNameAndSignature = GetMethodNameAndSignatureFromNativeReader(nativeLayoutReader, module.Handle, parsedCallingNameAndSigToken);

                    if (!parsedCallingNameAndSignature.Equals(callingMethodNameAndSignature))
                    {
                        continue;
                    }

                    uint parsedTargetMethodNameAndSigToken = entryParser.GetUnsigned();
                    MethodNameAndSignature targetMethodNameAndSignature = GetMethodNameAndSignatureFromNativeReader(nativeLayoutReader, module.Handle, parsedTargetMethodNameAndSigToken);

                    Debug.Assert(targetMethodNameAndSignature != null);

                    if (!TryGetGenericVirtualMethodPointer(targetTypeHandle, targetMethodNameAndSignature, genericArguments, out methodPointer, out dictionaryPointer))
                    {
                        var sb = new System.Text.StringBuilder();
                        sb.AppendLine("Generic virtual method pointer lookup failure.");
                        sb.AppendLine();
                        sb.AppendLine("Declaring type handle: " + declaringType.LowLevelToStringRawEETypeAddress());
                        sb.AppendLine("Target type handle: " + targetTypeHandle.LowLevelToStringRawEETypeAddress());
                        sb.AppendLine("Method name: " + targetMethodNameAndSignature.Name);
                        sb.AppendLine("Instantiation:");
                        for (int i = 0; i < genericArguments.Length; i++)
                        {
                            sb.AppendLine("  Argument " + i.LowLevelToString() + ": " + genericArguments[i].LowLevelToStringRawEETypeAddress());
                        }

                        Environment.FailFast(sb.ToString());
                    }

                    return(true);
                }
            }

            return(false);
        }
Beispiel #14
0
        public static object CreateInstance(
            [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
            Type type, BindingFlags bindingAttr, Binder binder, object?[]?args, CultureInfo?culture, object?[]?activationAttributes)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            // If they didn't specify a lookup, then we will provide the default lookup.
            const BindingFlags LookupMask = (BindingFlags)0x000000FF;

            if ((bindingAttr & LookupMask) == 0)
            {
                bindingAttr |= BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance;
            }

            if (activationAttributes != null && activationAttributes.Length > 0)
            {
                throw new PlatformNotSupportedException(SR.NotSupported_ActivAttr);
            }

            type = type.UnderlyingSystemType;
            CreateInstanceCheckType(type);

            args ??= Array.Empty <object>();
            int numArgs = args.Length;

            Type?[] argTypes = new Type[numArgs];
            for (int i = 0; i < numArgs; i++)
            {
                argTypes[i] = args[i]?.GetType();
            }

            ConstructorInfo[]        candidates = type.GetConstructors(bindingAttr);
            ListBuilder <MethodBase> matches    = new ListBuilder <MethodBase>(candidates.Length);

            for (int i = 0; i < candidates.Length; i++)
            {
                if (candidates[i].QualifiesBasedOnParameterCount(bindingAttr, CallingConventions.Any, argTypes))
                {
                    matches.Add(candidates[i]);
                }
            }
            if (matches.Count == 0)
            {
                if (numArgs == 0 && type.IsValueType)
                {
                    return(RuntimeAugments.NewObject(type.TypeHandle));
                }

                throw new MissingMethodException(SR.Format(SR.Arg_NoDefCTor, type));
            }

            binder ??= Type.DefaultBinder;

            MethodBase invokeMethod = binder.BindToMethod(bindingAttr, matches.ToArray(), ref args, null, culture, null, out object?state);

            if (invokeMethod.GetParametersNoCopy().Length == 0)
            {
                if (args.Length != 0)
                {
                    Debug.Assert((invokeMethod.CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs);
                    throw new NotSupportedException(SR.NotSupported_CallToVarArg);
                }

                // Desktop compat: CoreClr invokes a "fast-path" here (call Activator.CreateInstance(type, true)) that also
                // bypasses the binder.ReorderArgumentArray() call. That "fast-path" isn't a fast-path for us so we won't do that
                // but we'll still null out the "state" variable to bypass the Reorder call.
                //
                // The only time this matters at all is if (1) a third party binder is being used and (2) it actually reordered the array
                // which it shouldn't have done because (a) we didn't request it to bind arguments by name, and (b) it's kinda hard to
                // reorder a zero-length args array. But who knows what a third party binder will do if we make a call to it that we didn't
                // used to do, so we'll preserve the CoreClr order of calls just to be safe.
                state = null;
            }

            object result = ((ConstructorInfo)invokeMethod).Invoke(bindingAttr, binder, args, culture);

            System.Diagnostics.DebugAnnotations.PreviousCallContainsDebuggerStepInCode();
            if (state != null)
            {
                binder.ReorderArgumentArray(ref args, state);
            }
            return(result);
        }
Beispiel #15
0
 protected override bool IsPointerImpl()
 {
     return(RuntimeAugments.IsUnmanagedPointerType(_typeHandle));
 }
Beispiel #16
0
 protected sealed override void UncheckedSetField(Object obj, Object value)
 {
     RuntimeAugments.StoreReferenceTypeField(obj, _offset, value);
 }
Beispiel #17
0
 protected override bool IsPrimitiveImpl()
 {
     return(RuntimeAugments.IsPrimitive(_typeHandle));
 }
Beispiel #18
0
        private bool ResolveInterfaceGenericVirtualMethodSlot_Static(RuntimeTypeHandle targetTypeHandle, ref RuntimeTypeHandle declaringType, ref MethodNameAndSignature methodNameAndSignature)
        {
            // Get the open type definition of the containing type of the generic virtual method being resolved
            RuntimeTypeHandle openCallingTypeHandle = GetTypeDefinition(declaringType);

            // Get the open type definition of the current type of the object instance on which the GVM is being resolved
            RuntimeTypeHandle openTargetTypeHandle;

            RuntimeTypeHandle[] targetTypeInstantiation;
            openTargetTypeHandle = GetOpenTypeDefinition(targetTypeHandle, out targetTypeInstantiation);

#if REFLECTION_EXECUTION_TRACE
            ReflectionExecutionLogger.WriteLine("INTERFACE GVM call = " + GetTypeNameDebug(declaringType) + "." + methodNameAndSignature.Name);
#endif

            foreach (IntPtr moduleHandle in ModuleList.Enumerate(RuntimeAugments.GetModuleFromTypeHandle(openTargetTypeHandle)))
            {
                NativeReader gvmTableReader;
                if (!TryGetNativeReaderForBlob(moduleHandle, ReflectionMapBlob.InterfaceGenericVirtualMethodTable, out gvmTableReader))
                {
                    continue;
                }

                NativeReader nativeLayoutReader;
                if (!TryGetNativeReaderForBlob(moduleHandle, ReflectionMapBlob.NativeLayoutInfo, out nativeLayoutReader))
                {
                    continue;
                }

                NativeParser    gvmTableParser = new NativeParser(gvmTableReader, 0);
                NativeHashtable gvmHashtable   = new NativeHashtable(gvmTableParser);

                ExternalReferencesTable extRefs = default(ExternalReferencesTable);
                extRefs.InitializeCommonFixupsTable(moduleHandle);

                var lookup = gvmHashtable.Lookup(openCallingTypeHandle.GetHashCode());

                NativeParser entryParser;
                while (!(entryParser = lookup.GetNext()).IsNull)
                {
                    RuntimeTypeHandle interfaceTypeHandle = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());
                    if (!openCallingTypeHandle.Equals(interfaceTypeHandle))
                    {
                        continue;
                    }

                    uint nameAndSigToken = extRefs.GetRvaFromIndex(entryParser.GetUnsigned());
                    MethodNameAndSignature interfaceMethodNameAndSignature = GetMethodNameAndSignatureFromNativeReader(nativeLayoutReader, nameAndSigToken);

                    if (!interfaceMethodNameAndSignature.Equals(methodNameAndSignature))
                    {
                        continue;
                    }

                    // For each of the possible GVM slot targets for the current interface call, we will do the following:
                    //
                    //  Step 1: Scan the types that currently provide implementations for the current GVM slot target, and look
                    //          for ones that match the target object's type.
                    //
                    //  Step 2: For each type that we find in step #1, get a list of all the interfaces that the current GVM target
                    //          provides an implementation for
                    //
                    //  Step 3: For each interface in the list in step #2, parse the signature of that interface, do the generic argument
                    //          substitution (in case of a generic interface), and check if this interface signature is assignable from the
                    //          calling interface signature (from the name and sig input). if there is an exact match based on
                    //          interface type, then we've found the right slot. Otherwise, re-scan the entry again and see if some interface
                    //          type is compatible with the initial slots interface by means of variance.
                    //          This is done by calling the TypeLoaderEnvironment helper function.
                    //
                    // Example:
                    //      public interface IFoo<out T, out U>
                    //      {
                    //          string M1<V>();
                    //      }
                    //      public class Foo1<T, U> : IFoo<T, U>, IFoo<Kvp<T, string>, U>
                    //      {
                    //          string IFoo<T, U>.M1<V>() { ... }
                    //          public virtual string M1<V>() { ... }
                    //      }
                    //      public class Foo2<T, U> : Foo1<object, U>, IFoo<U, T>
                    //      {
                    //          string IFoo<U, T>.M1<V>() { ... }
                    //      }
                    //
                    //  GVM Table layout for IFoo<T, U>.M1<V>:
                    //  {
                    //      InterfaceTypeHandle = IFoo<T, U>
                    //      InterfaceMethodNameAndSignature = { "M1", SigOf(string M1) }
                    //      GVMTargetSlots[] =
                    //      {
                    //          {
                    //              TargetMethodNameAndSignature = { "M1", SigOf(M1) }
                    //              TargetTypeHandle = Foo1<T, U>
                    //              ImplementingTypes[] = {
                    //                  ImplementingTypeHandle = Foo1<T, U>
                    //                  ImplementedInterfacesSignatures[] = { SigOf(IFoo<!0, !1>) }
                    //              }
                    //          },
                    //
                    //          {
                    //              TargetMethodNameAndSignature = { "M1", SigOf(M1) }
                    //              TargetTypeHandle = Foo1<T, U>
                    //              ImplementingTypes[] = {
                    //                  ImplementingTypeHandle = Foo1<T, U>
                    //                  ImplementedInterfacesSignatures[] = { SigOf(IFoo<Kvp<!0, string>, !1>) }
                    //              }
                    //          },
                    //
                    //          {
                    //              TargetMethodNameAndSignature = { "M1", SigOf(M1) }
                    //              TargetTypeHandle = Foo2<T, U>
                    //              ImplementingTypes = {
                    //                  ImplementingTypeHandle = Foo2<T, U>
                    //                  ImplementedInterfacesSignatures[] = { SigOf(IFoo<!1, !0>) }
                    //              }
                    //          },
                    //      }
                    //  }
                    //

                    uint currentOffset = entryParser.Offset;

                    // Non-variant dispatch of a variant generic interface generic virtual method.
                    if (FindMatchingInterfaceSlot(moduleHandle, nativeLayoutReader, ref entryParser, ref extRefs, ref declaringType, ref methodNameAndSignature, openTargetTypeHandle, targetTypeInstantiation, false))
                    {
                        return(true);
                    }

                    entryParser.Offset = currentOffset;

                    // Variant dispatch of a variant generic interface generic virtual method.
                    if (FindMatchingInterfaceSlot(moduleHandle, nativeLayoutReader, ref entryParser, ref extRefs, ref declaringType, ref methodNameAndSignature, openTargetTypeHandle, targetTypeInstantiation, true))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Beispiel #19
0
 public override string ToString()
 {
     return(RuntimeAugments.GetLastResortString(_typeHandle));
 }
Beispiel #20
0
        private unsafe bool ResolveGenericVirtualMethodTarget_Static(RuntimeTypeHandle targetTypeHandle, RuntimeTypeHandle declaringType, RuntimeTypeHandle[] genericArguments, MethodNameAndSignature callingMethodNameAndSignature, out IntPtr methodPointer, out IntPtr dictionaryPointer)
        {
            methodPointer = dictionaryPointer = IntPtr.Zero;

            // Get the open type definition of the containing type of the generic virtual method being resolved
            RuntimeTypeHandle openCallingTypeHandle = GetTypeDefinition(declaringType);

            // Get the open type definition of the current type of the object instance on which the GVM is being resolved
            RuntimeTypeHandle openTargetTypeHandle = GetTypeDefinition(targetTypeHandle);

            int hashCode = openCallingTypeHandle.GetHashCode();

            hashCode = ((hashCode << 13) ^ hashCode) ^ openTargetTypeHandle.GetHashCode();

#if REFLECTION_EXECUTION_TRACE
            ReflectionExecutionLogger.WriteLine("GVM Target Resolution = " + GetTypeNameDebug(targetTypeHandle) + "." + callingMethodNameAndSignature.Name);
#endif

            foreach (IntPtr moduleHandle in ModuleList.Enumerate(RuntimeAugments.GetModuleFromTypeHandle(openTargetTypeHandle)))
            {
                NativeReader gvmTableReader;
                if (!TryGetNativeReaderForBlob(moduleHandle, ReflectionMapBlob.GenericVirtualMethodTable, out gvmTableReader))
                {
                    continue;
                }

                NativeReader nativeLayoutReader;
                if (!TryGetNativeReaderForBlob(moduleHandle, ReflectionMapBlob.NativeLayoutInfo, out nativeLayoutReader))
                {
                    continue;
                }

                NativeParser            gvmTableParser = new NativeParser(gvmTableReader, 0);
                NativeHashtable         gvmHashtable   = new NativeHashtable(gvmTableParser);
                ExternalReferencesTable extRefs        = default(ExternalReferencesTable);
                extRefs.InitializeCommonFixupsTable(moduleHandle);

                var lookup = gvmHashtable.Lookup(hashCode);

                NativeParser entryParser;
                while (!(entryParser = lookup.GetNext()).IsNull)
                {
                    RuntimeTypeHandle parsedCallingTypeHandle = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());
                    if (!parsedCallingTypeHandle.Equals(openCallingTypeHandle))
                    {
                        continue;
                    }

                    RuntimeTypeHandle parsedTargetTypeHandle = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());
                    if (!parsedTargetTypeHandle.Equals(openTargetTypeHandle))
                    {
                        continue;
                    }

                    uint parsedCallingNameAndSigToken = extRefs.GetRvaFromIndex(entryParser.GetUnsigned());
                    MethodNameAndSignature parsedCallingNameAndSignature = GetMethodNameAndSignatureFromNativeReader(nativeLayoutReader, parsedCallingNameAndSigToken);

                    if (!parsedCallingNameAndSignature.Equals(callingMethodNameAndSignature))
                    {
                        continue;
                    }

                    uint parsedTargetMethodNameAndSigToken = extRefs.GetRvaFromIndex(entryParser.GetUnsigned());
                    MethodNameAndSignature targetMethodNameAndSignature = GetMethodNameAndSignatureFromNativeReader(nativeLayoutReader, parsedTargetMethodNameAndSigToken);

                    Debug.Assert(targetMethodNameAndSignature != null);

                    return(TryGetGenericVirtualMethodPointer(targetTypeHandle, targetMethodNameAndSignature, genericArguments, out methodPointer, out dictionaryPointer));
                }
            }

            return(false);
        }
        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 EEType 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());
        }
Beispiel #22
0
        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);
        }
Beispiel #23
0
        /// <summary>
        /// Register initially (eagerly) loaded modules.
        /// </summary>
        internal ModuleList()
        {
            _loadedModuleMap             = new ModuleMap(new ModuleInfo[0]);
            _moduleRegistrationCallbacks = default(Action <ModuleInfo>);
            _moduleRegistrationLock      = new Lock();

            RegisterNewModules(ModuleType.Eager);

            TypeManagerHandle systemObjectModule = RuntimeAugments.GetModuleFromTypeHandle(RuntimeAugments.RuntimeTypeHandleOf <object>());

            foreach (ModuleInfo m in _loadedModuleMap.Modules)
            {
                if (m.Handle == systemObjectModule)
                {
                    _systemModule = m;
                    break;
                }
            }
        }
Beispiel #24
0
 protected override bool HasElementTypeImpl()
 {
     return(RuntimeAugments.IsArrayType(_typeHandle) || RuntimeAugments.IsUnmanagedPointerType(_typeHandle) || RuntimeAugments.IsByRefType(_typeHandle));
 }
Beispiel #25
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);
                }
            }
Beispiel #26
0
 protected override bool IsArrayImpl()
 {
     return(RuntimeAugments.IsArrayType(_typeHandle));
 }
Beispiel #27
0
 /// <summary>
 /// Eager startup initialization of stack trace metadata support creates
 /// the per-module method name resolver hashtable and registers the runtime augment
 /// for metadata-based stack trace resolution.
 /// </summary>
 internal static void Initialize()
 {
     _perModuleMethodNameResolverHashtable = new PerModuleMethodNameResolverHashtable();
     RuntimeAugments.InitializeStackTraceMetadataSupport(new StackTraceMetadataCallbacksImpl());
 }
Beispiel #28
0
 protected override bool IsByRefImpl()
 {
     return(RuntimeAugments.IsByRefType(_typeHandle));
 }
        protected sealed override void UncheckedSetFieldBypassCctor(Object value)
        {
            IntPtr fieldAddress = RuntimeAugments.GetThreadStaticFieldAddress(DeclaringTypeHandle, ThreadStaticsBlockOffset, FieldOffset);

            RuntimeAugments.StoreReferenceTypeField(fieldAddress, value);
        }
 public static bool TryGetPointerTypeTargetType(RuntimeTypeHandle pointerTypeHandle, out RuntimeTypeHandle targetTypeHandle)
 {
     targetTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(pointerTypeHandle);
     return(true);
 }