Skip to content

Commit

Permalink
Move GetRefAny (with FCThrow) to managed
Browse files Browse the repository at this point in the history
  • Loading branch information
am11 committed Dec 3, 2024
1 parent 758bbc6 commit 6f3f4cc
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// 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.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
Expand All @@ -24,6 +25,9 @@ internal static void ThrowInvalidCastException(object fromType, void* toTypeHnd)
throw null!; // Provide hint to the inliner that this method does not return
}

[DoesNotReturn]
internal static void ThrowInvalidCastException() => throw new InvalidCastException();

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern object IsInstanceOfAny_NoCacheLookup(void* toTypeHnd, object obj);

Expand All @@ -33,6 +37,19 @@ internal static void ThrowInvalidCastException(object fromType, void* toTypeHnd)
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void WriteBarrier(ref object? dst, object? obj);

internal static ref byte GetRefAny(IntPtr clsHnd, TypedReference typedByRef)
{
// <TODO>@TODO right now we check for precisely the correct type.
// do we want to allow inheritance? (watch out since value
// classes inherit from object but do not normal object layout).</TODO>
if (clsHnd != typedByRef.Type)
{
ThrowInvalidCastException();
}

return ref typedByRef.Value;
}

// IsInstanceOf test used for unusual cases (naked type parameters, variant generic types)
// Unlike the IsInstanceOfInterface and IsInstanceOfClass functions,
// this test must deal with all kinds of type tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ public ref partial struct TypedReference
private readonly ref byte _value;
private readonly IntPtr _type;

internal readonly IntPtr Type => _type;
internal readonly ref byte Value => ref _value;

private TypedReference(ref byte target, RuntimeType type)
{
_value = ref target;
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/inc/jithelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
DYNAMICJITHELPER(CORINFO_HELP_UNBOX_TYPETEST,NULL, METHOD__CASTHELPERS__UNBOX_TYPETEST)
DYNAMICJITHELPER(CORINFO_HELP_UNBOX_NULLABLE,NULL, METHOD__CASTHELPERS__UNBOX_NULLABLE)

JITHELPER(CORINFO_HELP_GETREFANY, JIT_GetRefAny, METHOD__NIL)
DYNAMICJITHELPER(CORINFO_HELP_GETREFANY, NULL, METHOD__CASTHELPERS__GETREFANY)
DYNAMICJITHELPER(CORINFO_HELP_ARRADDR_ST, NULL, METHOD__CASTHELPERS__STELEMREF)
DYNAMICJITHELPER(CORINFO_HELP_LDELEMA_REF, NULL, METHOD__CASTHELPERS__LDELEMAREF)

Expand Down
5 changes: 3 additions & 2 deletions src/coreclr/vm/corelib.h
Original file line number Diff line number Diff line change
Expand Up @@ -1178,8 +1178,9 @@ DEFINE_METHOD(CASTHELPERS, UNBOX, Unbox, NoSig)
DEFINE_METHOD(CASTHELPERS, STELEMREF, StelemRef, SM_ArrObject_IntPtr_Obj_RetVoid)
DEFINE_METHOD(CASTHELPERS, LDELEMAREF, LdelemaRef, SM_ArrObject_IntPtr_PtrVoid_RetRefObj)
DEFINE_METHOD(CASTHELPERS, ARRAYTYPECHECK, ArrayTypeCheck, SM_Obj_Array_RetVoid)
DEFINE_METHOD(CASTHELPERS, UNBOX_NULLABLE, Unbox_Nullable, NoSig)
DEFINE_METHOD(CASTHELPERS, UNBOX_TYPETEST, Unbox_TypeTest, NoSig)
DEFINE_METHOD(CASTHELPERS, UNBOX_NULLABLE, Unbox_Nullable, NoSig)
DEFINE_METHOD(CASTHELPERS, UNBOX_TYPETEST, Unbox_TypeTest, NoSig)
DEFINE_METHOD(CASTHELPERS, GETREFANY, GetRefAny, NoSig)

DEFINE_CLASS(VIRTUALDISPATCHHELPERS, CompilerServices, VirtualDispatchHelpers)
DEFINE_METHOD(VIRTUALDISPATCHHELPERS, VIRTUALFUNCTIONPOINTER, VirtualFunctionPointer, NoSig)
Expand Down
18 changes: 0 additions & 18 deletions src/coreclr/vm/jithelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1382,24 +1382,6 @@ HCIMPL2(Object*, JIT_Box, CORINFO_CLASS_HANDLE type, void* unboxedData)
}
HCIMPLEND

/*************************************************************/
HCIMPL2_IV(LPVOID, JIT_GetRefAny, CORINFO_CLASS_HANDLE type, TypedByRef typedByRef)
{
FCALL_CONTRACT;

TypeHandle clsHnd(type);
// <TODO>@TODO right now we check for precisely the correct type.
// do we want to allow inheritance? (watch out since value
// classes inherit from object but do not normal object layout).</TODO>
if (clsHnd != typedByRef.type) {
FCThrow(kInvalidCastException);
}

return(typedByRef.data);
}
HCIMPLEND


/*************************************************************/
HCIMPL2(BOOL, JIT_IsInstanceOfException, CORINFO_CLASS_HANDLE type, Object* obj)
{
Expand Down

0 comments on commit 6f3f4cc

Please sign in to comment.