예제 #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
 public FixupCellMetadataResolver(NativeFormatMetadataUnit metadataUnit, NativeLayoutInfoLoadContext loadContext)
 {
     _metadataUnit  = metadataUnit;
     _methodContext = null;
     _typeContext   = null;
     _loadContextFromNativeLayout = loadContext;
 }
예제 #3
0
 public FixupCellMetadataResolver(NativeFormatMetadataUnit metadataUnit, NativeLayoutInfoLoadContext loadContext)
 {
     _metadataUnit = metadataUnit;
     _methodContext = null;
     _typeContext = null;
     _loadContextFromNativeLayout = loadContext;
 }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
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));
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        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;
        }
예제 #15
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;
        }
예제 #16
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);
        }
예제 #17
0
        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;
        }
예제 #18
0
 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);
     }
 }
예제 #19
0
 /// 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;
 }
예제 #20
0
        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);
        }
예제 #21
0
        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
            }
        }
예제 #23
0
        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);
        }
예제 #24
0
        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;
        }
예제 #25
0
        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);
        }
예제 #26
0
        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;
        }
예제 #27
0
        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);
        }
예제 #29
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();

                    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;
            }
        }
예제 #30
0
        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);
        }