예제 #1
0
        /// <summary>
        /// Initialize the Reader and LoadContext fields of the native layout info
        /// </summary>
        /// <param name="type"></param>
        /// <param name="nativeLayoutInfo"></param>
        private static void FinishInitNativeLayoutInfo(TypeDesc type, ref NativeLayoutInfo nativeLayoutInfo)
        {
            var nativeLayoutInfoLoadContext = new NativeLayoutInfoLoadContext();

            nativeLayoutInfoLoadContext._typeSystemContext = type.Context;
            nativeLayoutInfoLoadContext._module            = nativeLayoutInfo.Module;

            if (type is DefType)
            {
                nativeLayoutInfoLoadContext._typeArgumentHandles = ((DefType)type).Instantiation;
            }
            else if (type is ArrayType)
            {
                nativeLayoutInfoLoadContext._typeArgumentHandles = new Instantiation(new TypeDesc[] { ((ArrayType)type).ElementType });
            }
            else
            {
                Debug.Assert(false);
            }

            nativeLayoutInfoLoadContext._methodArgumentHandles = new Instantiation(null);

            nativeLayoutInfo.Reader      = TypeLoaderEnvironment.Instance.GetNativeLayoutInfoReader(nativeLayoutInfo.Module.Handle);
            nativeLayoutInfo.LoadContext = nativeLayoutInfoLoadContext;
        }
예제 #2
0
        //
        // Returns the template type handle for a generic instantiation type
        //
        public static TypeDesc TryGetTypeTemplate(TypeDesc concreteType, ref NativeLayoutInfo nativeLayoutInfo)
        {
#if GENERICS_FORCE_USG
            return(TryGetUniversalTypeTemplate(concreteType, ref nativeLayoutInfo));
#else
            // First, see if there is a specific canonical template
            TypeDesc result = TryGetTypeTemplate_Internal(concreteType, CanonicalFormKind.Specific, out nativeLayoutInfo.Module, out nativeLayoutInfo.Offset);

            // If not found, see if there's a universal canonical template
            result ??= TryGetUniversalTypeTemplate(concreteType, ref nativeLayoutInfo);

            return(result);
#endif
        }
예제 #3
0
        public NativeParser GetParserForUniversalNativeLayoutInfo(out NativeLayoutInfoLoadContext universalLayoutLoadContext, out NativeLayoutInfo universalLayoutInfo)
        {
            universalLayoutInfo        = new NativeLayoutInfo();
            universalLayoutLoadContext = null;
            TypeDesc universalTemplate = TypeBeingBuilt.Context.TemplateLookup.TryGetUniversalTypeTemplate(TypeBeingBuilt, ref universalLayoutInfo);

            if (universalTemplate == null)
            {
                return(new NativeParser());
            }

            FinishInitNativeLayoutInfo(TypeBeingBuilt, ref universalLayoutInfo);
            universalLayoutLoadContext = universalLayoutInfo.LoadContext;
            return(new NativeParser(universalLayoutInfo.Reader, universalLayoutInfo.Offset));
        }
예제 #4
0
        //
        // Returns the template type handle for a generic instantation type
        //
        public TypeDesc TryGetTypeTemplate(TypeDesc concreteType, ref NativeLayoutInfo nativeLayoutInfo)
        {
#if GENERICS_FORCE_USG
            return TryGetUniversalTypeTemplate(concreteType, ref nativeLayoutInfo);
#else
            // First, see if there is a specific canonical template
            TypeDesc result = TryGetTypeTemplate_Internal(concreteType, CanonicalFormKind.Specific, out nativeLayoutInfo.Module, out nativeLayoutInfo.Token);

            // If not found, see if there's a universal canonical template
            if (result == null)
                result = TryGetUniversalTypeTemplate(concreteType, ref nativeLayoutInfo);

            return result;
#endif
        }
예제 #5
0
        public NativeParser GetParserForUniversalNativeLayoutInfo(out NativeLayoutInfoLoadContext universalLayoutLoadContext)
        {
            NativeLayoutInfo universalLayoutInfo = new NativeLayoutInfo();
            universalLayoutLoadContext = null;
            TypeDesc universalTemplate = TypeBeingBuilt.Context.TemplateLookup.TryGetUniversalTypeTemplate(TypeBeingBuilt, ref universalLayoutInfo);
            if (universalTemplate == null)
                return new NativeParser();

            FinishInitNativeLayoutInfo(TypeBeingBuilt, ref universalLayoutInfo);
            universalLayoutLoadContext = universalLayoutInfo.LoadContext;
            return new NativeParser(universalLayoutInfo.Reader, universalLayoutInfo.Token);
        }
예제 #6
0
        /// <summary>
        /// Initialize the Reader and LoadContext fields of the native layout info
        /// </summary>
        /// <param name="type"></param>
        /// <param name="nativeLayoutInfo"></param>
        private static void FinishInitNativeLayoutInfo(TypeDesc type, ref NativeLayoutInfo nativeLayoutInfo)
        {
            var nativeLayoutInfoLoadContext = new NativeLayoutInfoLoadContext();

            nativeLayoutInfoLoadContext._typeSystemContext = type.Context;
            nativeLayoutInfoLoadContext._moduleHandle = nativeLayoutInfo.Module;

            if (type is DefType)
            {
                nativeLayoutInfoLoadContext._typeArgumentHandles = ((DefType)type).Instantiation;
            }
            else if (type is ArrayType)
            {
                nativeLayoutInfoLoadContext._typeArgumentHandles = new Instantiation(new TypeDesc[] { ((ArrayType)type).ElementType });
            }
            else
            {
                Debug.Assert(false);
            }

            nativeLayoutInfoLoadContext._methodArgumentHandles = new Instantiation(null);

            nativeLayoutInfo.Reader = TypeLoaderEnvironment.Instance.GetNativeLayoutInfoReader(nativeLayoutInfo.Module);
            nativeLayoutInfo.LoadContext = nativeLayoutInfoLoadContext;
        }
예제 #7
0
 public TypeDesc TryGetNonUniversalTypeTemplate(TypeDesc concreteType, ref NativeLayoutInfo nativeLayoutInfo)
 {
     return(TryGetTypeTemplate_Internal(concreteType, CanonicalFormKind.Specific, out nativeLayoutInfo.Module, out nativeLayoutInfo.Offset));
 }
예제 #8
0
        // This method computes the method pointer and dictionary pointer for a GVM.
        // Inputs:
        //      - targetTypeHanlde: target type on which the GVM is implemented
        //      - nameAndSignature: name and signature of the GVM method
        //      - genericMethodArgumentHandles: GVM instantiation arguments
        // Outputs:
        //      - methodPointer: pointer to the GVM's implementation
        //      - dictionaryPointer: (if applicable) pointer to the dictionary to be used with the GVM call
        public bool TryGetGenericVirtualMethodPointer(RuntimeTypeHandle targetTypeHandle, MethodNameAndSignature nameAndSignature, RuntimeTypeHandle[] genericMethodArgumentHandles, out IntPtr methodPointer, out IntPtr dictionaryPointer)
        {
            methodPointer = dictionaryPointer = IntPtr.Zero;

            TypeSystemContext context = TypeSystemContextFactory.Create();

            DefType            targetType          = (DefType)context.ResolveRuntimeTypeHandle(targetTypeHandle);
            Instantiation      methodInstantiation = context.ResolveRuntimeTypeHandles(genericMethodArgumentHandles);
            InstantiatedMethod method = (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, targetType, nameAndSignature, methodInstantiation, IntPtr.Zero, false);

            if (!method.CanShareNormalGenericCode())
            {
                // First see if we can find an exact method implementation for the GVM (avoid using USG implementations if we can,
                // because USG code is much slower).
                if (TryLookupExactMethodPointerForComponents(targetTypeHandle, nameAndSignature, genericMethodArgumentHandles, out methodPointer))
                {
                    Debug.Assert(methodPointer != IntPtr.Zero);
                    TypeSystemContextFactory.Recycle(context);
                    return(true);
                }
            }

            // If we cannot find an exact method entry point, look for an equivalent template and compute the generic dictinoary
            TemplateLocator    templateLocator  = new TemplateLocator();
            NativeLayoutInfo   nativeLayoutInfo = new NativeLayoutInfo();
            InstantiatedMethod templateMethod   = templateLocator.TryGetGenericMethodTemplate(method, out nativeLayoutInfo.Module, out nativeLayoutInfo.Token);

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

            methodPointer = templateMethod.IsCanonicalMethod(CanonicalFormKind.Universal) ?
                            templateMethod.UsgFunctionPointer :
                            templateMethod.FunctionPointer;

            if (!TryLookupGenericMethodDictionaryForComponents(targetTypeHandle, nameAndSignature, genericMethodArgumentHandles, out dictionaryPointer))
            {
                using (LockHolder.Hold(_typeLoaderLock))
                {
                    // Now that we hold the lock, we may find that existing types can now find
                    // their associated RuntimeTypeHandle. Flush the type builder states as a way
                    // to force the reresolution of RuntimeTypeHandles which couldn't be found before.
                    context.FlushTypeBuilderStates();

                    if (!TypeBuilder.TryBuildGenericMethod(method, out dictionaryPointer))
                    {
                        return(false);
                    }
                }
            }

            Debug.Assert(methodPointer != IntPtr.Zero && dictionaryPointer != IntPtr.Zero);

            if (templateMethod.IsCanonicalMethod(CanonicalFormKind.Universal))
            {
                // Check if we need to wrap the method pointer into a calling convention converter thunk
                if (!TypeLoaderEnvironment.Instance.MethodSignatureHasVarsNeedingCallingConventionConverter(context, nameAndSignature.Signature))
                {
                    TypeSystemContextFactory.Recycle(context);
                    return(true);
                }

                RuntimeTypeHandle[] typeArgs = Array.Empty <RuntimeTypeHandle>();

                if (RuntimeAugments.IsGenericType(targetTypeHandle))
                {
                    RuntimeAugments.GetGenericInstantiation(targetTypeHandle, out typeArgs);
                }

                // Create a CallingConventionConverter to call the method correctly
                IntPtr thunkPtr = CallConverterThunk.MakeThunk(
                    CallConverterThunk.ThunkKind.StandardToGenericInstantiating,
                    methodPointer,
                    nameAndSignature.Signature,
                    dictionaryPointer,
                    typeArgs,
                    genericMethodArgumentHandles);

                Debug.Assert(thunkPtr != IntPtr.Zero);

                methodPointer = thunkPtr;
                // Set dictionaryPointer to null so we don't make a fat function pointer around the whole thing.
                dictionaryPointer = IntPtr.Zero;

                // TODO! add a new call converter thunk that will pass the instantiating arg through and use a fat function pointer.
                // should allow us to make fewer thunks.
            }

            TypeSystemContextFactory.Recycle(context);
            return(true);
        }
예제 #9
0
 public TypeDesc TryGetNonUniversalTypeTemplate(TypeDesc concreteType, ref NativeLayoutInfo nativeLayoutInfo)
 {
     return TryGetTypeTemplate_Internal(concreteType, CanonicalFormKind.Specific, out nativeLayoutInfo.Module, out nativeLayoutInfo.Token);
 }
예제 #10
0
 public TypeDesc TryGetUniversalTypeTemplate(TypeDesc concreteType, ref NativeLayoutInfo nativeLayoutInfo)
 {
     return(TryGetTypeTemplate_Internal(concreteType, CanonicalFormKind.Universal, out nativeLayoutInfo.Module, out nativeLayoutInfo.Token));
 }