Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common/src/Internal/Runtime/EEType.cs')
-rw-r--r--src/Common/src/Internal/Runtime/EEType.cs319
1 files changed, 219 insertions, 100 deletions
diff --git a/src/Common/src/Internal/Runtime/EEType.cs b/src/Common/src/Internal/Runtime/EEType.cs
index c9852dd80..66d952d2f 100644
--- a/src/Common/src/Internal/Runtime/EEType.cs
+++ b/src/Common/src/Internal/Runtime/EEType.cs
@@ -3,9 +3,11 @@
// See the LICENSE file in the project root for more information.
using System;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Internal.NativeFormat;
+using Internal.Runtime.CompilerServices;
using Debug = System.Diagnostics.Debug;
@@ -63,12 +65,12 @@ namespace Internal.Runtime
[StructLayout(LayoutKind.Sequential)]
internal unsafe struct DispatchMapEntry
{
- internal UInt16 _usInterfaceIndex;
- internal UInt16 _usInterfaceMethodSlot;
- internal UInt16 _usImplMethodSlot;
+ internal ushort _usInterfaceIndex;
+ internal ushort _usInterfaceMethodSlot;
+ internal ushort _usImplMethodSlot;
}
- private UInt32 _entryCount;
+ private uint _entryCount;
private DispatchMapEntry _dispatchMap; // at least one entry if any interfaces defined
public bool IsEmpty
@@ -79,7 +81,7 @@ namespace Internal.Runtime
}
}
- public UInt32 NumEntries
+ public uint NumEntries
{
get
{
@@ -97,7 +99,7 @@ namespace Internal.Runtime
{
get
{
- return sizeof(UInt32) + sizeof(DispatchMapEntry) * (int)_entryCount;
+ return sizeof(uint) + sizeof(DispatchMapEntry) * (int)_entryCount;
}
}
@@ -106,7 +108,7 @@ namespace Internal.Runtime
get
{
fixed (DispatchMap* pThis = &this)
- return (DispatchMapEntry*)((byte*)pThis + sizeof(UInt32) + (sizeof(DispatchMapEntry) * index));
+ return (DispatchMapEntry*)((byte*)pThis + sizeof(uint) + (sizeof(DispatchMapEntry) * index));
}
}
}
@@ -147,7 +149,7 @@ namespace Internal.Runtime
private static unsafe class OptionalFieldsReader
{
- internal static UInt32 GetInlineField(byte* pFields, EETypeOptionalFieldTag eTag, UInt32 uiDefaultValue)
+ internal static uint GetInlineField(byte* pFields, EETypeOptionalFieldTag eTag, uint uiDefaultValue)
{
if (pFields == null)
return uiDefaultValue;
@@ -158,7 +160,7 @@ namespace Internal.Runtime
byte fieldHeader = NativePrimitiveDecoder.ReadUInt8(ref pFields);
isLastField = (fieldHeader & 0x80) != 0;
EETypeOptionalFieldTag eCurrentTag = (EETypeOptionalFieldTag)(fieldHeader & 0x7f);
- UInt32 uiCurrentValue = NativePrimitiveDecoder.DecodeUnsigned(ref pFields);
+ uint uiCurrentValue = NativePrimitiveDecoder.DecodeUnsigned(ref pFields);
// If we found a tag match return the current value.
if (eCurrentTag == eTag)
@@ -170,13 +172,29 @@ namespace Internal.Runtime
}
}
- private UInt16 _usComponentSize;
- private UInt16 _usFlags;
- private UInt32 _uBaseSize;
+ /// <summary>
+ /// Gets a value indicating whether the statically generated data structures use relative pointers.
+ /// </summary>
+ internal static bool SupportsRelativePointers
+ {
+ [Intrinsic]
+ get
+ {
+#if PROJECTN
+ return true;
+#else
+ throw new NotImplementedException();
+#endif
+ }
+ }
+
+ private ushort _usComponentSize;
+ private ushort _usFlags;
+ private uint _uBaseSize;
private RelatedTypeUnion _relatedType;
- private UInt16 _usNumVtableSlots;
- private UInt16 _usNumInterfaces;
- private UInt32 _uHashCode;
+ private ushort _usNumVtableSlots;
+ private ushort _usNumInterfaces;
+ private uint _uHashCode;
#if EETYPE_TYPE_MANAGER
private IntPtr _ppTypeManager;
@@ -187,14 +205,14 @@ namespace Internal.Runtime
// if the alignment is 8 bytes or less. If the alignment is higher then there may be a need for more bits to hold
// the rest of the padding data.
// If paddings of greater than 7 bytes are necessary, then the high bits of the field represent that padding
- private const UInt32 ValueTypePaddingLowMask = 0x7;
- private const UInt32 ValueTypePaddingHighMask = 0xFFFFFF00;
- private const UInt32 ValueTypePaddingMax = 0x07FFFFFF;
+ private const uint ValueTypePaddingLowMask = 0x7;
+ private const uint ValueTypePaddingHighMask = 0xFFFFFF00;
+ private const uint ValueTypePaddingMax = 0x07FFFFFF;
private const int ValueTypePaddingHighShift = 8;
- private const UInt32 ValueTypePaddingAlignmentMask = 0xF8;
+ private const uint ValueTypePaddingAlignmentMask = 0xF8;
private const int ValueTypePaddingAlignmentShift = 3;
- internal UInt16 ComponentSize
+ internal ushort ComponentSize
{
get
{
@@ -208,7 +226,7 @@ namespace Internal.Runtime
#endif
}
- internal UInt16 GenericArgumentCount
+ internal ushort GenericArgumentCount
{
get
{
@@ -224,7 +242,7 @@ namespace Internal.Runtime
#endif
}
- internal UInt16 Flags
+ internal ushort Flags
{
get
{
@@ -238,7 +256,7 @@ namespace Internal.Runtime
#endif
}
- internal UInt32 BaseSize
+ internal uint BaseSize
{
get
{
@@ -252,7 +270,7 @@ namespace Internal.Runtime
#endif
}
- internal UInt16 NumVtableSlots
+ internal ushort NumVtableSlots
{
get
{
@@ -266,7 +284,7 @@ namespace Internal.Runtime
#endif
}
- internal UInt16 NumInterfaces
+ internal ushort NumInterfaces
{
get
{
@@ -280,7 +298,7 @@ namespace Internal.Runtime
#endif
}
- internal UInt32 HashCode
+ internal uint HashCode
{
get
{
@@ -298,7 +316,7 @@ namespace Internal.Runtime
{
get
{
- return (EETypeKind)(_usFlags & (UInt16)EETypeFlags.EETypeKindMask);
+ return (EETypeKind)(_usFlags & (ushort)EETypeFlags.EETypeKindMask);
}
}
@@ -306,7 +324,7 @@ namespace Internal.Runtime
{
get
{
- return ((_usFlags & (UInt16)EETypeFlags.OptionalFieldsFlag) != 0);
+ return ((_usFlags & (ushort)EETypeFlags.OptionalFieldsFlag) != 0);
}
}
@@ -316,7 +334,7 @@ namespace Internal.Runtime
{
get
{
- return ((_usFlags & (UInt16)EETypeFlags.GenericVarianceFlag) != 0);
+ return ((_usFlags & (ushort)EETypeFlags.GenericVarianceFlag) != 0);
}
}
@@ -399,7 +417,7 @@ namespace Internal.Runtime
{
get
{
- return ((_usFlags & (UInt16)EETypeFlags.IsGenericFlag) != 0);
+ return ((_usFlags & (ushort)EETypeFlags.IsGenericFlag) != 0);
}
}
@@ -416,11 +434,10 @@ namespace Internal.Runtime
get
{
Debug.Assert(IsGeneric);
- UInt32 cbOffset = GetFieldOffset(EETypeField.ETF_GenericDefinition);
- fixed (EEType* pThis = &this)
- {
- return ((EETypeRef*)((byte*)pThis + cbOffset))->Value;
- }
+ if (IsDynamicType || !SupportsRelativePointers)
+ return GetField<IatAwarePointer<EEType>>(EETypeField.ETF_GenericDefinition).Value;
+
+ return GetField<IatAwareRelativePointer<EEType>>(EETypeField.ETF_GenericDefinition).Value;
}
#if TYPE_LOADER_IMPLEMENTATION
set
@@ -435,17 +452,39 @@ namespace Internal.Runtime
#endif
}
+ [StructLayout(LayoutKind.Sequential)]
+ private readonly struct GenericComposition
+ {
+ public readonly ushort Arity;
+
+ private readonly EETypeRef _genericArgument1;
+ public EETypeRef* GenericArguments
+ {
+ get
+ {
+ return (EETypeRef*)Unsafe.AsPointer(ref Unsafe.AsRef(in _genericArgument1));
+ }
+ }
+
+ public GenericVariance* GenericVariance
+ {
+ get
+ {
+ // Generic variance directly follows the last generic argument
+ return (GenericVariance*)(GenericArguments + Arity);
+ }
+ }
+ }
+
internal uint GenericArity
{
get
{
Debug.Assert(IsGeneric);
- UInt32 cbOffset = GetFieldOffset(EETypeField.ETF_GenericComposition);
- fixed (EEType* pThis = &this)
- {
- // Number of generic arguments is the first UInt16 of the composition stream.
- return **(UInt16**)((byte*)pThis + cbOffset);
- }
+ if (IsDynamicType || !SupportsRelativePointers)
+ return GetField<Pointer<GenericComposition>>(EETypeField.ETF_GenericComposition).Value->Arity;
+
+ return GetField<RelativePointer<GenericComposition>>(EETypeField.ETF_GenericComposition).Value->Arity;
}
}
@@ -454,13 +493,10 @@ namespace Internal.Runtime
get
{
Debug.Assert(IsGeneric);
- UInt32 cbOffset = GetFieldOffset(EETypeField.ETF_GenericComposition);
- fixed (EEType* pThis = &this)
- {
- // Generic arguments follow after a (padded) UInt16 specifying their count
- // in the generic composition stream.
- return ((*(EETypeRef**)((byte*)pThis + cbOffset)) + 1);
- }
+ if (IsDynamicType || !SupportsRelativePointers)
+ return GetField<Pointer<GenericComposition>>(EETypeField.ETF_GenericComposition).Value->GenericArguments;
+
+ return GetField<RelativePointer<GenericComposition>>(EETypeField.ETF_GenericComposition).Value->GenericArguments;
}
}
@@ -473,12 +509,10 @@ namespace Internal.Runtime
if (!HasGenericVariance)
return null;
- UInt32 cbOffset = GetFieldOffset(EETypeField.ETF_GenericComposition);
- fixed (EEType* pThis = &this)
- {
- // Variance info follows immediatelly after the generic arguments
- return (GenericVariance*)(GenericArguments + GenericArity);
- }
+ if (IsDynamicType || !SupportsRelativePointers)
+ return GetField<Pointer<GenericComposition>>(EETypeField.ETF_GenericComposition).Value->GenericVariance;
+
+ return GetField<RelativePointer<GenericComposition>>(EETypeField.ETF_GenericComposition).Value->GenericVariance;
}
}
@@ -504,7 +538,7 @@ namespace Internal.Runtime
{
get
{
- return ((_usFlags & (UInt16)EETypeFlags.IsInterfaceFlag) != 0);
+ return ((_usFlags & (ushort)EETypeFlags.IsInterfaceFlag) != 0);
}
}
@@ -561,7 +595,7 @@ namespace Internal.Runtime
// Currently, the meaning is a shape of 0 indicates that this is a Pointer,
// shape of 1 indicates a ByRef, and >=SZARRAY_BASE_SIZE indicates that this is an array.
// Two types are not equivalent if their shapes do not exactly match.
- internal UInt32 ParameterizedTypeShape
+ internal uint ParameterizedTypeShape
{
get
{
@@ -579,7 +613,7 @@ namespace Internal.Runtime
{
get
{
- return ((_usFlags & (UInt16)EETypeFlags.RelatedTypeViaIATFlag) != 0);
+ return ((_usFlags & (ushort)EETypeFlags.RelatedTypeViaIATFlag) != 0);
}
}
@@ -595,7 +629,7 @@ namespace Internal.Runtime
{
get
{
- return ((_usFlags & (UInt16)EETypeFlags.ICastableFlag) != 0);
+ return ((_usFlags & (ushort)EETypeFlags.ICastableFlag) != 0);
}
}
@@ -611,14 +645,14 @@ namespace Internal.Runtime
byte* optionalFields = OptionalFieldsPtr;
if(optionalFields != null)
{
- const UInt16 NoSlot = 0xFFFF;
- UInt16 uiSlot = (UInt16)OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.ICastableIsInstSlot, NoSlot);
+ const ushort NoSlot = 0xFFFF;
+ ushort uiSlot = (ushort)OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.ICastableIsInstSlot, NoSlot);
if (uiSlot != NoSlot)
{
if (uiSlot < NumVtableSlots)
return GetVTableStartAddress()[uiSlot];
else
- return GetSealedVirtualSlot((UInt16)(uiSlot - NumVtableSlots));
+ return GetSealedVirtualSlot((ushort)(uiSlot - NumVtableSlots));
}
}
@@ -643,14 +677,14 @@ namespace Internal.Runtime
byte* optionalFields = OptionalFieldsPtr;
if(optionalFields != null)
{
- const UInt16 NoSlot = 0xFFFF;
- UInt16 uiSlot = (UInt16)OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.ICastableGetImplTypeSlot, NoSlot);
+ const ushort NoSlot = 0xFFFF;
+ ushort uiSlot = (ushort)OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.ICastableGetImplTypeSlot, NoSlot);
if (uiSlot != NoSlot)
{
if (uiSlot < NumVtableSlots)
return GetVTableStartAddress()[uiSlot];
else
- return GetSealedVirtualSlot((UInt16)(uiSlot - NumVtableSlots));
+ return GetSealedVirtualSlot((ushort)(uiSlot - NumVtableSlots));
}
}
@@ -667,7 +701,7 @@ namespace Internal.Runtime
{
get
{
- return ((_usFlags & (UInt16)EETypeFlags.ValueTypeFlag) != 0);
+ return ((_usFlags & (ushort)EETypeFlags.ValueTypeFlag) != 0);
}
}
@@ -675,7 +709,7 @@ namespace Internal.Runtime
{
get
{
- return ((_usFlags & (UInt16)EETypeFlags.HasPointersFlag) != 0);
+ return ((_usFlags & (ushort)EETypeFlags.HasPointersFlag) != 0);
}
#if TYPE_LOADER_IMPLEMENTATION
set
@@ -700,7 +734,7 @@ namespace Internal.Runtime
}
}
- internal UInt32 ValueTypeFieldPadding
+ internal uint ValueTypeFieldPadding
{
get
{
@@ -712,15 +746,15 @@ namespace Internal.Runtime
// Get the value from the optional fields. The default is zero if that particular field was not included.
// The low bits of this field is the ValueType field padding, the rest of the byte is the alignment if present
- UInt32 ValueTypeFieldPaddingData = OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.ValueTypeFieldPadding, 0);
- UInt32 padding = ValueTypeFieldPaddingData & ValueTypePaddingLowMask;
+ uint ValueTypeFieldPaddingData = OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.ValueTypeFieldPadding, 0);
+ uint padding = ValueTypeFieldPaddingData & ValueTypePaddingLowMask;
// If there is additional padding, the other bits have that data
padding |= (ValueTypeFieldPaddingData & ValueTypePaddingHighMask) >> (ValueTypePaddingHighShift - ValueTypePaddingAlignmentShift);
return padding;
}
}
- internal UInt32 ValueTypeSize
+ internal uint ValueTypeSize
{
get
{
@@ -732,7 +766,7 @@ namespace Internal.Runtime
}
}
- internal UInt32 FieldByteCountNonGCAligned
+ internal uint FieldByteCountNonGCAligned
{
get
{
@@ -769,7 +803,7 @@ namespace Internal.Runtime
byte* optionalFields = OptionalFieldsPtr;
if (optionalFields == null)
return false;
- UInt32 idxDispatchMap = OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.DispatchMap, 0xffffffff);
+ uint idxDispatchMap = OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.DispatchMap, 0xffffffff);
if (idxDispatchMap == 0xffffffff)
{
if (HasDynamicallyAllocatedDispatchMap)
@@ -912,7 +946,7 @@ namespace Internal.Runtime
get
{
Debug.Assert(IsNullable);
- UInt32 cbNullableTypeOffset = GetFieldOffset(EETypeField.ETF_NullableType);
+ uint cbNullableTypeOffset = GetFieldOffset(EETypeField.ETF_NullableType);
fixed (EEType* pThis = &this)
{
if (IsNullableTypeViaIAT)
@@ -987,30 +1021,30 @@ namespace Internal.Runtime
return (IntPtr*)pResult;
}
- private static IntPtr FollowRelativePointer(Int32* pDist)
+ private static IntPtr FollowRelativePointer(int* pDist)
{
- Int32 dist = *pDist;
+ int dist = *pDist;
IntPtr result = (IntPtr)((byte*)pDist + dist);
return result;
}
- internal IntPtr GetSealedVirtualSlot(UInt16 slotNumber)
+ internal IntPtr GetSealedVirtualSlot(ushort slotNumber)
{
Debug.Assert(!IsNullable);
Debug.Assert((RareFlags & EETypeRareFlags.HasSealedVTableEntriesFlag) != 0);
fixed (EEType* pThis = &this)
{
- if (IsDynamicType)
+ if (IsDynamicType || !SupportsRelativePointers)
{
- UInt32 cbSealedVirtualSlotsTypeOffset = GetFieldOffset(EETypeField.ETF_SealedVirtualSlots);
+ uint cbSealedVirtualSlotsTypeOffset = GetFieldOffset(EETypeField.ETF_SealedVirtualSlots);
IntPtr* pSealedVirtualsSlotTable = *(IntPtr**)((byte*)pThis + cbSealedVirtualSlotsTypeOffset);
return pSealedVirtualsSlotTable[slotNumber];
}
else
{
- UInt32 cbSealedVirtualSlotsTypeOffset = GetFieldOffset(EETypeField.ETF_SealedVirtualSlots);
- Int32* pSealedVirtualsSlotTable = (Int32*)FollowRelativePointer((Int32*)((byte*)pThis + cbSealedVirtualSlotsTypeOffset));
+ uint cbSealedVirtualSlotsTypeOffset = GetFieldOffset(EETypeField.ETF_SealedVirtualSlots);
+ int* pSealedVirtualsSlotTable = (int*)FollowRelativePointer((int*)((byte*)pThis + cbSealedVirtualSlotsTypeOffset));
IntPtr result = FollowRelativePointer(&pSealedVirtualsSlotTable[slotNumber]);
return result;
}
@@ -1038,7 +1072,7 @@ namespace Internal.Runtime
if (!HasOptionalFields)
return null;
- UInt32 cbOptionalFieldsOffset = GetFieldOffset(EETypeField.ETF_OptionalFieldsPtr);
+ uint cbOptionalFieldsOffset = GetFieldOffset(EETypeField.ETF_OptionalFieldsPtr);
fixed (EEType* pThis = &this)
{
return *(byte**)((byte*)pThis + cbOptionalFieldsOffset);
@@ -1063,7 +1097,7 @@ namespace Internal.Runtime
get
{
Debug.Assert(IsDynamicType);
- UInt32 cbOffset = GetFieldOffset(EETypeField.ETF_DynamicTemplateType);
+ uint cbOffset = GetFieldOffset(EETypeField.ETF_DynamicTemplateType);
fixed (EEType* pThis = &this)
{
return *(EEType**)((byte*)pThis + cbOffset);
@@ -1087,7 +1121,7 @@ namespace Internal.Runtime
get
{
Debug.Assert((RareFlags & EETypeRareFlags.IsDynamicTypeWithGcStatics) != 0);
- UInt32 cbOffset = GetFieldOffset(EETypeField.ETF_DynamicGcStatics);
+ uint cbOffset = GetFieldOffset(EETypeField.ETF_DynamicGcStatics);
fixed (EEType* pThis = &this)
{
return (IntPtr)((byte*)pThis + cbOffset);
@@ -1111,7 +1145,7 @@ namespace Internal.Runtime
get
{
Debug.Assert((RareFlags & EETypeRareFlags.IsDynamicTypeWithNonGcStatics) != 0);
- UInt32 cbOffset = GetFieldOffset(EETypeField.ETF_DynamicNonGcStatics);
+ uint cbOffset = GetFieldOffset(EETypeField.ETF_DynamicNonGcStatics);
fixed (EEType* pThis = &this)
{
return (IntPtr)((byte*)pThis + cbOffset);
@@ -1136,7 +1170,7 @@ namespace Internal.Runtime
{
if ((RareFlags & EETypeRareFlags.HasDynamicModuleFlag) != 0)
{
- UInt32 cbOffset = GetFieldOffset(EETypeField.ETF_DynamicModule);
+ uint cbOffset = GetFieldOffset(EETypeField.ETF_DynamicModule);
fixed (EEType* pThis = &this)
{
return *(DynamicModule**)((byte*)pThis + cbOffset);
@@ -1209,7 +1243,7 @@ namespace Internal.Runtime
// Get the value from the optional fields. The default is zero if that particular field was not included.
// The low bits of this field is the ValueType field padding, the rest of the value is the alignment if present
- UInt32 alignmentValue = (OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.ValueTypeFieldPadding, 0) & ValueTypePaddingAlignmentMask) >> ValueTypePaddingAlignmentShift;
+ uint alignmentValue = (OptionalFieldsReader.GetInlineField(optionalFields, EETypeOptionalFieldTag.ValueTypeFieldPadding, 0) & ValueTypePaddingAlignmentMask) >> ValueTypePaddingAlignmentShift;
// Alignment is stored as 1 + the log base 2 of the alignment, except a 0 indicates standard pointer alignment.
if (alignmentValue == 0)
@@ -1235,10 +1269,10 @@ namespace Internal.Runtime
}
}
- public UInt32 GetFieldOffset(EETypeField eField)
+ public uint GetFieldOffset(EETypeField eField)
{
// First part of EEType consists of the fixed portion followed by the vtable.
- UInt32 cbOffset = (UInt32)(sizeof(EEType) + (IntPtr.Size * _usNumVtableSlots));
+ uint cbOffset = (uint)(sizeof(EEType) + (IntPtr.Size * _usNumVtableSlots));
// Then we have the interface map.
if (eField == EETypeField.ETF_InterfaceMap)
@@ -1246,7 +1280,7 @@ namespace Internal.Runtime
Debug.Assert(NumInterfaces > 0);
return cbOffset;
}
- cbOffset += (UInt32)(sizeof(EEInterfaceInfo) * NumInterfaces);
+ cbOffset += (uint)(sizeof(EEInterfaceInfo) * NumInterfaces);
// Followed by the pointer to the finalizer method.
if (eField == EETypeField.ETF_Finalizer)
@@ -1255,7 +1289,7 @@ namespace Internal.Runtime
return cbOffset;
}
if (IsFinalizable)
- cbOffset += (UInt32)IntPtr.Size;
+ cbOffset += (uint)IntPtr.Size;
// Followed by the pointer to the optional fields.
if (eField == EETypeField.ETF_OptionalFieldsPtr)
@@ -1264,7 +1298,7 @@ namespace Internal.Runtime
return cbOffset;
}
if (HasOptionalFields)
- cbOffset += (UInt32)IntPtr.Size;
+ cbOffset += (uint)IntPtr.Size;
// Followed by the pointer to the type target of a Nullable<T>.
if (eField == EETypeField.ETF_NullableType)
@@ -1278,13 +1312,13 @@ namespace Internal.Runtime
return cbOffset;
if (IsNullable)
- cbOffset += (UInt32)IntPtr.Size;
+ cbOffset += (uint)IntPtr.Size;
EETypeRareFlags rareFlags = RareFlags;
// in the case of sealed vtable entries on static types, we have a UInt sized relative pointer
if ((rareFlags & EETypeRareFlags.HasSealedVTableEntriesFlag) != 0)
- cbOffset += (IsDynamicType ? (UInt32)IntPtr.Size : 4);
+ cbOffset += (IsDynamicType || !SupportsRelativePointers ? (uint)IntPtr.Size : 4);
if (eField == EETypeField.ETF_DynamicDispatchMap)
{
@@ -1292,7 +1326,7 @@ namespace Internal.Runtime
return cbOffset;
}
if ((rareFlags & EETypeRareFlags.HasDynamicallyAllocatedDispatchMapFlag) != 0)
- cbOffset += (UInt32)IntPtr.Size;
+ cbOffset += (uint)IntPtr.Size;
if (eField == EETypeField.ETF_GenericDefinition)
{
@@ -1300,7 +1334,12 @@ namespace Internal.Runtime
return cbOffset;
}
if (IsGeneric)
- cbOffset += (UInt32)IntPtr.Size;
+ {
+ if ((rareFlags & EETypeRareFlags.IsDynamicTypeFlag) != 0 || !SupportsRelativePointers)
+ cbOffset += (uint)IntPtr.Size;
+ else
+ cbOffset += 4;
+ }
if (eField == EETypeField.ETF_GenericComposition)
{
@@ -1308,7 +1347,12 @@ namespace Internal.Runtime
return cbOffset;
}
if (IsGeneric)
- cbOffset += (UInt32)IntPtr.Size;
+ {
+ if ((rareFlags & EETypeRareFlags.IsDynamicTypeFlag) != 0 || !SupportsRelativePointers)
+ cbOffset += (uint)IntPtr.Size;
+ else
+ cbOffset += 4;
+ }
if (eField == EETypeField.ETF_DynamicModule)
{
@@ -1316,7 +1360,7 @@ namespace Internal.Runtime
}
if ((rareFlags & EETypeRareFlags.HasDynamicModuleFlag) != 0)
- cbOffset += (UInt32)IntPtr.Size;
+ cbOffset += (uint)IntPtr.Size;
if (eField == EETypeField.ETF_DynamicTemplateType)
{
@@ -1324,7 +1368,7 @@ namespace Internal.Runtime
return cbOffset;
}
if (IsDynamicType)
- cbOffset += (UInt32)IntPtr.Size;
+ cbOffset += (uint)IntPtr.Size;
if (eField == EETypeField.ETF_DynamicGcStatics)
{
@@ -1332,7 +1376,7 @@ namespace Internal.Runtime
return cbOffset;
}
if ((rareFlags & EETypeRareFlags.IsDynamicTypeWithGcStatics) != 0)
- cbOffset += (UInt32)IntPtr.Size;
+ cbOffset += (uint)IntPtr.Size;
if (eField == EETypeField.ETF_DynamicNonGcStatics)
{
@@ -1340,7 +1384,7 @@ namespace Internal.Runtime
return cbOffset;
}
if ((rareFlags & EETypeRareFlags.IsDynamicTypeWithNonGcStatics) != 0)
- cbOffset += (UInt32)IntPtr.Size;
+ cbOffset += (uint)IntPtr.Size;
if (eField == EETypeField.ETF_DynamicThreadStaticOffset)
{
@@ -1354,6 +1398,12 @@ namespace Internal.Runtime
return 0;
}
+ public ref T GetField<T>(EETypeField eField)
+ {
+ fixed (EEType* pThis = &this)
+ return ref Unsafe.AddByteOffset(ref Unsafe.As<EEType, T>(ref *pThis), (IntPtr)GetFieldOffset(eField));
+ }
+
#if TYPE_LOADER_IMPLEMENTATION
internal static UInt32 GetSizeofEEType(
UInt16 cVirtuals,
@@ -1415,6 +1465,75 @@ namespace Internal.Runtime
}
}
+ // Wrapper around pointers
+ [StructLayout(LayoutKind.Sequential)]
+ internal unsafe readonly struct Pointer<T> where T : unmanaged
+ {
+ private readonly T* _value;
+
+ public T* Value
+ {
+ get
+ {
+ return _value;
+ }
+ }
+ }
+
+ // Wrapper around pointers that might be indirected through IAT
+ [StructLayout(LayoutKind.Sequential)]
+ internal unsafe readonly struct IatAwarePointer<T> where T : unmanaged
+ {
+ private readonly T* _value;
+
+ public T* Value
+ {
+ get
+ {
+ if (((int)_value & IndirectionConstants.IndirectionCellPointer) == 0)
+ return _value;
+ return *(T**)((byte*)_value - IndirectionConstants.IndirectionCellPointer);
+ }
+ }
+ }
+
+ // Wrapper around relative pointers
+ [StructLayout(LayoutKind.Sequential)]
+ internal unsafe readonly struct RelativePointer<T> where T : unmanaged
+ {
+ private readonly int _value;
+
+ public T* Value
+ {
+ get
+ {
+ return (T*)((byte*)Unsafe.AsPointer(ref Unsafe.AsRef(in _value)) + _value);
+ }
+ }
+ }
+
+ // Wrapper around relative pointers that might be indirected through IAT
+ [StructLayout(LayoutKind.Sequential)]
+ internal unsafe readonly struct IatAwareRelativePointer<T> where T : unmanaged
+ {
+ private readonly int _value;
+
+ public T* Value
+ {
+ get
+ {
+ if ((_value & IndirectionConstants.IndirectionCellPointer) == 0)
+ {
+ return (T*)((byte*)Unsafe.AsPointer(ref Unsafe.AsRef(in _value)) + _value);
+ }
+ else
+ {
+ return *(T**)((byte*)Unsafe.AsPointer(ref Unsafe.AsRef(in _value)) + (_value & ~IndirectionConstants.IndirectionCellPointer));
+ }
+ }
+ }
+ }
+
[StructLayout(LayoutKind.Sequential)]
internal struct DynamicModule
{