if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
- EETypePtr eeType = array.GetEETypePtr();
- nuint totalByteLength = eeType.ComponentSize * array.NativeLength;
+ MethodTable* mt = array.GetMethodTable();
+ nuint totalByteLength = mt->ComponentSize * array.NativeLength;
ref byte pStart = ref MemoryMarshal.GetArrayDataReference(array);
- if (!eeType.ContainsGCPointers)
+ if (!mt->ContainsGCPointers)
{
SpanHelpers.ClearWithoutReferences(ref pStart, totalByteLength);
}
ref byte p = ref Unsafe.As<RawArrayData>(array).Data;
int lowerBound = 0;
- EETypePtr eeType = array.GetEETypePtr();
- if (!eeType.IsSzArray)
+ MethodTable* mt = array.GetMethodTable();
+ if (!mt->IsSzArray)
{
- int rank = eeType.ArrayRank;
+ int rank = mt->ArrayRank;
lowerBound = Unsafe.Add(ref Unsafe.As<byte, int>(ref p), rank);
p = ref Unsafe.Add(ref p, 2 * sizeof(int) * rank); // skip the bounds
}
if (index < lowerBound || offset < 0 || length < 0 || (uint)(offset + length) > array.NativeLength)
ThrowHelper.ThrowIndexOutOfRangeException();
- nuint elementSize = eeType.ComponentSize;
+ nuint elementSize = mt->ComponentSize;
ref byte ptr = ref Unsafe.AddByteOffset(ref p, (uint)offset * elementSize);
nuint byteLength = (uint)length * elementSize;
- if (eeType.ContainsGCPointers)
+ if (mt->ContainsGCPointers)
{
Debug.Assert(byteLength % (nuint)sizeof(IntPtr) == 0);
SpanHelpers.ClearWithReferences(ref Unsafe.As<byte, IntPtr>(ref ptr), byteLength / (uint)sizeof(IntPtr));
//
// Return storage size of an individual element in bytes.
//
- internal nuint ElementSize
+ internal unsafe nuint ElementSize
{
get
{
- return this.GetEETypePtr().ComponentSize;
+ return this.GetMethodTable()->ComponentSize;
}
}
}
}
- internal bool IsAbstract
- {
- get
- {
- return _value->IsAbstract;
- }
- }
-
internal bool IsByRefLike
{
get
}
}
- internal ushort ComponentSize
- {
- get
- {
- return _value->ComponentSize;
- }
- }
-
internal uint BaseSize
{
get
// Returns true iff the object has a component size;
// i.e., is variable length like System.String or Array.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static bool ObjectHasComponentSize(object obj)
+ internal static unsafe bool ObjectHasComponentSize(object obj)
{
- Debug.Assert(obj != null);
- return obj.GetEETypePtr().ComponentSize != 0;
+ return GetMethodTable(obj)->HasComponentSize;
}
public static void PrepareMethod(RuntimeMethodHandle method)
Justification = "We keep class constructors of all types with an MethodTable")]
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2072:UnrecognizedReflectionPattern",
Justification = "Constructed MethodTable of a Nullable forces a constructed MethodTable of the element type")]
- public static object GetUninitializedObject(
+ public static unsafe object GetUninitializedObject(
// This API doesn't call any constructors, but the type needs to be seen as constructed.
// A type is seen as constructed if a constructor is kept.
// This obviously won't cover a type with no constructor. Reference types with no
throw new NotSupportedException(SR.NotSupported_ManagedActivation);
}
- EETypePtr eeTypePtr = type.TypeHandle.ToEETypePtr();
+ MethodTable* mt = type.TypeHandle.ToMethodTable();
- if (eeTypePtr.ElementType == Internal.Runtime.EETypeElementType.Void)
+ if (mt->ElementType == Internal.Runtime.EETypeElementType.Void)
{
throw new ArgumentException(SR.Argument_InvalidValue);
}
// Don't allow strings (we already checked for arrays above)
- if (eeTypePtr.ComponentSize != 0)
+ if (mt->HasComponentSize)
{
throw new ArgumentException(SR.Argument_NoUninitializedStrings);
}
- if (RuntimeImports.AreTypesAssignable(eeTypePtr, EETypePtr.EETypePtrOf<Delegate>()))
+ if (RuntimeImports.AreTypesAssignable(mt, MethodTable.Of<Delegate>()))
{
throw new MemberAccessException();
}
- if (eeTypePtr.IsAbstract)
+ if (mt->IsAbstract)
{
throw new MemberAccessException(SR.Acc_CreateAbst);
}
- if (eeTypePtr.IsByRefLike)
+ if (mt->IsByRefLike)
{
throw new NotSupportedException(SR.NotSupported_ByRefLike);
}
- if (eeTypePtr.IsNullable)
+ if (mt->IsNullable)
{
- return GetUninitializedObject(Type.GetTypeFromEETypePtr(eeTypePtr.NullableType));
+ mt = mt->NullableType;
+ return GetUninitializedObject(Type.GetTypeFromEETypePtr(new EETypePtr(mt)));
}
// Triggering the .cctor here is slightly different than desktop/CoreCLR, which
// in MethodTable just for this API to behave slightly differently.
RunClassConstructor(type.TypeHandle);
- return RuntimeImports.RhNewObject(eeTypePtr);
+ return RuntimeImports.RhNewObject(mt);
}
}
[MethodImpl(MethodImplOptions.InternalCall)]
[RuntimeImport(RuntimeLibrary, "RhTypeCast_AreTypesAssignable")]
- private static extern unsafe bool AreTypesAssignable(MethodTable* pSourceType, MethodTable* pTargetType);
+ internal static extern unsafe bool AreTypesAssignable(MethodTable* pSourceType, MethodTable* pTargetType);
internal static unsafe bool AreTypesAssignable(EETypePtr pSourceType, EETypePtr pTargetType)
=> AreTypesAssignable(pSourceType.ToPointer(), pTargetType.ToPointer());
[MethodImpl(MethodImplOptions.InternalCall)]
[RuntimeImport(RuntimeLibrary, "RhNewObject")]
- private static extern unsafe object RhNewObject(MethodTable* pEEType);
+ internal static extern unsafe object RhNewObject(MethodTable* pEEType);
internal static unsafe object RhNewObject(EETypePtr pEEType)
=> RhNewObject(pEEType.ToPointer());
return new EETypePtr(_value);
}
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal MethodTable* ToMethodTable()
+ {
+ return (MethodTable*)_value;
+ }
+
internal bool IsNull
{
get