/// <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; }
// // 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 }
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)); }
// // 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 }
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); }
/// <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; }
public TypeDesc TryGetNonUniversalTypeTemplate(TypeDesc concreteType, ref NativeLayoutInfo nativeLayoutInfo) { return(TryGetTypeTemplate_Internal(concreteType, CanonicalFormKind.Specific, out nativeLayoutInfo.Module, out nativeLayoutInfo.Offset)); }
// 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); }
public TypeDesc TryGetNonUniversalTypeTemplate(TypeDesc concreteType, ref NativeLayoutInfo nativeLayoutInfo) { return TryGetTypeTemplate_Internal(concreteType, CanonicalFormKind.Specific, out nativeLayoutInfo.Module, out nativeLayoutInfo.Token); }
public TypeDesc TryGetUniversalTypeTemplate(TypeDesc concreteType, ref NativeLayoutInfo nativeLayoutInfo) { return(TryGetTypeTemplate_Internal(concreteType, CanonicalFormKind.Universal, out nativeLayoutInfo.Module, out nativeLayoutInfo.Token)); }