Skip to content

Commit

Permalink
Complete TryUnBox
Browse files Browse the repository at this point in the history
  • Loading branch information
huoyaoyuan committed May 28, 2024
1 parent 527021c commit e7d843a
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 6 deletions.
19 changes: 17 additions & 2 deletions src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,22 @@ private unsafe void InternalSetValue(object? value, nint flattenedIndex)
// value class or primitive type

ref byte offsetDataRef = ref Unsafe.Add(ref arrayDataRef, flattenedIndex * pMethodTable->ComponentSize);
if (!RuntimeHelpers.TryUnboxInto(ref offsetDataRef, pElementMethodTable, value))
if (CastHelpers.IsInstanceOfAny(pElementMethodTable, value) != null)
{
if (pElementMethodTable->IsNullable)
{
RuntimeHelpers.Unbox_Nullable(ref offsetDataRef, pElementMethodTable, value);
}
else if (pElementMethodTable->ContainsGCPointers)
{
Buffer.BulkMoveWithWriteBarrier(ref offsetDataRef, ref value.GetRawData(), pElementMethodTable->GetNumInstanceFieldBytes());
}
else
{
SpanHelpers.Memmove(ref offsetDataRef, ref value.GetRawData(), pElementMethodTable->GetNumInstanceFieldBytes());
}
}
else
{
// Allow enum -> primitive conversion, disallow primitive -> enum conversion
MethodTable* thSrc = RuntimeHelpers.GetMethodTable(value);
Expand All @@ -707,7 +722,7 @@ private unsafe void InternalSetValue(object? value, nint flattenedIndex)
if (!RuntimeHelpers.CanPrimitiveWiden(srcType, targetType))
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_PrimitiveWiden);

PrimitiveWiden(ref Unsafe.Unbox<byte>(value), ref offsetDataRef, srcType, targetType);
PrimitiveWiden(ref value.GetRawData(), ref offsetDataRef, srcType, targetType);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,6 @@ internal static unsafe bool ObjectHasComponentSize(object obj)
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern unsafe void Unbox_Nullable(ref byte destination, MethodTable* toTypeHnd, object? obj);

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern unsafe bool TryUnboxInto(ref byte destination, MethodTable* toTypeHnd, object obj);

// Given an object reference, returns its MethodTable*.
//
// WARNING: The caller has to ensure that MethodTable* does not get unloaded. The most robust way
Expand Down
1 change: 0 additions & 1 deletion src/coreclr/vm/ecalllist.h
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,6 @@ FCFuncEnd()
#endif // FEATURE_COMINTEROP

FCFuncStart(gCastHelpers)
FCFuncElement("CanCastTo_NoCacheLookup", ::IsInstanceOfAny_NoCacheLookup)
FCFuncElement("IsInstanceOfAny_NoCacheLookup", ::IsInstanceOfAny_NoCacheLookup)
FCFuncElement("ChkCastAny_NoCacheLookup", ::ChkCastAny_NoCacheLookup)
FCFuncElement("Unbox_Helper", ::Unbox_Helper)
Expand Down

0 comments on commit e7d843a

Please sign in to comment.