| File: Internal\Runtime\TypeLoader\NativeLayoutInfoLoadContext.cs | Web Access |
| Project: src\runtime\src\coreclr\nativeaot\System.Private.TypeLoader\src\System.Private.TypeLoader.csproj (System.Private.TypeLoader) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Runtime.General; using Internal.NativeFormat; using Internal.Runtime; using Internal.Runtime.Augments; using Internal.Runtime.CompilerServices; using Internal.TypeSystem; using Internal.TypeSystem.NoMetadata; namespace Internal.Runtime.TypeLoader { // // Wrap state required by the native layout info parsing in a structure, so that it can be conveniently passed around. // internal class NativeLayoutInfoLoadContext { public TypeSystemContext _typeSystemContext; public NativeFormatModuleInfo _module; private ExternalReferencesTable _staticInfoLookup; private ExternalReferencesTable _externalReferencesLookup; public Instantiation _typeArgumentHandles; public Instantiation _methodArgumentHandles; private DefType GetInstantiationType(ref NativeParser parser, uint arity) { DefType typeDefinition = (DefType)GetType(ref parser); TypeDesc[] typeArguments = new TypeDesc[arity]; for (uint i = 0; i < arity; i++) typeArguments[i] = GetType(ref parser); return _typeSystemContext.ResolveGenericInstantiation(typeDefinition, new Instantiation(typeArguments)); } private TypeDesc GetModifierType(ref NativeParser parser, TypeModifierKind modifier) { TypeDesc typeParameter = GetType(ref parser); switch (modifier) { case TypeModifierKind.Array: return _typeSystemContext.GetArrayType(typeParameter); case TypeModifierKind.ByRef: return _typeSystemContext.GetByRefType(typeParameter); case TypeModifierKind.Pointer: return _typeSystemContext.GetPointerType(typeParameter); default: NativeParser.ThrowBadImageFormatException(); return null; } } private void InitializeExternalReferencesLookup() { if (!_externalReferencesLookup.IsInitialized()) { bool success = _externalReferencesLookup.InitializeNativeReferences(_module); Debug.Assert(success); } } private IntPtr GetExternalReferencePointer(uint index) { InitializeExternalReferencesLookup(); return _externalReferencesLookup.GetIntPtrFromIndex(index); } internal TypeDesc GetExternalType(uint index) { InitializeExternalReferencesLookup(); RuntimeTypeHandle rtth = _externalReferencesLookup.GetRuntimeTypeHandleFromIndex(index); return _typeSystemContext.ResolveRuntimeTypeHandle(rtth); } internal IntPtr GetGCStaticInfo(uint index) { if (!_staticInfoLookup.IsInitialized()) { bool success = _staticInfoLookup.InitializeNativeStatics(_module); Debug.Assert(success); } return _staticInfoLookup.GetIntPtrFromIndex(index); } private unsafe TypeDesc GetLookbackType(ref NativeParser parser, uint lookback) { var lookbackParser = parser.GetLookbackParser(lookback); return GetType(ref lookbackParser); } 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: { TypeDesc elementType = GetType(ref parser); int rank = (int)data; // Skip encoded bounds and lobounds uint boundsCount = parser.GetUnsigned(); while (boundsCount > 0) { parser.GetUnsigned(); boundsCount--; } uint loBoundsCount = parser.GetUnsigned(); while (loBoundsCount > 0) { parser.GetUnsigned(); loBoundsCount--; } return _typeSystemContext.GetArrayType(elementType, rank); } case TypeSignatureKind.BuiltIn: return _typeSystemContext.GetWellKnownType((WellKnownType)data); case TypeSignatureKind.FunctionPointer: { var callConv = (MethodCallingConvention)parser.GetUnsigned(); Debug.Assert((callConv & MethodCallingConvention.Generic) == 0); uint numParams = parser.GetUnsigned(); TypeDesc returnType = GetType(ref parser); TypeDesc[] parameters = new TypeDesc[numParams]; for (uint i = 0; i < parameters.Length; i++) parameters[i] = GetType(ref parser); return _typeSystemContext.GetFunctionPointerType( new MethodSignature( (callConv & MethodCallingConvention.Unmanaged) != 0 ? MethodSignatureFlags.UnmanagedCallingConvention : 0, 0, returnType, parameters )); } default: NativeParser.ThrowBadImageFormatException(); return null; } } internal MethodDesc GetMethod(ref NativeParser parser) { MethodFlags flags = (MethodFlags)parser.GetUnsigned(); IntPtr functionPointer = IntPtr.Zero; if ((flags & MethodFlags.HasFunctionPointer) != 0) functionPointer = GetExternalReferencePointer(parser.GetUnsigned()); DefType containingType = (DefType)GetType(ref parser); int token = (int)parser.GetUnsigned(); MethodNameAndSignature nameAndSignature = new MethodNameAndSignature(_module.MetadataReader, token.AsHandle().ToMethodHandle(_module.MetadataReader)); bool unboxingStub = (flags & MethodFlags.IsUnboxingStub) != 0; bool asyncVariant = (flags & MethodFlags.IsAsyncVariant) != 0; bool returnDroppingAsyncThunk = (flags & MethodFlags.IsReturnDroppingAsyncThunk) != 0; MethodDesc retVal; if ((flags & MethodFlags.HasInstantiation) != 0) { TypeDesc[] typeArguments = GetTypeSequence(ref parser); Debug.Assert(typeArguments.Length > 0); retVal = this._typeSystemContext.ResolveGenericMethodInstantiation(unboxingStub, asyncVariant, returnDroppingAsyncThunk, containingType, nameAndSignature, new Instantiation(typeArguments)); } else { retVal = this._typeSystemContext.ResolveRuntimeMethod(unboxingStub, asyncVariant, returnDroppingAsyncThunk, containingType, nameAndSignature); } if ((flags & MethodFlags.HasFunctionPointer) != 0) { retVal.SetFunctionPointer(functionPointer); } return retVal; } internal TypeDesc[] GetTypeSequence(ref NativeParser parser) { uint count = parser.GetSequenceCount(); TypeDesc[] sequence = new TypeDesc[count]; for (uint i = 0; i < count; i++) { sequence[i] = GetType(ref parser); } return sequence; } } }