コード例 #1
0
        private MethodNameAndSignature GetMethodNameAndSignatureFromNativeReader(NativeReader nativeLayoutReader, uint nativeLayoutOffset)
        {
            NativeParser parser = new NativeParser(nativeLayoutReader, nativeLayoutOffset);

            string methodName = parser.GetString();

            // Signatures are indirected to through a relative offset so that we don't have to parse them
            // when not comparing signatures (parsing them requires resolving types and is tremendously 
            // expensive).
            NativeParser sigParser = parser.GetParserFromRelativeOffset();
            IntPtr methodSigPtr = sigParser.Reader.OffsetToAddress(sigParser.Offset);

            return new MethodNameAndSignature(methodName, RuntimeMethodSignature.CreateFromNativeLayoutSignature(methodSigPtr));
        }
コード例 #2
0
            public NativeParser GetNext()
            {
                for (;;)
                {
                    while (_parser.Offset < _endOffset)
                    {
                        byte lowHashcode = _parser.GetUInt8();
                        return(_parser.GetParserFromRelativeOffset());
                    }

                    if (_currentBucket >= _table._bucketMask)
                    {
                        return(new NativeParser());
                    }

                    _currentBucket++;
                    _parser = _table.GetParserForBucket(_currentBucket, out _endOffset);
                }
            }
コード例 #3
0
ファイル: NativeFormatReader.cs プロジェクト: z77ma/runtime
            public NativeParser GetNext()
            {
                while (_parser.Offset < _endOffset)
                {
                    byte lowHashcode = _parser.GetUInt8();

                    if (lowHashcode == _lowHashcode)
                    {
                        return(_parser.GetParserFromRelativeOffset());
                    }

                    // The entries are sorted by hashcode within the bucket. It allows us to terminate the lookup prematurely.
                    if (lowHashcode > _lowHashcode)
                    {
                        _endOffset = _parser.Offset; // Ensure that extra call to GetNext returns null parser again
                        break;
                    }

                    _parser.SkipInteger();
                }

                return(default);
コード例 #4
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;
        }
コード例 #5
0
        public bool TryGetMethodNameAndSignaturePointersFromNativeLayoutSignature(IntPtr module, uint methodNameAndSigToken, out IntPtr methodNameSigPtr, out IntPtr methodSigPtr)
        {
            methodNameSigPtr = default(IntPtr);
            methodSigPtr = default(IntPtr);

            NativeReader reader = GetNativeLayoutInfoReader(module);
            uint offset = methodNameAndSigToken;
            NativeParser parser = new NativeParser(reader, offset);
            if (parser.IsNull)
                return false;

            methodNameSigPtr = parser.Reader.OffsetToAddress(parser.Offset);
            string methodName = parser.GetString();

            // Signatures are indirected to through a relative offset so that we don't have to parse them
            // when not comparing signatures (parsing them requires resolving types and is tremendously 
            // expensive).
            NativeParser sigParser = parser.GetParserFromRelativeOffset();
            methodSigPtr = sigParser.Reader.OffsetToAddress(sigParser.Offset);

            return true;
        }