コード例 #1
0
        private bool FindMatchingInterfaceSlot(IntPtr moduleHandle, NativeReader nativeLayoutReader, ref NativeParser entryParser, ref ExternalReferencesTable extRefs, ref RuntimeTypeHandle declaringType, ref MethodNameAndSignature methodNameAndSignature, RuntimeTypeHandle openTargetTypeHandle, RuntimeTypeHandle[] targetTypeInstantiation, bool variantDispatch)
        {
            uint numTargetImplementations = entryParser.GetUnsigned();

            for (uint j = 0; j < numTargetImplementations; j++)
            {
                uint nameAndSigToken = extRefs.GetRvaFromIndex(entryParser.GetUnsigned());
                MethodNameAndSignature targetMethodNameAndSignature = GetMethodNameAndSignatureFromNativeReader(nativeLayoutReader, nameAndSigToken);
                RuntimeTypeHandle targetTypeHandle = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());

#if REFLECTION_EXECUTION_TRACE
                ReflectionExecutionLogger.WriteLine("    Searching for GVM implementation on targe type = " + GetTypeNameDebug(targetTypeHandle));
#endif

                uint numIfaceImpls = entryParser.GetUnsigned();

                for (uint k = 0; k < numIfaceImpls; k++)
                {
                    RuntimeTypeHandle implementingTypeHandle = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());

                    uint numIfaceSigs = entryParser.GetUnsigned();

                    if (!openTargetTypeHandle.Equals(implementingTypeHandle))
                    {
                        // Skip over signatures data
                        for (uint l = 0; l < numIfaceSigs; l++)
                            entryParser.GetUnsigned();

                        continue;
                    }

                    for (uint l = 0; l < numIfaceSigs; l++)
                    {
                        RuntimeTypeHandle currentIfaceTypeHandle = default(RuntimeTypeHandle);

                        NativeParser ifaceSigParser = new NativeParser(nativeLayoutReader, extRefs.GetRvaFromIndex(entryParser.GetUnsigned()));
                        IntPtr currentIfaceSigPtr = ifaceSigParser.Reader.OffsetToAddress(ifaceSigParser.Offset);

                        if (TypeLoaderEnvironment.Instance.GetTypeFromSignatureAndContext(currentIfaceSigPtr, targetTypeInstantiation, null, out currentIfaceTypeHandle, out currentIfaceSigPtr))
                        {
                            Debug.Assert(!currentIfaceTypeHandle.IsNull());

                            if ((!variantDispatch && declaringType.Equals(currentIfaceTypeHandle)) ||
                                (variantDispatch && RuntimeAugments.IsAssignableFrom(declaringType, currentIfaceTypeHandle)))
                            {
#if REFLECTION_EXECUTION_TRACE
                                ReflectionExecutionLogger.WriteLine("    " + (declaringType.Equals(currentIfaceTypeHandle) ? "Exact" : "Variant-compatible") + " match found on this target type!");
#endif
                                // We found the GVM slot target for the input interface GVM call, so let's update the interface GVM slot and return success to the caller
                                declaringType = targetTypeHandle;
                                methodNameAndSignature = targetMethodNameAndSignature;
                                return true;
                            }
                        }
                    }
                }
            }

            return false;
        }
コード例 #2
0
        /// <summary>
        /// Build an array of GenericDictionaryCell from a NativeParser stream that has the appropriate metadata
        /// Return null if there are no cells to describe
        /// </summary>
        internal unsafe static GenericDictionaryCell[] BuildDictionaryFromMetadataTokensAndContext(TypeBuilder typeBuilder, NativeParser parser, NativeFormatMetadataUnit nativeMetadataUnit, FixupCellMetadataResolver resolver)
        {
            uint parserStartOffset = parser.Offset;

            uint count = parser.GetSequenceCount();

            // An empty dictionary isn't interesting
            if (count == 0)
                return null;

            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++)
            {
                MetadataFixupKind fixupKind = (MetadataFixupKind)parser.GetUInt8();
                Internal.Metadata.NativeFormat.Handle token = parser.GetUnsigned().AsHandle();
                Internal.Metadata.NativeFormat.Handle token2 = new Internal.Metadata.NativeFormat.Handle();

                switch (fixupKind)
                {
                    case MetadataFixupKind.GenericConstrainedMethod:
                    case MetadataFixupKind.NonGenericConstrainedMethod:
                    case MetadataFixupKind.NonGenericDirectConstrainedMethod:
                        token2 = parser.GetUnsigned().AsHandle();
                        break;
                }
                GenericDictionaryCell cell = CreateCellFromFixupKindAndToken(fixupKind, resolver, token, token2);
                cell.Prepare(typeBuilder);
                dictionary[i] = cell;
            }

            return dictionary;
        }
コード例 #3
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;
        }
コード例 #4
0
        private bool CompareTypeSigs(ref NativeParser parser1, ref NativeParser parser2)
        {
            // startOffset lets us backtrack to the TypeSignatureKind for external types since the TypeLoader
            // expects to read it in.
            uint data1;
            uint startOffset1 = parser1.Offset;
            var typeSignatureKind1 = parser1.GetTypeSignatureKind(out data1);

            // If the parser is at a lookback type, get a new parser for it and recurse.
            // Since we haven't read the element type of parser2 yet, we just pass it in unchanged
            if (typeSignatureKind1 == TypeSignatureKind.Lookback)
            {
                NativeParser lookbackParser1 = parser1.GetLookbackParser(data1);
                return CompareTypeSigs(ref lookbackParser1, ref parser2);
            }

            uint data2;
            uint startOffset2 = parser2.Offset;
            var typeSignatureKind2 = parser2.GetTypeSignatureKind(out data2);

            // If parser2 is a lookback type, we need to rewind parser1 to its startOffset1
            // before recursing.
            if (typeSignatureKind2 == TypeSignatureKind.Lookback)
            {
                NativeParser lookbackParser2 = parser2.GetLookbackParser(data2);
                parser1 = new NativeParser(parser1.Reader, startOffset1);
                return CompareTypeSigs(ref parser1, ref lookbackParser2);
            }

            if (typeSignatureKind1 != typeSignatureKind2)
                return false;

            switch (typeSignatureKind1)
            {
                case TypeSignatureKind.Lookback:
                    {
                        //  Recursion above better have removed all lookbacks
                        Debug.Assert(false, "Unexpected lookback type");
                        return false;
                    }

                case TypeSignatureKind.Modifier:
                    {
                        // Ensure the modifier kind (vector, pointer, byref) is the same
                        if (data1 != data2)
                            return false;
                        return CompareTypeSigs(ref parser1, ref parser2);
                    }

                case TypeSignatureKind.Variable:
                    {
                        // variable index is in data
                        if (data1 != data2)
                            return false;
                        break;
                    }

                case TypeSignatureKind.MultiDimArray:
                    {
                        // rank is in data
                        if (data1 != data2)
                            return false;

                        if (!CompareTypeSigs(ref parser1, ref parser2))
                            return false;

                        uint boundCount1 = parser1.GetUnsigned();
                        uint boundCount2 = parser2.GetUnsigned();
                        if (boundCount1 != boundCount2)
                            return false;

                        for (uint i = 0; i < boundCount1; i++)
                        {
                            if (parser1.GetUnsigned() != parser2.GetUnsigned())
                                return false;
                        }

                        uint lowerBoundCount1 = parser1.GetUnsigned();
                        uint lowerBoundCount2 = parser2.GetUnsigned();
                        if (lowerBoundCount1 != lowerBoundCount2)
                            return false;

                        for (uint i = 0; i < lowerBoundCount1; i++)
                        {
                            if (parser1.GetUnsigned() != parser2.GetUnsigned())
                                return false;
                        }
                        break;
                    }

                case TypeSignatureKind.FunctionPointer:
                    {
                        // callingConvention is in data
                        if (data1 != data2)
                            return false;
                        uint argCount1 = parser1.GetUnsigned();
                        uint argCount2 = parser2.GetUnsigned();
                        if (argCount1 != argCount2)
                            return false;
                        for (uint i = 0; i < argCount1; i++)
                        {
                            if (!CompareTypeSigs(ref parser1, ref parser2))
                                return false;
                        }
                        break;
                    }

                case TypeSignatureKind.Instantiation:
                    {
                        // Type parameter count is in data
                        if (data1 != data2)
                            return false;

                        if (!CompareTypeSigs(ref parser1, ref parser2))
                            return false;

                        for (uint i = 0; i < data1; i++)
                        {
                            if (!CompareTypeSigs(ref parser1, ref parser2))
                                return false;
                        }
                        break;
                    }

                case TypeSignatureKind.External:
                    {
                        RuntimeTypeHandle typeHandle1 = GetExternalTypeHandle(ref parser1, data1);
                        RuntimeTypeHandle typeHandle2 = GetExternalTypeHandle(ref parser2, data2);
                        if (!typeHandle1.Equals(typeHandle2))
                            return false;

                        break;
                    }

                default:
                    return false;
            }
            return true;
        }
コード例 #5
0
        private bool CompareMethodSigs(NativeParser parser1, NativeParser parser2)
        {
            MethodCallingConvention callingConvention1 = (MethodCallingConvention)parser1.GetUnsigned();
            MethodCallingConvention callingConvention2 = (MethodCallingConvention)parser2.GetUnsigned();

            if (callingConvention1 != callingConvention2)
                return false;

            if ((callingConvention1 & MethodCallingConvention.Generic) == MethodCallingConvention.Generic)
            {
                if (parser1.GetUnsigned() != parser2.GetUnsigned())
                    return false;
            }

            uint parameterCount1 = parser1.GetUnsigned();
            uint parameterCount2 = parser2.GetUnsigned();
            if (parameterCount1 != parameterCount2)
                return false;

            // Compare one extra parameter to account for the return type
            for (uint i = 0; i <= parameterCount1; i++)
            {
                if (!CompareTypeSigs(ref parser1, ref parser2))
                    return false;
            }

            return true;
        }
コード例 #6
0
        private uint GetGenericArgCountFromSig(NativeParser parser)
        {
            MethodCallingConvention callingConvention = (MethodCallingConvention)parser.GetUnsigned();

            if ((callingConvention & MethodCallingConvention.Generic) == MethodCallingConvention.Generic)
            {
                return parser.GetUnsigned();
            }
            else
            {
                return 0;
            }
        }
コード例 #7
0
        /// <summary>
        /// IF THESE SEMANTICS EVER CHANGE UPDATE THE LOGIC WHICH DEFINES THIS BEHAVIOR IN 
        /// THE DYNAMIC TYPE LOADER AS WELL AS THE COMPILER. 
        ///
        /// Parameter's are considered to have type layout dependent on their generic instantiation
        /// if the type of the parameter in its signature is a type variable, or if the type is a generic 
        /// structure which meets 2 characteristics:
        /// 1. Structure size/layout is affected by the size/layout of one or more of its generic parameters
        /// 2. One or more of the generic parameters is a type variable, or a generic structure which also recursively
        ///    would satisfy constraint 2. (Note, that in the recursion case, whether or not the structure is affected
        ///    by the size/layout of its generic parameters is not investigated.)
        ///    
        /// Examples parameter types, and behavior.
        /// 
        /// T -> true
        /// List<T> -> false
        /// StructNotDependentOnArgsForSize<T> -> false
        /// GenStructDependencyOnArgsForSize<T> -> true
        /// StructNotDependentOnArgsForSize<GenStructDependencyOnArgsForSize<T>> -> true
        /// StructNotDependentOnArgsForSize<GenStructDependencyOnArgsForSize<List<T>>>> -> false
        /// 
        /// Example non-parameter type behavior
        /// T -> true
        /// List<T> -> false
        /// StructNotDependentOnArgsForSize<T> -> *true*
        /// GenStructDependencyOnArgsForSize<T> -> true
        /// StructNotDependentOnArgsForSize<GenStructDependencyOnArgsForSize<T>> -> true
        /// StructNotDependentOnArgsForSize<GenStructDependencyOnArgsForSize<List<T>>>> -> false
        /// </summary>
        private bool TypeSignatureHasVarsNeedingCallingConventionConverter(ref NativeParser parser, TypeSystemContext context, HasVarsInvestigationLevel investigationLevel)
        {
            uint data;
            var kind = parser.GetTypeSignatureKind(out data);

            switch (kind)
            {
                case TypeSignatureKind.External: return false;
                case TypeSignatureKind.Variable: return true;

                case TypeSignatureKind.Lookback:
                    {
                        var lookbackParser = parser.GetLookbackParser(data);
                        return TypeSignatureHasVarsNeedingCallingConventionConverter(ref lookbackParser, context, investigationLevel);
                    }

                case TypeSignatureKind.Instantiation:
                    {
                        RuntimeTypeHandle genericTypeDef;
                        if (!TryGetTypeFromSimpleTypeSignature(ref parser, out genericTypeDef))
                        {
                            Debug.Assert(false);
                            return true;    // Returning true will prevent further reading from the native parser
                        }

                        if (!RuntimeAugments.IsValueType(genericTypeDef))
                        {
                            // Reference types are treated like pointers. No calling convention conversion needed. Just consume the rest of the signature.
                            for (uint i = 0; i < data; i++)
                                TypeSignatureHasVarsNeedingCallingConventionConverter(ref parser, context, HasVarsInvestigationLevel.Ignore);
                            return false;
                        }
                        else
                        {
                            bool result = false;
                            for (uint i = 0; i < data; i++)
                                result = TypeSignatureHasVarsNeedingCallingConventionConverter(ref parser, context, HasVarsInvestigationLevel.NotParameter) || result;

                            if ((result == true) && (investigationLevel == HasVarsInvestigationLevel.Parameter))
                            {
                                if (!TryComputeHasInstantiationDeterminedSize(genericTypeDef, context, out result))
                                    Environment.FailFast("Unable to setup calling convention converter correctly");

                                return result;
                            }

                            return result;
                        }
                    }

                case TypeSignatureKind.Modifier:
                    {
                        // Arrays, pointers and byref types signatures are treated as pointers, not requiring calling convention conversion.
                        // Just consume the parameter type from the stream and return false;
                        TypeSignatureHasVarsNeedingCallingConventionConverter(ref parser, context, HasVarsInvestigationLevel.Ignore);
                        return false;
                    }

                case TypeSignatureKind.MultiDimArray:
                    {
                        // No need for a calling convention converter for this case. Just consume the signature from the stream.

                        TypeSignatureHasVarsNeedingCallingConventionConverter(ref parser, context, HasVarsInvestigationLevel.Ignore);

                        uint boundCount = parser.GetUnsigned();
                        for (uint i = 0; i < boundCount; i++)
                            parser.GetUnsigned();

                        uint lowerBoundCount = parser.GetUnsigned();
                        for (uint i = 0; i < lowerBoundCount; i++)
                            parser.GetUnsigned();
                    }
                    return false;

                case TypeSignatureKind.FunctionPointer:
                    {
                        // No need for a calling convention converter for this case. Just consume the signature from the stream.

                        uint argCount = parser.GetUnsigned();
                        for (uint i = 0; i < argCount; i++)
                            TypeSignatureHasVarsNeedingCallingConventionConverter(ref parser, context, HasVarsInvestigationLevel.Ignore);
                    }
                    return false;

                default:
                    parser.ThrowBadImageFormatException();
                    return true;
            }
        }
コード例 #8
0
        private bool MethodSignatureHasVarsNeedingCallingConventionConverter_NativeLayout(TypeSystemContext context, IntPtr methodSig)
        {
            IntPtr moduleHandle = RuntimeAugments.GetModuleFromPointer(methodSig);
            NativeReader reader = GetNativeLayoutInfoReader(moduleHandle);
            NativeParser parser = new NativeParser(reader, reader.AddressToOffset(methodSig));

            MethodCallingConvention callingConvention = (MethodCallingConvention)parser.GetUnsigned();
            uint numGenArgs = callingConvention.HasFlag(MethodCallingConvention.Generic) ? parser.GetUnsigned() : 0;
            uint parameterCount = parser.GetUnsigned();

            // Check the return type of the method
            if (TypeSignatureHasVarsNeedingCallingConventionConverter(ref parser, context, HasVarsInvestigationLevel.Parameter))
                return true;

            // Check the parameters of the method
            for (uint i = 0; i < parameterCount; i++)
            {
                if (TypeSignatureHasVarsNeedingCallingConventionConverter(ref parser, context, HasVarsInvestigationLevel.Parameter))
                    return true;
            }

            return false;
        }
コード例 #9
0
        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;
        }
コード例 #10
0
        internal bool IsStaticMethodSignature(RuntimeMethodSignature methodSig)
        {
            if (methodSig.IsNativeLayoutSignature)
            {
                IntPtr moduleHandle = RuntimeAugments.GetModuleFromPointer(methodSig.NativeLayoutSignature);
                NativeReader reader = GetNativeLayoutInfoReader(moduleHandle);
                NativeParser parser = new NativeParser(reader, reader.AddressToOffset(methodSig.NativeLayoutSignature));

                MethodCallingConvention callingConvention = (MethodCallingConvention)parser.GetUnsigned();
                return callingConvention.HasFlag(MethodCallingConvention.Static);
            }
            else
            {
                var metadataReader = ModuleList.Instance.GetMetadataReaderForModule(methodSig.ModuleHandle);
                var methodHandle = methodSig.Token.AsHandle().ToMethodHandle(metadataReader);

                var method = methodHandle.GetMethod(metadataReader);
                return (method.Flags & MethodAttributes.Static) != 0;
            }
        }
コード例 #11
0
        private static RuntimeTypeHandle[] GetTypeSequence(ref ExternalReferencesTable extRefs, ref NativeParser parser)
        {
            uint count = parser.GetUnsigned();
            RuntimeTypeHandle[] result = new RuntimeTypeHandle[count];
            for (uint i = 0; i < count; i++)
                result[i] = extRefs.GetRuntimeTypeHandleFromIndex(parser.GetUnsigned());

            return result;
        }
コード例 #12
0
        internal MethodDesc GetMethod(ref NativeParser parser, out IntPtr methodNameSigPtr, out IntPtr methodSigPtr)
        {
            MethodFlags flags = (MethodFlags)parser.GetUnsigned();

            IntPtr functionPointer = IntPtr.Zero;
            if ((flags & MethodFlags.HasFunctionPointer) != 0)
                functionPointer = GetExternalReferencePointer(parser.GetUnsigned());

            DefType containingType = (DefType)GetType(ref parser);
            MethodNameAndSignature nameAndSignature = TypeLoaderEnvironment.Instance.GetMethodNameAndSignature(ref parser, out methodNameSigPtr, out methodSigPtr);

            bool unboxingStub = (flags & MethodFlags.IsUnboxingStub) != 0;

            MethodDesc retVal = null;
            if ((flags & MethodFlags.HasInstantiation) != 0)
            {
                TypeDesc[] typeArguments = GetTypeSequence(ref parser);
                Debug.Assert(typeArguments.Length > 0);
                retVal = this._typeSystemContext.ResolveGenericMethodInstantiation(unboxingStub, containingType, nameAndSignature, new Instantiation(typeArguments), functionPointer, (flags & MethodFlags.FunctionPointerIsUSG) != 0);
            }
            else
            {
                retVal = this._typeSystemContext.ResolveRuntimeMethod(unboxingStub, containingType, nameAndSignature, functionPointer, (flags & MethodFlags.FunctionPointerIsUSG) != 0);
            }

            if ((flags & MethodFlags.FunctionPointerIsUSG) != 0)
            {
                // TODO, consider a change such that if a USG function pointer is passed in, but we have
                // a way to get a non-usg pointer, that may be preferable
                Debug.Assert(retVal.UsgFunctionPointer != IntPtr.Zero);
            }

            return retVal;
        }
コード例 #13
0
        internal TypeDesc GetType(ref NativeParser parser)
        {
            uint data;
            var kind = parser.GetTypeSignatureKind(out data);

            switch (kind)
            {
                case TypeSignatureKind.Lookback:
                    return GetLookbackType(ref parser, data);

                case TypeSignatureKind.Variable:
                    uint index = data >> 1;
                    return (((data & 0x1) != 0) ? _methodArgumentHandles : _typeArgumentHandles)[checked((int)index)];

                case TypeSignatureKind.Instantiation:
                    return GetInstantiationType(ref parser, data);

                case TypeSignatureKind.Modifier:
                    return GetModifierType(ref parser, (TypeModifierKind)data);

                case TypeSignatureKind.External:
                    return GetExternalType(data);

                case TypeSignatureKind.MultiDimArray:
                    {
                        DefType elementType = (DefType)GetType(ref parser);
                        int rank = (int)data;

                        // Skip encoded bounds and lobounds
                        uint boundsCount = parser.GetUnsigned();
                        while (boundsCount > 0)
                            parser.GetUnsigned();

                        uint loBoundsCount = parser.GetUnsigned();
                        while (loBoundsCount > 0)
                            parser.GetUnsigned();

                        return _typeSystemContext.GetArrayType(elementType, rank);
                    }

                case TypeSignatureKind.FunctionPointer:
                    Debug.Assert(false, "NYI!");
                    parser.ThrowBadImageFormatException();
                    return null;

                default:
                    parser.ThrowBadImageFormatException();
                    return null;
            }
        }
コード例 #14
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;
        }