From 428f66c9e8c1a21e3b839171845d0fb7e8ae5d82 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Fri, 16 Aug 2024 20:16:23 -0700 Subject: [PATCH 1/2] Remove legacy API for MCG support --- .../System.Private.CoreLib.csproj | 1 - .../CompilerServices/ICastableHelpers.cs | 25 -------- .../RuntimeHelpers.CoreCLR.cs | 1 - src/coreclr/clr.featuredefines.props | 2 - src/coreclr/clrdefinitions.cmake | 1 - src/coreclr/inc/dacvars.h | 4 -- src/coreclr/vm/.vscode/c_cpp_properties.json | 1 - src/coreclr/vm/appdomain.cpp | 4 -- src/coreclr/vm/callconvbuilder.cpp | 44 ++++---------- src/coreclr/vm/corelib.h | 9 --- src/coreclr/vm/jithelpers.cpp | 29 --------- src/coreclr/vm/jitinterface.cpp | 4 +- src/coreclr/vm/metasig.h | 6 -- src/coreclr/vm/method.cpp | 8 --- src/coreclr/vm/methodtable.cpp | 58 +----------------- src/coreclr/vm/methodtable.h | 9 +-- src/coreclr/vm/methodtablebuilder.cpp | 7 --- src/coreclr/vm/prestub.cpp | 6 +- src/coreclr/vm/vars.cpp | 5 -- src/coreclr/vm/vars.hpp | 5 -- src/coreclr/vm/virtualcallstub.cpp | 42 +------------ src/coreclr/vm/wellknownattributes.h | 3 - .../src/CompatibilitySuppressions.xml | 4 -- .../System.Private.CoreLib.Shared.projitems | 1 - .../Runtime/CompilerServices/ICastable.cs | 60 ------------------- 25 files changed, 21 insertions(+), 318 deletions(-) delete mode 100644 src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/ICastableHelpers.cs delete mode 100644 src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ICastable.cs diff --git a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj index ae68b714729953..b7890db6cffe04 100644 --- a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -196,7 +196,6 @@ - diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/ICastableHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/ICastableHelpers.cs deleted file mode 100644 index ca9f73a5c667e8..00000000000000 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/ICastableHelpers.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics.CodeAnalysis; - -namespace System.Runtime.CompilerServices -{ - /// - /// Helpers that allows VM to call into ICastable methods without having to deal with RuntimeTypeHandle. - /// RuntimeTypeHandle is a struct and is always passed in stack in x86, which our VM call helpers don't - /// particularly like. - /// - internal static class ICastableHelpers - { - internal static bool IsInstanceOfInterface(ICastable castable, RuntimeType type, [NotNullWhen(true)] out Exception? castError) - { - return castable.IsInstanceOfInterface(new RuntimeTypeHandle(type), out castError); - } - - internal static RuntimeType GetImplType(ICastable castable, RuntimeType interfaceType) - { - return castable.GetImplType(new RuntimeTypeHandle(interfaceType)).GetRuntimeType(); - } - } -} diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs index 88e07e8d388ced..3057f8d730d6de 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs @@ -682,7 +682,6 @@ internal unsafe struct MethodTable // Types that require non-trivial interface cast have this bit set in the category private const uint enum_flag_NonTrivialInterfaceCast = 0x00080000 // enum_flag_Category_Array | 0x40000000 // enum_flag_ComObject - | 0x00400000 // enum_flag_ICastable; | 0x10000000 // enum_flag_IDynamicInterfaceCastable; | 0x00040000; // enum_flag_Category_ValueType diff --git a/src/coreclr/clr.featuredefines.props b/src/coreclr/clr.featuredefines.props index 1f513b1354d7ae..565cf03ee77368 100644 --- a/src/coreclr/clr.featuredefines.props +++ b/src/coreclr/clr.featuredefines.props @@ -2,7 +2,6 @@ true true - true true true true @@ -35,7 +34,6 @@ $(DefineConstants);FEATURE_PERFTRACING $(DefineConstants);FEATURE_EVENTSOURCE_XPLAT $(DefineConstants);FEATURE_TYPEEQUIVALENCE - $(DefineConstants);FEATURE_ICASTABLE $(DefineConstants);FEATURE_EH_FUNCLETS $(DefineConstants);PROFILING_SUPPORTED diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index 0a7a73bd4f1061..222eead41676c1 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -122,7 +122,6 @@ endif(CLR_CMAKE_TARGET_LINUX) if(NOT CLR_CMAKE_TARGET_NETBSD) add_definitions(-DFEATURE_HIJACK) endif(NOT CLR_CMAKE_TARGET_NETBSD) -add_definitions(-DFEATURE_ICASTABLE) if (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_ARM64)) add_definitions(-DFEATURE_INTEROP_DEBUGGING) endif (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_ARM64)) diff --git a/src/coreclr/inc/dacvars.h b/src/coreclr/inc/dacvars.h index 03995176313c24..b2b983f1078a98 100644 --- a/src/coreclr/inc/dacvars.h +++ b/src/coreclr/inc/dacvars.h @@ -175,10 +175,6 @@ DEFINE_DACVAR(UNKNOWN_POINTER_TYPE, dac__g_pBaseCOMObject, ::g_pBaseCOMObject) DEFINE_DACVAR(UNKNOWN_POINTER_TYPE, dac__g_pIDynamicInterfaceCastableInterface, ::g_pIDynamicInterfaceCastableInterface) -#ifdef FEATURE_ICASTABLE -DEFINE_DACVAR(UNKNOWN_POINTER_TYPE, dac__g_pICastableInterface, ::g_pICastableInterface) -#endif // FEATURE_ICASTABLE - DEFINE_DACVAR(UNKNOWN_POINTER_TYPE, dac__g_pObjectFinalizerMD, ::g_pObjectFinalizerMD) DEFINE_DACVAR(bool, dac__g_fProcessDetach, ::g_fProcessDetach) diff --git a/src/coreclr/vm/.vscode/c_cpp_properties.json b/src/coreclr/vm/.vscode/c_cpp_properties.json index 30f8ba3e8f5c44..c61fa10a35d428 100644 --- a/src/coreclr/vm/.vscode/c_cpp_properties.json +++ b/src/coreclr/vm/.vscode/c_cpp_properties.json @@ -53,7 +53,6 @@ "FEATURE_DEFAULT_INTERFACES", "FEATURE_EVENT_TRACE=1", "FEATURE_HIJACK", - "FEATURE_ICASTABLE", "FEATURE_INTEROP_DEBUGGING", "FEATURE_ISYM_READER", "FEATURE_MULTICASTSTUB_AS_IL", diff --git a/src/coreclr/vm/appdomain.cpp b/src/coreclr/vm/appdomain.cpp index 125ba5f22cc618..5f31e0c9305e9d 100644 --- a/src/coreclr/vm/appdomain.cpp +++ b/src/coreclr/vm/appdomain.cpp @@ -1268,10 +1268,6 @@ void SystemDomain::LoadBaseSystemClasses() } #endif - #ifdef FEATURE_ICASTABLE - g_pICastableInterface = CoreLibBinder::GetClass(CLASS__ICASTABLE); - #endif // FEATURE_ICASTABLE - #ifdef FEATURE_EH_FUNCLETS g_pEHClass = CoreLibBinder::GetClass(CLASS__EH); g_pExceptionServicesInternalCallsClass = CoreLibBinder::GetClass(CLASS__EXCEPTIONSERVICES_INTERNALCALLS); diff --git a/src/coreclr/vm/callconvbuilder.cpp b/src/coreclr/vm/callconvbuilder.cpp index d68ac7f023ec3d..58a14e3cc733f9 100644 --- a/src/coreclr/vm/callconvbuilder.cpp +++ b/src/coreclr/vm/callconvbuilder.cpp @@ -490,21 +490,14 @@ bool CallConv::TryGetCallingConventionFromUnmanagedCallersOnly(_In_ MethodDesc* BYTE* pData = NULL; LONG cData = 0; - bool nativeCallableInternalData = false; HRESULT hr = pMD->GetCustomAttribute(WellKnownAttribute::UnmanagedCallersOnly, (const VOID **)(&pData), (ULONG *)&cData); - if (hr == S_FALSE) - { - hr = pMD->GetCustomAttribute(WellKnownAttribute::NativeCallableInternal, (const VOID **)(&pData), (ULONG *)&cData); - nativeCallableInternalData = SUCCEEDED(hr); - } - IfFailThrow(hr); _ASSERTE(cData > 0); CustomAttributeParser ca(pData, cData); - // UnmanagedCallersOnly and NativeCallableInternal each + // UnmanagedCallersOnly each // have optional named arguments. CaNamedArg namedArgs[2]; @@ -512,15 +505,8 @@ bool CallConv::TryGetCallingConventionFromUnmanagedCallersOnly(_In_ MethodDesc* CaType caCallConvs; // Define attribute specific optional named properties - if (nativeCallableInternalData) - { - namedArgs[0].InitI4FieldEnum("CallingConvention", "System.Runtime.InteropServices.CallingConvention", (ULONG)(CorPinvokeMap)0); - } - else - { - caCallConvs.Init(SERIALIZATION_TYPE_SZARRAY, SERIALIZATION_TYPE_TYPE, SERIALIZATION_TYPE_UNDEFINED, NULL, 0); - namedArgs[0].Init("CallConvs", SERIALIZATION_TYPE_SZARRAY, caCallConvs); - } + caCallConvs.Init(SERIALIZATION_TYPE_SZARRAY, SERIALIZATION_TYPE_TYPE, SERIALIZATION_TYPE_UNDEFINED, NULL, 0); + namedArgs[0].Init("CallConvs", SERIALIZATION_TYPE_SZARRAY, caCallConvs); // Define common optional named properties CaTypeCtor caEntryPoint(SERIALIZATION_TYPE_STRING); @@ -542,25 +528,17 @@ bool CallConv::TryGetCallingConventionFromUnmanagedCallersOnly(_In_ MethodDesc* if (namedArgs[0].val.type.tag == SERIALIZATION_TYPE_UNDEFINED) return false; - CorInfoCallConvExtension callConvLocal; - if (nativeCallableInternalData) + CallConvBuilder builder; + if (!TryGetCallingConventionFromTypeArray(&namedArgs[0].val, &builder)) { - callConvLocal = (CorInfoCallConvExtension)(namedArgs[0].val.u4 << 8); + // We found a second base calling convention. + return false; } - else - { - CallConvBuilder builder; - if (!TryGetCallingConventionFromTypeArray(&namedArgs[0].val, &builder)) - { - // We found a second base calling convention. - return false; - } - callConvLocal = builder.GetCurrentCallConv(); - if (callConvLocal == CallConvBuilder::UnsetValue) - { - callConvLocal = CallConv::GetDefaultUnmanagedCallingConvention(); - } + CorInfoCallConvExtension callConvLocal = builder.GetCurrentCallConv(); + if (callConvLocal == CallConvBuilder::UnsetValue) + { + callConvLocal = CallConv::GetDefaultUnmanagedCallingConvention(); } *pCallConv = callConvLocal; diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 0adc92baf3927c..745d762e832209 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -1124,15 +1124,6 @@ DEFINE_FIELD_U(_condition, ContractExceptionObject, _Condition) DEFINE_CLASS(MODULEBASE, Reflection, Module) -#ifdef FEATURE_ICASTABLE -DEFINE_CLASS(ICASTABLE, CompilerServices, ICastable) - -DEFINE_CLASS(ICASTABLEHELPERS, CompilerServices, ICastableHelpers) -DEFINE_METHOD(ICASTABLEHELPERS, ISINSTANCEOF, IsInstanceOfInterface, SM_ICastable_RtType_RefException_RetBool) -DEFINE_METHOD(ICASTABLEHELPERS, GETIMPLTYPE, GetImplType, SM_ICastable_RtType_RetRtType) - -#endif // FEATURE_ICASTABLE - DEFINE_CLASS(STACKALLOCATEDBOX, CompilerServices, StackAllocatedBox`1) DEFINE_CLASS(UTF8STRINGMARSHALLER, Marshalling, Utf8StringMarshaller) diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index b365309257dbc3..876d2af8d63ec3 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -1080,35 +1080,6 @@ BOOL ObjIsInstanceOfCore(Object *pObject, TypeHandle toTypeHnd, BOOL throwCastEx } else #endif // FEATURE_COMINTEROP -#ifdef FEATURE_ICASTABLE - // If type implements ICastable interface we give it a chance to tell us if it can be casted - // to a given type. - if (pMT->IsICastable()) - { - // Make actual call to ICastableHelpers.IsInstanceOfInterface(obj, interfaceTypeObj, out exception) - OBJECTREF exception = NULL; - GCPROTECT_BEGIN(exception); - - PREPARE_NONVIRTUAL_CALLSITE(METHOD__ICASTABLEHELPERS__ISINSTANCEOF); - - OBJECTREF managedType = toTypeHnd.GetManagedClassObject(); //GC triggers - - DECLARE_ARGHOLDER_ARRAY(args, 3); - args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(obj); - args[ARGNUM_1] = OBJECTREF_TO_ARGHOLDER(managedType); - args[ARGNUM_2] = PTR_TO_ARGHOLDER(&exception); - - CALL_MANAGED_METHOD(fCast, BOOL, args); - INDEBUG(managedType = NULL); // managedType isn't protected during the call - - if (!fCast && throwCastException && exception != NULL) - { - RealCOMPlusThrow(exception); - } - GCPROTECT_END(); //exception - } - else -#endif // FEATURE_ICASTABLE if (pMT->IsIDynamicInterfaceCastable()) { fCast = DynamicInterfaceCastable::IsInstanceOf(&obj, toTypeHnd, throwCastException); diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 9c76cf0e7b08b0..315cd5481d3aec 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -4209,8 +4209,8 @@ TypeCompareState CEEInfo::compareTypesForCast( else #endif // FEATURE_COMINTEROP - // If casting from ICastable or IDynamicInterfaceCastable, don't try to optimize - if (fromHnd.GetMethodTable()->IsICastable() || fromHnd.GetMethodTable()->IsIDynamicInterfaceCastable()) + // If casting from IDynamicInterfaceCastable, don't try to optimize + if (fromHnd.GetMethodTable()->IsIDynamicInterfaceCastable()) { result = TypeCompareState::May; } diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index 9a409e100a1e56..0a9f50a7a912cd 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -577,12 +577,6 @@ DEFINE_METASIG(IM(PtrVoid_RetVoid, P(v), v)) DEFINE_METASIG_T(IM(PtrCopyConstructorCookie_RetVoid, P(g(COPY_CONSTRUCTOR_COOKIE)), v)) #endif // defined(TARGET_X86) && defined(TARGET_WINDOWS) - -#ifdef FEATURE_ICASTABLE -DEFINE_METASIG_T(SM(ICastable_RtType_RefException_RetBool, C(ICASTABLE) C(CLASS) r(C(EXCEPTION)), F)) -DEFINE_METASIG_T(SM(ICastable_RtType_RetRtType, C(ICASTABLE) C(CLASS), C(CLASS))) -#endif // FEATURE_ICASTABLE - DEFINE_METASIG_T(SM(IDynamicInterfaceCastable_RuntimeType_Bool_RetBool, C(IDYNAMICINTERFACECASTABLE) C(CLASS) F, F)) DEFINE_METASIG_T(SM(IDynamicInterfaceCastable_RuntimeType_RetRtType, C(IDYNAMICINTERFACECASTABLE) C(CLASS), C(CLASS))) diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index 8b7239896a0ea6..d944116216523c 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -3517,14 +3517,6 @@ BOOL MethodDesc::HasUnmanagedCallersOnlyAttribute() WellKnownAttribute::UnmanagedCallersOnly, nullptr, nullptr); - if (hr != S_OK) - { - // See https://github.com/dotnet/runtime/issues/37622 - hr = GetCustomAttribute( - WellKnownAttribute::NativeCallableInternal, - nullptr, - nullptr); - } return (hr == S_OK) ? TRUE : FALSE; } diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 5e0ba6c09bfd5e..528b5950167e14 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -375,24 +375,6 @@ void MethodTable::SetComObjectType() SetFlag(enum_flag_ComObject); } -#ifdef FEATURE_ICASTABLE -void MethodTable::SetICastable() -{ - LIMITED_METHOD_CONTRACT; - SetFlag(enum_flag_ICastable); -} -#endif - -BOOL MethodTable::IsICastable() -{ - LIMITED_METHOD_DAC_CONTRACT; -#ifdef FEATURE_ICASTABLE - return GetFlag(enum_flag_ICastable); -#else - return FALSE; -#endif -} - void MethodTable::SetIDynamicInterfaceCastable() { LIMITED_METHOD_CONTRACT; @@ -499,42 +481,6 @@ PTR_MethodTable InterfaceInfo_t::GetApproxMethodTable(Module * pContainingModule MethodTable *pServerMT = (*pServer)->GetMethodTable(); PREFIX_ASSUME(pServerMT != NULL); -#ifdef FEATURE_ICASTABLE - // In case of ICastable, instead of trying to find method implementation in the real object type - // we call GetMethodDescForInterfaceMethod() again with whatever type it returns. - // It allows objects that implement ICastable to mimic behavior of other types. - if (pServerMT->IsICastable() && - !pItfMD->HasMethodInstantiation() && - !TypeHandle(pServerMT).CanCastTo(ownerType)) // we need to make sure object doesn't implement this interface in a natural way - { - GCStress::MaybeTrigger(); - - // Make call to ICastableHelpers.GetImplType(obj, interfaceTypeObj) - PREPARE_NONVIRTUAL_CALLSITE(METHOD__ICASTABLEHELPERS__GETIMPLTYPE); - - OBJECTREF ownerManagedType = ownerType.GetManagedClassObject(); //GC triggers - - DECLARE_ARGHOLDER_ARRAY(args, 2); - args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(*pServer); - args[ARGNUM_1] = OBJECTREF_TO_ARGHOLDER(ownerManagedType); - - OBJECTREF impTypeObj = NULL; - CALL_MANAGED_METHOD_RETREF(impTypeObj, OBJECTREF, args); - - INDEBUG(ownerManagedType = NULL); //ownerManagedType wasn't protected during the call - if (impTypeObj == NULL) // GetImplType returns default(RuntimeTypeHandle) - { - COMPlusThrow(kEntryPointNotFoundException); - } - - ReflectClassBaseObject* resultTypeObj = ((ReflectClassBaseObject*)OBJECTREFToObject(impTypeObj)); - TypeHandle resultTypeHnd = resultTypeObj->GetType(); - MethodTable *pResultMT = resultTypeHnd.GetMethodTable(); - - RETURN(pResultMT->GetMethodDescForInterfaceMethod(ownerType, pItfMD, TRUE /* throwOnConflict */)); - } -#endif - // For IDynamicInterfaceCastable, instead of trying to find method implementation in the real object type // we call GetInterfaceImplementation on the object and call GetMethodDescForInterfaceMethod // with whatever type it returns. @@ -1462,8 +1408,8 @@ BOOL MethodTable::CanCastTo(MethodTable* pTargetMT, TypeHandlePairList* pVisited CanCastToClass(pTargetMT, pVisited); // We only consider type-based conversion rules here. - // Therefore a negative result cannot rule out convertibility for ICastable, IDynamicInterfaceCastable, and COM objects - if (result || !(pTargetMT->IsInterface() && (this->IsComObjectType() || this->IsICastable() || this->IsIDynamicInterfaceCastable()))) + // Therefore a negative result cannot rule out convertibility for IDynamicInterfaceCastable and COM objects + if (result || !(pTargetMT->IsInterface() && (this->IsComObjectType() || this->IsIDynamicInterfaceCastable()))) { CastCache::TryAddToCache(this, pTargetMT, (BOOL)result); } diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 79334cb03201fd..9e209f7c5e50d2 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -1031,12 +1031,6 @@ class MethodTable // mark the class type as COM object class void SetComObjectType(); -#ifdef FEATURE_ICASTABLE - void SetICastable(); -#endif - - BOOL IsICastable(); // This type implements ICastable interface - void SetIDynamicInterfaceCastable(); BOOL IsIDynamicInterfaceCastable(); @@ -3697,7 +3691,7 @@ public : enum_flag_HasFinalizer = 0x00100000, // instances require finalization. GC depends on this bit. enum_flag_Collectible = 0x00200000, // GC depends on this bit. - enum_flag_ICastable = 0x00400000, // class implements ICastable interface + // enum_flag_unused = 0x00400000, #ifdef FEATURE_64BIT_ALIGNMENT enum_flag_RequiresAlign8 = 0x00800000, // Type requires 8-byte alignment (only set on platforms that require this and don't get it implicitly) @@ -3717,7 +3711,6 @@ public : // Types that require non-trivial interface cast have this bit set in the category enum_flag_NonTrivialInterfaceCast = enum_flag_Category_Array | enum_flag_ComObject - | enum_flag_ICastable | enum_flag_IDynamicInterfaceCastable | enum_flag_Category_ValueType diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index 6faa9972c3332f..ebe68bafaad892 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -1998,13 +1998,6 @@ MethodTableBuilder::BuildMethodTableThrowing( if (!IsValueClass()) { -#ifdef FEATURE_ICASTABLE - if (g_pICastableInterface != NULL && pMT->CanCastToInterface(g_pICastableInterface)) - { - pMT->SetICastable(); - } -#endif // FEATURE_ICASTABLE - if (g_pIDynamicInterfaceCastableInterface != NULL && pMT->CanCastToInterface(g_pIDynamicInterfaceCastableInterface)) { pMT->SetIDynamicInterfaceCastable(); diff --git a/src/coreclr/vm/prestub.cpp b/src/coreclr/vm/prestub.cpp index de1f7fd09007ba..3fbeffa8620fcb 100644 --- a/src/coreclr/vm/prestub.cpp +++ b/src/coreclr/vm/prestub.cpp @@ -2662,7 +2662,7 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method { pDispatchingMT = curobj->GetMethodTable(); - if (pDispatchingMT->IsICastable() || pDispatchingMT->IsIDynamicInterfaceCastable()) + if (pDispatchingMT->IsIDynamicInterfaceCastable()) { MethodTable* pMDMT = pMD->GetMethodTable(); TypeHandle objectType(pDispatchingMT); @@ -2672,7 +2672,7 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method INDEBUG(curobj = NULL); // curobj is unprotected and CanCastTo() can trigger GC if (!objectType.CanCastTo(methodType)) { - // Apparently ICastable magic was involved when we chose this method to be called + // Apparently IDynamicInterfaceCastable magic was involved when we chose this method to be called // that's why we better stick to the MethodTable it belongs to, otherwise // DoPrestub() will fail not being able to find implementation for pMD in pDispatchingMT. @@ -3534,7 +3534,7 @@ static PCODE getHelperForStaticBase(Module * pModule, CORCOMPILE_FIXUP_BLOB_KIND bool threadStatic = (kind == ENCODE_THREAD_STATIC_BASE_NONGC_HELPER || kind == ENCODE_THREAD_STATIC_BASE_GC_HELPER); CorInfoHelpFunc helper; - + if (threadStatic) { if (GCStatic) diff --git a/src/coreclr/vm/vars.cpp b/src/coreclr/vm/vars.cpp index 7ff76d014a4ec9..ebd5310e40e6dc 100644 --- a/src/coreclr/vm/vars.cpp +++ b/src/coreclr/vm/vars.cpp @@ -72,11 +72,6 @@ GPTR_IMPL(MethodTable, g_pBaseCOMObject); #endif GPTR_IMPL(MethodTable, g_pIDynamicInterfaceCastableInterface); - -#ifdef FEATURE_ICASTABLE -GPTR_IMPL(MethodTable, g_pICastableInterface); -#endif // FEATURE_ICASTABLE - GPTR_IMPL(MethodDesc, g_pObjectFinalizerMD); GPTR_IMPL(Thread,g_pFinalizerThread); diff --git a/src/coreclr/vm/vars.hpp b/src/coreclr/vm/vars.hpp index 5814aa1ee83483..528d513e9d7b3f 100644 --- a/src/coreclr/vm/vars.hpp +++ b/src/coreclr/vm/vars.hpp @@ -350,11 +350,6 @@ GPTR_DECL(MethodTable, g_pBaseCOMObject); #endif GPTR_DECL(MethodTable, g_pIDynamicInterfaceCastableInterface); - -#ifdef FEATURE_ICASTABLE -GPTR_DECL(MethodTable, g_pICastableInterface); -#endif // FEATURE_ICASTABLE - GPTR_DECL(MethodDesc, g_pObjectFinalizerMD); #ifdef FEATURE_INTEROP_DEBUGGING diff --git a/src/coreclr/vm/virtualcallstub.cpp b/src/coreclr/vm/virtualcallstub.cpp index 5f7754e3f808f4..44bbb7e15d8615 100644 --- a/src/coreclr/vm/virtualcallstub.cpp +++ b/src/coreclr/vm/virtualcallstub.cpp @@ -1570,7 +1570,6 @@ PCODE VirtualCallStubManager::ResolveWorker(StubCallSite* pCallSite, #if defined(_DEBUG) if (!objectType->IsComObjectType() - && !objectType->IsICastable() && !objectType->IsIDynamicInterfaceCastable()) { CONSISTENCY_CHECK(!MethodTable::GetMethodDescForSlotAddress(target)->IsGenericMethodDefinition()); @@ -1989,41 +1988,6 @@ VirtualCallStubManager::Resolver( fShouldPatch = TRUE; } #endif // FEATURE_COMINTEROP -#ifdef FEATURE_ICASTABLE - else if (pMT->IsICastable() && protectedObj != NULL && *protectedObj != NULL) - { - GCStress::MaybeTrigger(); - - // In case of ICastable, instead of trying to find method implementation in the real object type - // we call Resolver() again with whatever type it returns. - // It allows objects that implement ICastable to mimic behavior of other types. - MethodTable * pTokenMT = GetTypeFromToken(token); - - // Make call to ICastableHelpers.GetImplType(this, interfaceTypeObj) - PREPARE_NONVIRTUAL_CALLSITE(METHOD__ICASTABLEHELPERS__GETIMPLTYPE); - - OBJECTREF tokenManagedType = pTokenMT->GetManagedClassObject(); //GC triggers - - DECLARE_ARGHOLDER_ARRAY(args, 2); - args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(*protectedObj); - args[ARGNUM_1] = OBJECTREF_TO_ARGHOLDER(tokenManagedType); - - OBJECTREF impTypeObj = NULL; - CALL_MANAGED_METHOD_RETREF(impTypeObj, OBJECTREF, args); - - INDEBUG(tokenManagedType = NULL); //tokenManagedType wasn't protected during the call - if (impTypeObj == NULL) // GetImplType returns default(RuntimeTypeHandle) - { - COMPlusThrow(kEntryPointNotFoundException); - } - - ReflectClassBaseObject* resultTypeObj = ((ReflectClassBaseObject*)OBJECTREFToObject(impTypeObj)); - TypeHandle resultTypeHnd = resultTypeObj->GetType(); - MethodTable *pResultMT = resultTypeHnd.GetMethodTable(); - - return Resolver(pResultMT, token, protectedObj, ppTarget, throwOnConflict); - } -#endif // FEATURE_ICASTABLE else if (pMT->IsIDynamicInterfaceCastable() && protectedObj != NULL && *protectedObj != NULL @@ -2234,8 +2198,7 @@ VirtualCallStubManager::GetTarget( // No match, now do full resolve BOOL fPatch; - // TODO: passing NULL as protectedObj here can lead to incorrect behavior for ICastable objects - // We need to review if this is the case and refactor this code if we want ICastable to become officially supported + // TODO: passing NULL as protectedObj here can lead to incorrect behavior for IDynamicInterfaceCastable objects fPatch = Resolver(pMT, token, NULL, &target, throwOnConflict); _ASSERTE(!throwOnConflict || target != (PCODE)NULL); @@ -3814,8 +3777,7 @@ MethodDesc *VirtualCallStubManagerManager::Entry2MethodDesc( DispatchToken token(VirtualCallStubManager::GetTokenFromStubQuick(pMgr, stubStartAddress, sk)); PCODE target = (PCODE)NULL; - // TODO: passing NULL as protectedObj here can lead to incorrect behavior for ICastable objects - // We need to review if this is the case and refactor this code if we want ICastable to become officially supported + // TODO: passing NULL as protectedObj here can lead to incorrect behavior for IDynamicInterfaceCastable objects VirtualCallStubManager::Resolver(pMT, token, NULL, &target, TRUE /* throwOnConflict */); return pMT->GetMethodDescForSlotAddress(target); diff --git a/src/coreclr/vm/wellknownattributes.h b/src/coreclr/vm/wellknownattributes.h index 85a747b2c9a948..aa7b9396149f4d 100644 --- a/src/coreclr/vm/wellknownattributes.h +++ b/src/coreclr/vm/wellknownattributes.h @@ -29,7 +29,6 @@ enum class WellKnownAttribute : DWORD ManagedToNativeComInteropStub, UnmanagedCallConv, UnmanagedCallersOnly, - NativeCallableInternal, // This is needed to support MCG scenarios TypeIdentifier, UnmanagedFunctionPointer, ThreadStatic, @@ -92,8 +91,6 @@ inline const char *GetWellKnownAttributeName(WellKnownAttribute attribute) return "System.Runtime.InteropServices.UnmanagedCallConvAttribute"; case WellKnownAttribute::UnmanagedCallersOnly: return "System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute"; - case WellKnownAttribute::NativeCallableInternal: - return "System.Runtime.InteropServices.NativeCallableInternalAttribute"; case WellKnownAttribute::TypeIdentifier: return "System.Runtime.InteropServices.TypeIdentifierAttribute"; case WellKnownAttribute::UnmanagedFunctionPointer: diff --git a/src/libraries/System.Private.CoreLib/src/CompatibilitySuppressions.xml b/src/libraries/System.Private.CoreLib/src/CompatibilitySuppressions.xml index 6ee3efba01f6e4..413297c1857c92 100644 --- a/src/libraries/System.Private.CoreLib/src/CompatibilitySuppressions.xml +++ b/src/libraries/System.Private.CoreLib/src/CompatibilitySuppressions.xml @@ -5,10 +5,6 @@ CP0001 T:Internal.Console - - CP0001 - T:System.Runtime.CompilerServices.ICastable - CP0002 F:System.Resources.ResourceManager.BaseNameField diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 412fb8ba8b8644..d920dc227a376e 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -855,7 +855,6 @@ - diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ICastable.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ICastable.cs deleted file mode 100644 index ae117637668eb2..00000000000000 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ICastable.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics.CodeAnalysis; - -namespace System.Runtime.CompilerServices -{ - /// - /// Support for dynamic interface casting. Specifically implementing this interface on a type will allow the - /// type to support interfaces (for the purposes of casting and interface dispatch) that do not appear in its - /// interface map. - /// - public interface ICastable - { - // This is called if casting this object to the given interface type would otherwise fail. Casting - // here means the IL isinst and castclass instructions in the case where they are given an interface - // type as the target type. - // - // A return value of true indicates the cast is valid. - // - // If false is returned when this is called as part of a castclass then the usual InvalidCastException - // will be thrown unless an alternate exception is assigned to the castError output parameter. This - // parameter is ignored on successful casts or during the evaluation of an isinst (which returns null - // rather than throwing on error). - // - // No exception should be thrown from this method (it will cause unpredictable effects, including the - // possibility of an immediate failfast). - // - // The results of this call are not cached, so it is advisable to provide a performant implementation. - // - // The results of this call should be invariant for the same class, interface type pair. That is - // because this is the only guard placed before an interface invocation at runtime. If a type decides - // it no longer wants to implement a given interface it has no way to synchronize with callers that - // have already cached this relationship and can invoke directly via the interface pointer. - bool IsInstanceOfInterface(RuntimeTypeHandle interfaceType, [NotNullWhen(true)] out Exception? castError); - - // This is called as part of the interface dispatch mechanism when the dispatcher logic cannot find - // the given interface type in the interface map of this object. - // - // It allows the implementor to return an alternate class type which does implement the interface. The - // interface lookup shall be performed again on this type (failure to find the interface this time - // resulting in a fail fast) and the corresponding implemented method on that class called instead. - // - // Naturally, since the call is dispatched to a method on a class which does not match the type of the - // this pointer, extreme care must be taken in the implementation of the interface methods of this - // surrogate type. - // - // No exception should be thrown from this method (it will cause unpredictable effects, including the - // possibility of an immediate failfast). - // - // There is no error path defined here. By construction all interface dispatches will already have - // been verified via the castclass/isinst mechanism (and thus a call to IsInstanceOfInterface above) - // so this method is expected to succeed in all cases. The contract for interface dispatch does not - // include any errors from the infrastructure, of which this is a part. - // - // The results of this lookup are cached so computation of the result is not as perf-sensitive as - // IsInstanceOfInterface. - RuntimeTypeHandle GetImplType(RuntimeTypeHandle interfaceType); - } -} From 48f7588ea896e06f8ce55315432814b5958d5638 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Fri, 16 Aug 2024 20:29:47 -0700 Subject: [PATCH 2/2] Remove ICastable tests. --- src/tests/Interop/ICastable/Castable.cs | 210 ------------------ src/tests/Interop/ICastable/Castable.csproj | 10 - .../ICastable/ICastable.CoreLib.csproj | 22 -- src/tests/issues.targets | 3 - 4 files changed, 245 deletions(-) delete mode 100644 src/tests/Interop/ICastable/Castable.cs delete mode 100644 src/tests/Interop/ICastable/Castable.csproj delete mode 100644 src/tests/Interop/ICastable/ICastable.CoreLib.csproj diff --git a/src/tests/Interop/ICastable/Castable.cs b/src/tests/Interop/ICastable/Castable.cs deleted file mode 100644 index fcefb7e025e160..00000000000000 --- a/src/tests/Interop/ICastable/Castable.cs +++ /dev/null @@ -1,210 +0,0 @@ -// 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.Runtime.CompilerServices; -using Xunit; - -public interface IRetArg -{ - T ReturnArg(T t); -} - -public interface IRetThis -{ - IRetThis ReturnThis(); - Type GetMyType(); -} - - -public interface IUnimplemented -{ - void UnimplementedMethod(); -} - -public interface IExtra -{ - int InnocentMethod(); -} - -public class CastableException : Exception {}; - - -public class RetArgImpl: IRetArg -{ - public string ReturnArg(string t) - { - Console.WriteLine("ReturnArg has been called."); - return t; - } -} - -public class GenRetArgImpl: IRetArg -{ - public T ReturnArg(T t) - { - Console.WriteLine(String.Format("Generic ReturnArg has been called. My type is {0}", GetType())); - return t; - } -} - - -public class RetThisImpl: IRetThis -{ - public IRetThis ReturnThis() - { - Console.WriteLine("RetThis has been called."); - return this; - } - - public Type GetMyType() - { - Console.WriteLine(String.Format("GetMyType has been called. My type is {0}", GetType())); - return GetType(); - } -} - - -public class Castable : ICastable, IExtra -{ - private Dictionary _interface2impl; - - public Castable(Dictionary interface2impl) - { - _interface2impl = interface2impl; - } - - public bool IsInstanceOfInterface(RuntimeTypeHandle interfaceType, out Exception castError) - { - Console.WriteLine(String.Format("IsInstanceOfInterface has been called for type {0}", Type.GetTypeFromHandle(interfaceType))); - if (_interface2impl == null) - { - castError = new CastableException(); - return false; - } - castError = null; - return _interface2impl.ContainsKey(Type.GetTypeFromHandle(interfaceType)); - } - - public RuntimeTypeHandle GetImplType(RuntimeTypeHandle interfaceType) - { - Console.WriteLine(String.Format("GetImplType has been called for type {0}", Type.GetTypeFromHandle(interfaceType))); - return _interface2impl[Type.GetTypeFromHandle(interfaceType)].TypeHandle; - } - - public int InnocentMethod() - { - Console.WriteLine(String.Format("InnocentMethod has been called. My type is {0}", GetType())); - return 3; - } -} - -public class BadCastable : ICastable -{ - public bool IsInstanceOfInterface(RuntimeTypeHandle interfaceType, out Exception castError) - { - castError = null; - return true; - } - - public RuntimeTypeHandle GetImplType(RuntimeTypeHandle interfaceType) - { - return default(RuntimeTypeHandle); - } -} - -public class CastableTests -{ - public static void Assert(bool value, string message) - { - Xunit.Assert.True(value, message); - } - - [Fact] - [SkipOnMono("ICastable is unsupported on Mono")] - public static void Test() - { - //Console.WriteLine("Execution started. Attach debugger and press enter."); - //Console.ReadLine(); - - try - { - object implProxy = new Castable( - new Dictionary() - { - { typeof(IRetArg), typeof(RetArgImpl) }, - { typeof(IRetArg), typeof(GenRetArgImpl) }, - { typeof(IRetThis), typeof(RetThisImpl) }, - { typeof(IExtra), null }, //we should never use it - } - ); - - // testing simple cases - Assert(implProxy is IRetThis, "implProxy should be castable to IRetThis via is"); - Assert(!(implProxy is IUnimplemented), "implProxy should not be castable to IUnimplemented via is"); - Assert((implProxy as IRetThis) != null, "implProxy should be castable to IRetThis is as"); - Assert((implProxy as IUnimplemented) == null, "implProxy should not be castable to IUnimplemented is as"); - var retThis = (IRetThis)implProxy; - Assert(object.ReferenceEquals(retThis.ReturnThis(), implProxy), "RetThis should return implProxy"); - Assert(retThis.GetMyType() == typeof(Castable), "GetMyType should return typeof(Castable)"); - - Assert(!(implProxy is IUnimplemented), "implProxy should not be castable to IUnimplemented via is"); - Assert((implProxy as IUnimplemented) == null, "implProxy should not be castable to IUnimplemented via as"); - - - // testing generics - IRetArg retArgStr = (IRetArg)implProxy; - Assert(retArgStr.ReturnArg("hohoho") == "hohoho", "retArgStr.ReturnArg() should return arg"); - - IRetArg retArgInt = (IRetArg)implProxy; - Assert(retArgInt.ReturnArg(42) == 42, "retArgInt.ReturnArg() should return arg"); - - - // testing Castable implementing other interfaces - var extra = (IExtra)implProxy; - Assert(extra.InnocentMethod() == 3, "InnocentMethod() should be called on Castable and return 3"); - - // testing error handling - try - { - var _ = (IUnimplemented)implProxy; - Assert(false, "pProxy should not be castable to I1"); - } - catch (InvalidCastException) {} - - object nullCastable = new Castable(null); - try - { - var _ = (IRetThis)nullCastable; - Assert(false, "Exceptions should be thrown from IsInstanceOfInterface"); - } - catch (CastableException) {} - - Assert(!(nullCastable is IRetThis), "null castable shouldn't be allowed to be casted to anything"); - - var shouldBeNull = nullCastable as IRetThis; - Assert(shouldBeNull == null, "shouldBeNull should be assigned null"); - - object badCastable = new BadCastable(); - try - { - var r = (IRetThis)badCastable; - r.ReturnThis(); - Assert(false, "Exceptions should be thrown from ReturnThis()"); - } - catch (EntryPointNotFoundException) {} - - //delegate testing - Func fInt = new Func(extra.InnocentMethod); - Assert(fInt() == 3, "Delegate call to InnocentMethod() should return 3"); - - Func func = new Func(retThis.ReturnThis); - Assert(object.ReferenceEquals(func(), implProxy), "Delegate call to ReturnThis() should return this"); - } - catch (Exception e) - { - Assert(false, e.ToString()); - } - } -} diff --git a/src/tests/Interop/ICastable/Castable.csproj b/src/tests/Interop/ICastable/Castable.csproj deleted file mode 100644 index ff9fd9f5783095..00000000000000 --- a/src/tests/Interop/ICastable/Castable.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - true - true - - - - - - diff --git a/src/tests/Interop/ICastable/ICastable.CoreLib.csproj b/src/tests/Interop/ICastable/ICastable.CoreLib.csproj deleted file mode 100644 index 49492925b187cd..00000000000000 --- a/src/tests/Interop/ICastable/ICastable.CoreLib.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - true - Library - SharedLibrary - - System.Private.CoreLib - disable - $(NoWarn);nullable - - - - - diff --git a/src/tests/issues.targets b/src/tests/issues.targets index a0410d57e0b9cf..8ff9e6ea7e8a19 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -1466,9 +1466,6 @@ Not supported on Mono - - needs triage - https://github.com/dotnet/runtime/issues/34072