/// <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; }
public FixupCellMetadataResolver(NativeFormatMetadataUnit metadataUnit, NativeLayoutInfoLoadContext loadContext) { _metadataUnit = metadataUnit; _methodContext = null; _typeContext = null; _loadContextFromNativeLayout = loadContext; }
internal bool GetCallingConverterDataFromMethodSignature_NativeLayout_Common( TypeSystemContext context, RuntimeSignature methodSig, Instantiation typeInstantiation, Instantiation methodInstantiation, out bool hasThis, out TypeDesc[] parameters, out bool[] parametersWithGenericDependentLayout, NativeReader nativeReader) { NativeLayoutInfoLoadContext nativeLayoutContext = new NativeLayoutInfoLoadContext(); nativeLayoutContext._module = (NativeFormatModuleInfo)methodSig.GetModuleInfo(); nativeLayoutContext._typeSystemContext = context; nativeLayoutContext._typeArgumentHandles = typeInstantiation; nativeLayoutContext._methodArgumentHandles = methodInstantiation; NativeFormatModuleInfo module = ModuleList.Instance.GetModuleInfoByHandle(new TypeManagerHandle(methodSig.ModuleHandle)); NativeReader reader = GetNativeLayoutInfoReader(methodSig); NativeParser parser = new NativeParser(reader, methodSig.NativeLayoutOffset); MethodCallingConvention callingConvention = (MethodCallingConvention)parser.GetUnsigned(); hasThis = !callingConvention.HasFlag(MethodCallingConvention.Static); if (callingConvention.HasFlag(MethodCallingConvention.Generic)) { parser.SkipInteger(); // numGenArgs } uint parameterCount = parser.GetUnsigned(); parameters = new TypeDesc[parameterCount + 1]; parametersWithGenericDependentLayout = new bool[parameterCount + 1]; // One extra parameter to account for the return type for (uint i = 0; i <= parameterCount; i++) { // NativeParser is a struct, so it can be copied. NativeParser parserCopy = parser; // Parse the signature twice. The first time to find out the exact type of the signature // The second time to identify if the parameter loaded via the signature should be forced to be // passed byref as part of the universal generic calling convention. parameters[i] = GetConstructedTypeFromParserAndNativeLayoutContext(ref parser, nativeLayoutContext); parametersWithGenericDependentLayout[i] = TypeSignatureHasVarsNeedingCallingConventionConverter(ref parserCopy, module, context, HasVarsInvestigationLevel.Parameter); if (parameters[i] == null) { return(false); } } return(true); }
private static void EnsureFieldLayoutLoadedForUniversalType(DefType type, NativeLayoutInfoLoadContext loadContext, NativeParser fieldLayoutParser) { Debug.Assert(type.HasInstantiation); Debug.Assert(type.ComputeTemplate().IsCanonicalSubtype(CanonicalFormKind.Universal)); if (type.NativeLayoutFields != null) { return; } type.NativeLayoutFields = ParseFieldLayout(type, loadContext, fieldLayoutParser); }
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)); }
private object TryParseNativeSignatureWorker(TypeSystemContext typeSystemContext, TypeManagerHandle moduleHandle, ref NativeParser parser, RuntimeTypeHandle[] typeGenericArgumentHandles, RuntimeTypeHandle[] methodGenericArgumentHandles, bool isMethodSignature) { Instantiation typeGenericArguments = typeSystemContext.ResolveRuntimeTypeHandles(typeGenericArgumentHandles ?? Array.Empty<RuntimeTypeHandle>()); Instantiation methodGenericArguments = typeSystemContext.ResolveRuntimeTypeHandles(methodGenericArgumentHandles ?? Array.Empty<RuntimeTypeHandle>()); NativeLayoutInfoLoadContext nativeLayoutContext = new NativeLayoutInfoLoadContext(); nativeLayoutContext._module = ModuleList.GetModuleInfoByHandle(moduleHandle); nativeLayoutContext._typeSystemContext = typeSystemContext; nativeLayoutContext._typeArgumentHandles = typeGenericArguments; nativeLayoutContext._methodArgumentHandles = methodGenericArguments; if (isMethodSignature) return nativeLayoutContext.GetMethod(ref parser); else return nativeLayoutContext.GetType(ref parser); }
private static NativeLayoutFieldDesc[] ParseFieldLayout(DefType owningType, NativeLayoutInfoLoadContext nativeLayoutInfoLoadContext, NativeParser fieldLayoutParser) { if (fieldLayoutParser.IsNull) { return(Empty <NativeLayoutFieldDesc> .Array); } uint numFields = fieldLayoutParser.GetUnsigned(); var fields = new NativeLayoutFieldDesc[numFields]; for (int i = 0; i < numFields; i++) { TypeDesc fieldType = nativeLayoutInfoLoadContext.GetType(ref fieldLayoutParser); NativeFormat.FieldStorage storage = (NativeFormat.FieldStorage)fieldLayoutParser.GetUnsigned(); fields[i] = new NativeLayoutFieldDesc(owningType, fieldType, storage); } return(fields); }
private RuntimeTypeHandle GetExternalTypeHandle(NativeFormatModuleInfo moduleHandle, uint typeIndex) { Debug.Assert(moduleHandle != null); RuntimeTypeHandle result; TypeSystemContext context = TypeSystemContextFactory.Create(); { NativeLayoutInfoLoadContext nativeLayoutContext = new NativeLayoutInfoLoadContext(); nativeLayoutContext._module = moduleHandle; nativeLayoutContext._typeSystemContext = context; TypeDesc type = nativeLayoutContext.GetExternalType(typeIndex); result = type.RuntimeTypeHandle; } TypeSystemContextFactory.Recycle(context); Debug.Assert(!result.IsNull()); return(result); }
private RuntimeTypeHandle GetExternalTypeHandle(ref NativeParser parser, uint typeIndex) { IntPtr moduleHandle = RuntimeAugments.GetModuleFromPointer(parser.Reader.OffsetToAddress(parser.Offset)); Debug.Assert(moduleHandle != IntPtr.Zero); RuntimeTypeHandle result; TypeSystemContext context = TypeSystemContextFactory.Create(); { NativeLayoutInfoLoadContext nativeLayoutContext = new NativeLayoutInfoLoadContext(); nativeLayoutContext._moduleHandle = moduleHandle; nativeLayoutContext._typeSystemContext = context; TypeDesc type = nativeLayoutContext.GetExternalType(typeIndex); result = type.RuntimeTypeHandle; } TypeSystemContextFactory.Recycle(context); Debug.Assert(!result.IsNull()); return(result); }
private static bool GetCallingConverterDataFromMethodSignature_MethodSignature(TypeSystem.MethodSignature methodSignature, NativeLayoutInfoLoadContext nativeLayoutContext, out bool hasThis, out TypeDesc[] parameters, out bool[] parametersWithGenericDependentLayout) { // Compute parameters dependent on generic instantiation for their layout parametersWithGenericDependentLayout = new bool[methodSignature.Length + 1]; parametersWithGenericDependentLayout[0] = TypeHasLayoutDependentOnGenericInstantiation(methodSignature.ReturnType, HasVarsInvestigationLevel.Parameter); for (int i = 0; i < methodSignature.Length; i++) { parametersWithGenericDependentLayout[i + 1] = TypeHasLayoutDependentOnGenericInstantiation(methodSignature[i], HasVarsInvestigationLevel.Parameter); } // Compute hasThis-ness hasThis = !methodSignature.IsStatic; // Compute parameter exact types parameters = new TypeDesc[methodSignature.Length + 1]; Instantiation typeInstantiation = nativeLayoutContext._typeArgumentHandles; Instantiation methodInstantiation = nativeLayoutContext._methodArgumentHandles; parameters[0] = methodSignature.ReturnType.InstantiateSignature(typeInstantiation, methodInstantiation); for (int i = 0; i < methodSignature.Length; i++) { parameters[i + 1] = methodSignature[i].InstantiateSignature(typeInstantiation, methodInstantiation); } return true; }
private RuntimeTypeHandle GetExternalTypeHandle(ref NativeParser parser, uint typeIndex) { IntPtr moduleHandle = RuntimeAugments.GetModuleFromPointer(parser.Reader.OffsetToAddress(parser.Offset)); Debug.Assert(moduleHandle != IntPtr.Zero); RuntimeTypeHandle result; TypeSystemContext context = TypeSystemContextFactory.Create(); { NativeLayoutInfoLoadContext nativeLayoutContext = new NativeLayoutInfoLoadContext(); nativeLayoutContext._moduleHandle = moduleHandle; nativeLayoutContext._typeSystemContext = context; TypeDesc type = nativeLayoutContext.GetExternalType(typeIndex); result = type.RuntimeTypeHandle; } TypeSystemContextFactory.Recycle(context); Debug.Assert(!result.IsNull()); return result; }
internal bool GetCallingConverterDataFromMethodSignature(TypeSystemContext context, RuntimeMethodSignature methodSig, NativeLayoutInfoLoadContext nativeLayoutContext, out bool hasThis, out TypeDesc[] parameters, out bool[] parametersWithGenericDependentLayout) { if (methodSig.IsNativeLayoutSignature) return GetCallingConverterDataFromMethodSignature_NativeLayout(context, methodSig.NativeLayoutSignature, nativeLayoutContext, out hasThis, out parameters, out parametersWithGenericDependentLayout); else { #if SUPPORTS_NATIVE_METADATA_TYPE_LOADING MetadataReader metadataReader = ModuleList.Instance.GetMetadataReaderForModule(methodSig.ModuleHandle); var methodHandle = methodSig.Token.AsHandle().ToMethodHandle(metadataReader); var metadataUnit = ((TypeLoaderTypeSystemContext)context).ResolveMetadataUnit(methodSig.ModuleHandle); var parser = new Internal.TypeSystem.NativeFormat.NativeFormatSignatureParser(metadataUnit, metadataReader.GetMethod(methodHandle).Signature, metadataReader); var signature = parser.ParseMethodSignature(); return GetCallingConverterDataFromMethodSignature_MethodSignature(signature, nativeLayoutContext, out hasThis, out parameters, out parametersWithGenericDependentLayout); #else parametersWithGenericDependentLayout = null; hasThis = false; parameters = null; return false; #endif } }
internal bool GetCallingConverterDataFromMethodSignature_NativeLayout(TypeSystemContext context, IntPtr methodSig, NativeLayoutInfoLoadContext nativeLayoutContext, out bool hasThis, out TypeDesc[] parameters, out bool[] parametersWithGenericDependentLayout) { hasThis = false; parameters = null; IntPtr moduleHandle = RuntimeAugments.GetModuleFromPointer(methodSig); NativeReader reader = GetNativeLayoutInfoReader(moduleHandle); NativeParser parser = new NativeParser(reader, reader.AddressToOffset(methodSig)); MethodCallingConvention callingConvention = (MethodCallingConvention)parser.GetUnsigned(); hasThis = !callingConvention.HasFlag(MethodCallingConvention.Static); uint numGenArgs = callingConvention.HasFlag(MethodCallingConvention.Generic) ? parser.GetUnsigned() : 0; uint parameterCount = parser.GetUnsigned(); parameters = new TypeDesc[parameterCount + 1]; parametersWithGenericDependentLayout = new bool[parameterCount + 1]; // One extra parameter to account for the return type for (uint i = 0; i <= parameterCount; i++) { // NativeParser is a struct, so it can be copied. NativeParser parserCopy = parser; // Parse the signature twice. The first time to find out the exact type of the signature // The second time to identify if the parameter loaded via the signature should be forced to be // passed byref as part of the universal generic calling convention. parameters[i] = GetConstructedTypeFromParserAndNativeLayoutContext(ref parser, nativeLayoutContext); parametersWithGenericDependentLayout[i] = TypeSignatureHasVarsNeedingCallingConventionConverter(ref parserCopy, context, HasVarsInvestigationLevel.Parameter); if (parameters[i] == null) return false; } return true; }
/// <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 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); }
internal TypeDesc GetConstructedTypeFromParserAndNativeLayoutContext(ref NativeParser parser, NativeLayoutInfoLoadContext nativeLayoutContext) { TypeDesc parsedType = nativeLayoutContext.GetType(ref parser); if (parsedType == null) return null; if (!EnsureTypeHandleForType(parsedType)) return null; return parsedType; }
internal override void ParseBaseType(NativeLayoutInfoLoadContext nativeLayoutInfoLoadContext, NativeParser baseTypeParser) { if (!baseTypeParser.IsNull) { // If the base type is available from the native layout info use it if the type we have is a NoMetadataType SetBaseType((DefType)nativeLayoutInfoLoadContext.GetType(ref baseTypeParser)); } else { // Set the base type for no metadata types, if we reach this point, and there isn't a parser, then we simply use the value from the template SetBaseType(ComputeTemplate().BaseType); } }
/// Parse the native layout to ensure that the type has proper base type setup. /// This is used to generalize out some behavior of NoMetadataTypes which actually use this information internal virtual void ParseBaseType(NativeLayoutInfoLoadContext nativeLayoutInfoLoadContext, NativeParser baseTypeParser) { return; }
private static void EnsureFieldLayoutLoadedForUniversalType(DefType type, NativeLayoutInfoLoadContext loadContext, NativeParser fieldLayoutParser) { Debug.Assert(type.HasInstantiation); Debug.Assert(type.ComputeTemplate().IsCanonicalSubtype(CanonicalFormKind.Universal)); if (type.NativeLayoutFields != null) return; type.NativeLayoutFields = ParseFieldLayout(type, loadContext, fieldLayoutParser); }
internal static GenericDictionaryCell ParseAndCreateCell(NativeLayoutInfoLoadContext nativeLayoutInfoLoadContext, ref NativeParser parser) { GenericDictionaryCell cell; var kind = parser.GetFixupSignatureKind(); switch (kind) { case FixupSignatureKind.TypeHandle: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("TypeHandle: " + type.ToString()); cell = new TypeHandleCell() { Type = type }; } break; case FixupSignatureKind.InterfaceCall: { var interfaceType = nativeLayoutInfoLoadContext.GetType(ref parser); var slot = parser.GetUnsigned(); TypeLoaderLogger.WriteLine("InterfaceCall: " + interfaceType.ToString() + ", slot #" + slot.LowLevelToString()); cell = new InterfaceCallCell() { InterfaceType = interfaceType, Slot = (int)slot }; } break; case FixupSignatureKind.MethodDictionary: { var genericMethod = nativeLayoutInfoLoadContext.GetMethod(ref parser); Debug.Assert(genericMethod.Instantiation.Length > 0); TypeLoaderLogger.WriteLine("MethodDictionary: " + genericMethod.ToString()); cell = new MethodDictionaryCell { GenericMethod = (InstantiatedMethod)genericMethod }; } break; case FixupSignatureKind.StaticData: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); StaticDataKind staticDataKind = (StaticDataKind)parser.GetUnsigned(); TypeLoaderLogger.WriteLine("StaticData (" + (staticDataKind == StaticDataKind.Gc ? "Gc" : "NonGc") + ": " + type.ToString()); cell = new StaticDataCell() { DataKind = staticDataKind, Type = type }; } break; case FixupSignatureKind.UnwrapNullableType: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("UnwrapNullableType of: " + type.ToString()); cell = new UnwrapNullableTypeCell() { Type = (DefType)type }; } break; case FixupSignatureKind.FieldLdToken: { NativeParser ldtokenSigParser = parser.GetParserFromRelativeOffset(); var type = nativeLayoutInfoLoadContext.GetType(ref ldtokenSigParser); IntPtr fieldNameSig = ldtokenSigParser.Reader.OffsetToAddress(ldtokenSigParser.Offset); TypeLoaderLogger.WriteLine("LdToken on: " + type.ToString() + "." + ldtokenSigParser.GetString()); cell = new FieldLdTokenCell() { FieldName = fieldNameSig, ContainingType = type }; } break; case FixupSignatureKind.MethodLdToken: { NativeParser ldtokenSigParser = parser.GetParserFromRelativeOffset(); IntPtr methodNameSigPtr; IntPtr methodSigPtr; var method = nativeLayoutInfoLoadContext.GetMethod(ref ldtokenSigParser, out methodNameSigPtr, out methodSigPtr); TypeLoaderLogger.WriteLine("LdToken on: " + method.OwningType.ToString() + "::" + method.NameAndSignature.Name); cell = new MethodLdTokenCell { Method = method, MethodName = methodNameSigPtr, MethodSignature = RuntimeMethodSignature.CreateFromNativeLayoutSignature(methodSigPtr) }; } break; case FixupSignatureKind.TypeSize: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("TypeSize: " + type.ToString()); cell = new TypeSizeCell() { Type = type }; } break; case FixupSignatureKind.FieldOffset: { var type = (DefType)nativeLayoutInfoLoadContext.GetType(ref parser); uint ordinal = parser.GetUnsigned(); TypeLoaderLogger.WriteLine("FieldOffset on: " + type.ToString()); cell = new FieldOffsetCell() { Ordinal = ordinal, ContainingType = type }; } break; case FixupSignatureKind.VTableOffset: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); var vtableSlot = parser.GetUnsigned(); TypeLoaderLogger.WriteLine("VTableOffset on: " + type.ToString() + ", slot: " + vtableSlot.LowLevelToString()); cell = new VTableOffsetCell() { ContainingType = type, VTableSlot = vtableSlot }; } break; case FixupSignatureKind.AllocateObject: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("AllocateObject on: " + type.ToString()); cell = new AllocateObjectCell { Type = type }; } break; case FixupSignatureKind.DefaultConstructor: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("DefaultConstructor on: " + type.ToString()); cell = new DefaultConstructorCell { Type = type }; } break; case FixupSignatureKind.TlsIndex: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("TlsIndex on: " + type.ToString()); cell = new TlsIndexCell { Type = type }; } break; case FixupSignatureKind.TlsOffset: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("TlsOffset on: " + type.ToString()); cell = new TlsOffsetCell { Type = type }; } break; case FixupSignatureKind.Method: { IntPtr methodSigPtr; IntPtr methodNameSigPtr; var method = nativeLayoutInfoLoadContext.GetMethod(ref parser, out methodNameSigPtr, out methodSigPtr); TypeLoaderLogger.WriteLine("Method: " + method.ToString()); cell = new MethodCell { Method = method, MethodSignature = RuntimeMethodSignature.CreateFromNativeLayoutSignature(methodSigPtr) }; } break; case FixupSignatureKind.NonGenericDirectConstrainedMethod: { var constraintType = nativeLayoutInfoLoadContext.GetType(ref parser); var constrainedMethodType = nativeLayoutInfoLoadContext.GetType(ref parser); var constrainedMethodSlot = parser.GetUnsigned(); TypeLoaderLogger.WriteLine("NonGenericDirectConstrainedMethod: " + constraintType.ToString() + " Method " + constrainedMethodType.ToString() + ", slot #" + constrainedMethodSlot.LowLevelToString()); cell = new NonGenericDirectConstrainedMethodCell() { ConstraintType = constraintType, ConstrainedMethodType = constrainedMethodType, ConstrainedMethodSlot = (int)constrainedMethodSlot }; } break; case FixupSignatureKind.NonGenericConstrainedMethod: { var constraintType = nativeLayoutInfoLoadContext.GetType(ref parser); var constrainedMethodType = nativeLayoutInfoLoadContext.GetType(ref parser); var constrainedMethodSlot = parser.GetUnsigned(); TypeLoaderLogger.WriteLine("NonGenericConstrainedMethod: " + constraintType.ToString() + " Method " + constrainedMethodType.ToString() + ", slot #" + constrainedMethodSlot.LowLevelToString()); cell = new NonGenericConstrainedMethodCell() { ConstraintType = constraintType, ConstrainedMethodType = constrainedMethodType, ConstrainedMethodSlot = (int)constrainedMethodSlot }; } break; case FixupSignatureKind.GenericConstrainedMethod: { var constraintType = nativeLayoutInfoLoadContext.GetType(ref parser); NativeParser ldtokenSigParser = parser.GetParserFromRelativeOffset(); IntPtr methodNameSigPtr; IntPtr methodSigPtr; var method = nativeLayoutInfoLoadContext.GetMethod(ref ldtokenSigParser, out methodNameSigPtr, out methodSigPtr); TypeLoaderLogger.WriteLine("GenericConstrainedMethod: " + constraintType.ToString() + " Method " + method.OwningType.ToString() + "::" + method.NameAndSignature.Name); cell = new GenericConstrainedMethodCell() { ConstraintType = constraintType, ConstrainedMethod = method, MethodName = methodNameSigPtr, MethodSignature = RuntimeMethodSignature.CreateFromNativeLayoutSignature(methodSigPtr) }; } break; case FixupSignatureKind.IsInst: case FixupSignatureKind.CastClass: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("Casting on: " + type.ToString()); cell = new CastingCell { Type = type, Throwing = (kind == FixupSignatureKind.CastClass) }; } break; case FixupSignatureKind.AllocateArray: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("AllocateArray on: " + type.ToString()); cell = new AllocateArrayCell { Type = type }; } break; case FixupSignatureKind.CheckArrayElementType: { var type = nativeLayoutInfoLoadContext.GetType(ref parser); TypeLoaderLogger.WriteLine("CheckArrayElementType on: " + type.ToString()); cell = new CheckArrayElementTypeCell { Type = type }; } break; case FixupSignatureKind.CallingConventionConverter: { NativeFormat.CallingConventionConverterKind flags = (NativeFormat.CallingConventionConverterKind)parser.GetUnsigned(); NativeParser sigParser = parser.GetParserFromRelativeOffset(); IntPtr signature = sigParser.Reader.OffsetToAddress(sigParser.Offset); #if TYPE_LOADER_TRACE TypeLoaderLogger.WriteLine("CallingConventionConverter on: "); TypeLoaderLogger.WriteLine(" -> Flags: " + ((int)flags).LowLevelToString()); TypeLoaderLogger.WriteLine(" -> Signature: " + signature.LowLevelToString()); for (int i = 0; !nativeLayoutInfoLoadContext._typeArgumentHandles.IsNull && i < nativeLayoutInfoLoadContext._typeArgumentHandles.Length; i++) TypeLoaderLogger.WriteLine(" -> TypeArg[" + i.LowLevelToString() + "]: " + nativeLayoutInfoLoadContext._typeArgumentHandles[i]); for (int i = 0; !nativeLayoutInfoLoadContext._methodArgumentHandles.IsNull && i < nativeLayoutInfoLoadContext._methodArgumentHandles.Length; i++) TypeLoaderLogger.WriteLine(" -> MethodArg[" + i.LowLevelToString() + "]: " + nativeLayoutInfoLoadContext._methodArgumentHandles[i]); #endif cell = new CallingConventionConverterCell { Flags = flags, Signature = RuntimeMethodSignature.CreateFromNativeLayoutSignature(signature), MethodArgs = nativeLayoutInfoLoadContext._methodArgumentHandles, TypeArgs = nativeLayoutInfoLoadContext._typeArgumentHandles }; } break; case FixupSignatureKind.NotYetSupported: TypeLoaderLogger.WriteLine("Valid dictionary entry, but not yet supported by the TypeLoader!"); throw new TypeBuilder.MissingTemplateException(); default: parser.ThrowBadImageFormatException(); cell = null; break; } return cell; }
internal bool GetCallingConverterDataFromMethodSignature(TypeSystemContext context, RuntimeMethodSignature methodSig, NativeLayoutInfoLoadContext nativeLayoutContext, out bool hasThis, out TypeDesc[] parameters, out bool[] parametersWithGenericDependentLayout) { if (methodSig.IsNativeLayoutSignature) { return(GetCallingConverterDataFromMethodSignature_NativeLayout(context, methodSig.NativeLayoutSignature, nativeLayoutContext, out hasThis, out parameters, out parametersWithGenericDependentLayout)); } else { #if SUPPORTS_NATIVE_METADATA_TYPE_LOADING MetadataReader metadataReader = ModuleList.Instance.GetMetadataReaderForModule(methodSig.ModuleHandle); var methodHandle = methodSig.Token.AsHandle().ToMethodHandle(metadataReader); var metadataUnit = ((TypeLoaderTypeSystemContext)context).ResolveMetadataUnit(methodSig.ModuleHandle); var parser = new Internal.TypeSystem.NativeFormat.NativeFormatSignatureParser(metadataUnit, metadataReader.GetMethod(methodHandle).Signature, metadataReader); var signature = parser.ParseMethodSignature(); return(GetCallingConverterDataFromMethodSignature_MethodSignature(signature, nativeLayoutContext, out hasThis, out parameters, out parametersWithGenericDependentLayout)); #else parametersWithGenericDependentLayout = null; hasThis = false; parameters = null; return(false); #endif } }
private static InstantiatedMethod TryGetGenericMethodTemplate_Internal(InstantiatedMethod concreteMethod, CanonicalFormKind kind, out NativeFormatModuleInfo nativeLayoutInfoModule, out uint nativeLayoutInfoToken) { nativeLayoutInfoModule = null; nativeLayoutInfoToken = 0; var canonForm = concreteMethod.GetCanonMethodTarget(kind); var hashCode = canonForm.GetHashCode(); foreach (NativeFormatModuleInfo moduleInfo in ModuleList.EnumerateModules()) { NativeReader nativeLayoutReader = TypeLoaderEnvironment.GetNativeLayoutInfoReader(moduleInfo.Handle); if (nativeLayoutReader == null) { continue; } NativeHashtable genericMethodTemplatesHashtable = LoadHashtable(moduleInfo, ReflectionMapBlob.GenericMethodsTemplateMap, out _); if (genericMethodTemplatesHashtable.IsNull) { continue; } var context = new NativeLayoutInfoLoadContext { _typeSystemContext = concreteMethod.Context, _typeArgumentHandles = concreteMethod.OwningType.Instantiation, _methodArgumentHandles = concreteMethod.Instantiation, _module = moduleInfo }; var enumerator = genericMethodTemplatesHashtable.Lookup(hashCode); NativeParser entryParser; while (!(entryParser = enumerator.GetNext()).IsNull) { var methodSignatureParser = new NativeParser(nativeLayoutReader, entryParser.GetUnsigned()); // Get the unified generic method holder and convert it to its canonical form var candidateTemplate = (InstantiatedMethod)context.GetMethod(ref methodSignatureParser); Debug.Assert(candidateTemplate.Instantiation.Length > 0); if (canonForm == candidateTemplate.GetCanonMethodTarget(kind)) { TypeLoaderLogger.WriteLine("Found template for generic method " + concreteMethod.ToString() + ": " + candidateTemplate.ToString()); nativeLayoutInfoModule = moduleInfo; nativeLayoutInfoToken = entryParser.GetUnsigned(); if (nativeLayoutInfoToken == BadTokenFixupValue) { // TODO: once multifile gets fixed up, make this throw a BadImageFormatException TypeLoaderLogger.WriteLine("ERROR: template not fixed up, skipping"); continue; } Debug.Assert( (kind != CanonicalFormKind.Universal) || (kind == CanonicalFormKind.Universal && candidateTemplate == candidateTemplate.GetCanonMethodTarget(kind))); return(candidateTemplate); } } } TypeLoaderLogger.WriteLine("ERROR: Cannot find a suitable template for generic method " + concreteMethod.ToString()); return(null); }
private TypeDesc GetConstructedTypeFromParserAndNativeLayoutContext(ref NativeParser parser, NativeLayoutInfoLoadContext nativeLayoutContext) { TypeDesc parsedType = nativeLayoutContext.GetType(ref parser); if (parsedType == null) return null; if (!EnsureTypeHandleForType(parsedType)) return null; return parsedType; }
private object TryParseNativeSignatureWorker(TypeSystemContext typeSystemContext, IntPtr moduleHandle, ref NativeParser parser, RuntimeTypeHandle[] typeGenericArgumentHandles, RuntimeTypeHandle[] methodGenericArgumentHandles, bool isMethodSignature) { Instantiation typeGenericArguments = typeSystemContext.ResolveRuntimeTypeHandles(typeGenericArgumentHandles ?? Array.Empty<RuntimeTypeHandle>()); Instantiation methodGenericArguments = typeSystemContext.ResolveRuntimeTypeHandles(methodGenericArgumentHandles ?? Array.Empty<RuntimeTypeHandle>()); NativeLayoutInfoLoadContext nativeLayoutContext = new NativeLayoutInfoLoadContext(); nativeLayoutContext._moduleHandle = moduleHandle; nativeLayoutContext._typeSystemContext = typeSystemContext; nativeLayoutContext._typeArgumentHandles = typeGenericArguments; nativeLayoutContext._methodArgumentHandles = methodGenericArguments; if (isMethodSignature) return nativeLayoutContext.GetMethod(ref parser); else return nativeLayoutContext.GetType(ref parser); }
private InstantiatedMethod TryGetGenericMethodTemplate_Internal(InstantiatedMethod concreteMethod, CanonicalFormKind kind, out IntPtr nativeLayoutInfoModule, out uint nativeLayoutInfoToken) { nativeLayoutInfoModule = default(IntPtr); nativeLayoutInfoToken = 0; var canonForm = concreteMethod.GetCanonMethodTarget(kind); var hashCode = canonForm.GetHashCode(); var loadedModulesCount = RuntimeAugments.GetLoadedModules(null); var loadedModuleHandles = new IntPtr[loadedModulesCount]; var loadedModules = RuntimeAugments.GetLoadedModules(loadedModuleHandles); Debug.Assert(loadedModulesCount == loadedModules); foreach (var moduleHandle in loadedModuleHandles) { NativeReader nativeLayoutReader = TypeLoaderEnvironment.Instance.GetNativeLayoutInfoReader(moduleHandle); if (nativeLayoutReader == null) continue; ExternalReferencesTable externalFixupsTable; NativeHashtable genericMethodTemplatesHashtable = LoadHashtable(moduleHandle, ReflectionMapBlob.GenericMethodsTemplateMap, out externalFixupsTable); if (genericMethodTemplatesHashtable.IsNull) continue; var context = new NativeLayoutInfoLoadContext { _typeSystemContext = concreteMethod.Context, _typeArgumentHandles = concreteMethod.OwningType.Instantiation, _methodArgumentHandles = concreteMethod.Instantiation, _moduleHandle = moduleHandle }; var enumerator = genericMethodTemplatesHashtable.Lookup(hashCode); NativeParser entryParser; while (!(entryParser = enumerator.GetNext()).IsNull) { var methodSignatureParser = new NativeParser(nativeLayoutReader, externalFixupsTable.GetRvaFromIndex(entryParser.GetUnsigned())); // Get the unified generic method holder and convert it to its canonical form var candidateTemplate = (InstantiatedMethod)context.GetMethod(ref methodSignatureParser); Debug.Assert(candidateTemplate.Instantiation.Length > 0); if (canonForm == candidateTemplate.GetCanonMethodTarget(kind)) { TypeLoaderLogger.WriteLine("Found template for generic method " + concreteMethod.ToString() + ": " + candidateTemplate.ToString()); nativeLayoutInfoModule = moduleHandle; nativeLayoutInfoToken = (uint)externalFixupsTable.GetRvaFromIndex(entryParser.GetUnsigned()); if (nativeLayoutInfoToken == BadTokenFixupValue) { // TODO: once multifile gets fixed up, make this throw a BadImageFormatException TypeLoaderLogger.WriteLine("ERROR: template not fixed up, skipping"); continue; } Debug.Assert( (kind != CanonicalFormKind.Universal && candidateTemplate != candidateTemplate.GetCanonMethodTarget(kind)) || (kind == CanonicalFormKind.Universal && candidateTemplate == candidateTemplate.GetCanonMethodTarget(kind))); return candidateTemplate; } } } TypeLoaderLogger.WriteLine("ERROR: Cannot find a suitable template for generic method " + concreteMethod.ToString()); return null; }
private static NativeLayoutFieldDesc[] ParseFieldLayout(DefType owningType, NativeLayoutInfoLoadContext nativeLayoutInfoLoadContext, NativeParser fieldLayoutParser) { if (fieldLayoutParser.IsNull) return Empty<NativeLayoutFieldDesc>.Array; uint numFields = fieldLayoutParser.GetUnsigned(); var fields = new NativeLayoutFieldDesc[numFields]; for (int i = 0; i < numFields; i++) { TypeDesc fieldType = nativeLayoutInfoLoadContext.GetType(ref fieldLayoutParser); NativeFormat.FieldStorage storage = (NativeFormat.FieldStorage)fieldLayoutParser.GetUnsigned(); fields[i] = new NativeLayoutFieldDesc(owningType, fieldType, storage); } return fields; }
internal bool GetCallingConverterDataFromMethodSignature_NativeLayout(TypeSystemContext context, IntPtr methodSig, NativeLayoutInfoLoadContext nativeLayoutContext, out bool hasThis, out TypeDesc[] parameters, out bool[] parametersWithGenericDependentLayout) { hasThis = false; parameters = null; IntPtr moduleHandle = RuntimeAugments.GetModuleFromPointer(methodSig); NativeReader reader = GetNativeLayoutInfoReader(moduleHandle); NativeParser parser = new NativeParser(reader, reader.AddressToOffset(methodSig)); MethodCallingConvention callingConvention = (MethodCallingConvention)parser.GetUnsigned(); hasThis = !callingConvention.HasFlag(MethodCallingConvention.Static); uint numGenArgs = callingConvention.HasFlag(MethodCallingConvention.Generic) ? parser.GetUnsigned() : 0; uint parameterCount = parser.GetUnsigned(); parameters = new TypeDesc[parameterCount + 1]; parametersWithGenericDependentLayout = new bool[parameterCount + 1]; // One extra parameter to account for the return type for (uint i = 0; i <= parameterCount; i++) { // NativeParser is a struct, so it can be copied. NativeParser parserCopy = parser; // Parse the signature twice. The first time to find out the exact type of the signature // The second time to identify if the parameter loaded via the signature should be forced to be // passed byref as part of the universal generic calling convention. parameters[i] = GetConstructedTypeFromParserAndNativeLayoutContext(ref parser, nativeLayoutContext); parametersWithGenericDependentLayout[i] = TypeSignatureHasVarsNeedingCallingConventionConverter(ref parserCopy, context, HasVarsInvestigationLevel.Parameter); if (parameters[i] == null) { return(false); } } return(true); }
// // 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(); 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; } }
internal unsafe static GenericDictionaryCell[] BuildDictionary(TypeBuilder typeBuilder, NativeLayoutInfoLoadContext nativeLayoutInfoLoadContext, NativeParser parser) { uint parserStartOffset = parser.Offset; uint count = parser.GetSequenceCount(); Debug.Assert(count > 0); TypeLoaderLogger.WriteLine("Parsing dictionary layout @ " + parserStartOffset.LowLevelToString() + " (" + count.LowLevelToString() + " entries)"); GenericDictionaryCell[] dictionary = new GenericDictionaryCell[count]; for (uint i = 0; i < count; i++) { GenericDictionaryCell cell = ParseAndCreateCell(nativeLayoutInfoLoadContext, ref parser); cell.Prepare(typeBuilder); dictionary[i] = cell; } return dictionary; }
static private bool GetCallingConverterDataFromMethodSignature_MethodSignature(TypeSystem.MethodSignature methodSignature, NativeLayoutInfoLoadContext nativeLayoutContext, out bool hasThis, out TypeDesc[] parameters, out bool[] parametersWithGenericDependentLayout) { // Compute parameters dependent on generic instantiation for their layout parametersWithGenericDependentLayout = new bool[methodSignature.Length + 1]; parametersWithGenericDependentLayout[0] = TypeHasLayoutDependentOnGenericInstantiation(methodSignature.ReturnType, HasVarsInvestigationLevel.Parameter); for (int i = 0; i < methodSignature.Length; i++) { parametersWithGenericDependentLayout[i + 1] = TypeHasLayoutDependentOnGenericInstantiation(methodSignature[i], HasVarsInvestigationLevel.Parameter); } // Compute hasThis-ness hasThis = !methodSignature.IsStatic; // Compute parameter exact types parameters = new TypeDesc[methodSignature.Length + 1]; Instantiation typeInstantiation = nativeLayoutContext._typeArgumentHandles; Instantiation methodInstantiation = nativeLayoutContext._methodArgumentHandles; parameters[0] = methodSignature.ReturnType.InstantiateSignature(typeInstantiation, methodInstantiation); for (int i = 0; i < methodSignature.Length; i++) { parameters[i + 1] = methodSignature[i].InstantiateSignature(typeInstantiation, methodInstantiation); } return(true); }