From f2e2409efbddc118330012542dbb50cb40c58e4f Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Tue, 24 Mar 2026 15:57:43 -0700 Subject: [PATCH 1/8] Replace MethodDescCallSite with UnmanagedCallersOnly in clrex.cpp Convert EEArgumentException, EETypeLoadException, and EEFileLoadException CreateThrowable methods to use UnmanagedCallersOnlyCaller instead of MethodDescCallSite/CallDescrWorker for invoking managed exception constructors. Add corresponding [UnmanagedCallersOnly] factory methods in managed code and remove unused metasig entries. Contributes to https://github.com/dotnet/runtime/issues/123864 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../src/System/Exception.CoreCLR.cs | 21 ++++ .../System/IO/FileLoadException.CoreCLR.cs | 15 ++- .../src/System/TypeLoadException.CoreCLR.cs | 16 +++ src/coreclr/vm/clrex.cpp | 115 +++--------------- src/coreclr/vm/corelib.h | 7 ++ src/coreclr/vm/metasig.h | 2 - 6 files changed, 78 insertions(+), 98 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs index 3c4c5623e76a9a..2db2a07c642641 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs @@ -396,5 +396,26 @@ internal static unsafe void CreateTargetInvocationException(Exception* pInnerExc *pException = ex; } } + + [UnmanagedCallersOnly] + internal static unsafe void CreateArgumentException(Exception* pEx, bool isArgumentException, delegate* pCtor, char* pResourceName, char* pParamName, Exception* pException) + { + try + { + string? message = pResourceName is not null ? SR.GetResourceString(new string(pResourceName)) : null; + string? paramName = pParamName is not null ? new string(pParamName) : null; + + // Note that ArgumentException takes arguments to its constructor in a different order, + // for usability reasons. However it is inconsistent with our other exceptions. + if (isArgumentException) + pCtor(*pEx, message, paramName); + else + pCtor(*pEx, paramName, message); + } + catch (Exception ex) + { + *pException = ex; + } + } } } diff --git a/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs index 439689ca9adc26..60b66a2ba35727 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs @@ -8,7 +8,6 @@ namespace System.IO { public partial class FileLoadException { - // Do not delete: this is invoked from native code. private FileLoadException(string? fileName, int hResult) : base(null) { @@ -36,5 +35,19 @@ internal static string FormatFileLoadExceptionMessage(string? fileName, int hRes [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "FileLoadException_GetMessageForHR")] private static partial void GetMessageForHR(int hresult, StringHandleOnStack retString); + + [UnmanagedCallersOnly] + internal static unsafe void Create(char* pFileName, int hresult, object* pThrowable, Exception* pException) + { + try + { + string? fileName = pFileName is not null ? new string(pFileName) : null; + *pThrowable = new FileLoadException(fileName, hresult); + } + catch (Exception ex) + { + *pException = ex; + } + } } } diff --git a/src/coreclr/System.Private.CoreLib/src/System/TypeLoadException.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/TypeLoadException.CoreCLR.cs index 4de0449e86958c..b33066cc34e1e1 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/TypeLoadException.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/TypeLoadException.CoreCLR.cs @@ -48,5 +48,21 @@ private void SetMessageField() [LibraryImport(RuntimeHelpers.QCall)] private static partial void GetTypeLoadExceptionMessage(int resourceId, StringHandleOnStack retString); + + [UnmanagedCallersOnly] + internal static unsafe void Create(char* pClassName, char* pAssemblyName, char* pMessageArg, int resourceId, object* pResult, Exception* pException) + { + try + { + string? className = pClassName is not null ? new string(pClassName) : null; + string? assemblyName = pAssemblyName is not null ? new string(pAssemblyName) : null; + string? messageArg = pMessageArg is not null ? new string(pMessageArg) : null; + *pResult = new TypeLoadException(className, assemblyName, messageArg, resourceId); + } + catch (Exception ex) + { + *pException = ex; + } + } } } diff --git a/src/coreclr/vm/clrex.cpp b/src/coreclr/vm/clrex.cpp index 2953e0a75b5f08..f9e9ff0947fbc1 100644 --- a/src/coreclr/vm/clrex.cpp +++ b/src/coreclr/vm/clrex.cpp @@ -1295,14 +1295,9 @@ OBJECTREF EEArgumentException::CreateThrowable() struct { OBJECTREF pThrowable; - STRINGREF s1; - OBJECTREF pTmpThrowable; } gc; gc.pThrowable = NULL; - gc.s1 = NULL; - gc.pTmpThrowable = NULL; GCPROTECT_BEGIN(gc); - ResMgrGetString(m_resourceName, &gc.s1); MethodTable *pMT = CoreLibBinder::GetException(m_kind); gc.pThrowable = AllocateObject(pMT); @@ -1316,32 +1311,15 @@ OBJECTREF EEArgumentException::CreateThrowable() COMPlusThrowNonLocalized(kMissingMethodException, wzMethodName); } - MethodDescCallSite exceptionCtor(pMD); + UnmanagedCallersOnlyCaller createArgException(METHOD__EXCEPTION__CREATE_ARGUMENT_EXCEPTION); + createArgException.InvokeThrowing( + &gc.pThrowable, + m_kind == kArgumentException, + pMD->GetSingleCallableAddrOfCode(), + m_resourceName.GetUnicode(), + m_argumentName.GetUnicode()); - STRINGREF argName = StringObject::NewString(m_argumentName); - - // Note that ArgumentException takes arguments to its constructor in a different order, - // for usability reasons. However it is inconsistent with our other exceptions. - if (m_kind == kArgumentException) - { - ARG_SLOT args1[] = { - ObjToArgSlot(gc.pThrowable), - ObjToArgSlot(gc.s1), - ObjToArgSlot(argName), - }; - exceptionCtor.Call(args1); - } - else - { - ARG_SLOT args1[] = { - ObjToArgSlot(gc.pThrowable), - ObjToArgSlot(argName), - ObjToArgSlot(gc.s1), - }; - exceptionCtor.Call(args1); - } - - GCPROTECT_END(); //Prot + GCPROTECT_END(); return gc.pThrowable; } @@ -1422,54 +1400,19 @@ OBJECTREF EETypeLoadException::CreateThrowable() } CONTRACTL_END; - MethodTable *pMT = CoreLibBinder::GetException(kTypeLoadException); - - struct { - OBJECTREF pNewException; - STRINGREF pNewAssemblyString; - STRINGREF pNewClassString; - STRINGREF pNewMessageArgString; - } gc; - gc.pNewException = NULL; - gc.pNewAssemblyString = NULL; - gc.pNewClassString = NULL; - gc.pNewMessageArgString = NULL; - GCPROTECT_BEGIN(gc); - - gc.pNewClassString = StringObject::NewString(m_fullName); - - if (!m_pMessageArg.IsEmpty()) - gc.pNewMessageArgString = StringObject::NewString(m_pMessageArg); - - if (!m_pAssemblyName.IsEmpty()) - gc.pNewAssemblyString = StringObject::NewString(m_pAssemblyName); - - gc.pNewException = AllocateObject(pMT); - - MethodDesc* pMD = MemberLoader::FindMethod(gc.pNewException->GetMethodTable(), - COR_CTOR_METHOD_NAME, &gsig_IM_Str_Str_Str_Int_RetVoid); - - if (!pMD) - { - MAKE_WIDEPTR_FROMUTF8(wzMethodName, COR_CTOR_METHOD_NAME); - COMPlusThrowNonLocalized(kMissingMethodException, wzMethodName); - } - - MethodDescCallSite exceptionCtor(pMD); + OBJECTREF throwable = NULL; + GCPROTECT_BEGIN(throwable); - ARG_SLOT args[] = { - ObjToArgSlot(gc.pNewException), - ObjToArgSlot(gc.pNewClassString), - ObjToArgSlot(gc.pNewAssemblyString), - ObjToArgSlot(gc.pNewMessageArgString), - (ARG_SLOT)m_resIDWhy, - }; + LPCWSTR pClassName = m_fullName.GetUnicode(); + LPCWSTR pAssemblyName = m_pAssemblyName.IsEmpty() ? NULL : m_pAssemblyName.GetUnicode(); + LPCWSTR pMessageArg = m_pMessageArg.IsEmpty() ? NULL : m_pMessageArg.GetUnicode(); - exceptionCtor.Call(args); + UnmanagedCallersOnlyCaller createTypeLoadEx(METHOD__TYPE_LOAD_EXCEPTION__CREATE); + createTypeLoadEx.InvokeThrowing(pClassName, pAssemblyName, pMessageArg, (int)m_resIDWhy, &throwable); GCPROTECT_END(); - return gc.pNewException; + return throwable; } // --------------------------------------------------------------------------- @@ -1605,33 +1548,15 @@ OBJECTREF EEFileLoadException::CreateThrowable() struct { OBJECTREF pNewException; - STRINGREF pNewFileString; } gc; gc.pNewException = NULL; - gc.pNewFileString = NULL; GCPROTECT_BEGIN(gc); - gc.pNewFileString = StringObject::NewString(m_name); - gc.pNewException = AllocateObject(CoreLibBinder::GetException(m_kind)); - - MethodDesc* pMD = MemberLoader::FindMethod(gc.pNewException->GetMethodTable(), - COR_CTOR_METHOD_NAME, &gsig_IM_Str_Int_RetVoid); - - if (!pMD) - { - MAKE_WIDEPTR_FROMUTF8(wzMethodName, COR_CTOR_METHOD_NAME); - COMPlusThrowNonLocalized(kMissingMethodException, wzMethodName); - } - - MethodDescCallSite exceptionCtor(pMD); - - ARG_SLOT args[] = { - ObjToArgSlot(gc.pNewException), - ObjToArgSlot(gc.pNewFileString), - (ARG_SLOT) m_hr - }; - exceptionCtor.Call(args); + LPCWSTR pFileName = m_name.GetUnicode(); + UnmanagedCallersOnlyCaller createFileLoadEx(METHOD__FILE_LOAD_EXCEPTION__CREATE); + createFileLoadEx.InvokeThrowing(pFileName, (int)m_hr, &gc.pNewException); + _ASSERTE(gc.pNewException->GetMethodTable() == CoreLibBinder::GetException(m_kind)); GCPROTECT_END(); diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 51fd4dee8af33c..227decef5e7098 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -309,6 +309,7 @@ DEFINE_METHOD(EXCEPTION, GET_SOURCE_BSTR, GetSourceBstr, DEFINE_METHOD(EXCEPTION, GET_HELP_CONTEXT_BSTR, GetHelpContextBstr, SM_PtrException_PtrIntPtr_PtrUInt_PtrException_RetVoid) #endif // FEATURE_COMINTEROP DEFINE_METHOD(EXCEPTION, CREATE_TARGET_INVOCATION_EXCEPTION, CreateTargetInvocationException, SM_PtrException_PtrObj_PtrException_RetVoid) +DEFINE_METHOD(EXCEPTION, CREATE_ARGUMENT_EXCEPTION, CreateArgumentException, NoSig) DEFINE_CLASS(SYSTEM_EXCEPTION, System, SystemException) @@ -317,6 +318,12 @@ DEFINE_METHOD(SYSTEM_EXCEPTION, STR_EX_CTOR, .ctor, DEFINE_CLASS(TYPE_INIT_EXCEPTION, System, TypeInitializationException) +DEFINE_CLASS(TYPE_LOAD_EXCEPTION, System, TypeLoadException) +DEFINE_METHOD(TYPE_LOAD_EXCEPTION, CREATE, Create, NoSig) + +DEFINE_CLASS(FILE_LOAD_EXCEPTION, IO, FileLoadException) +DEFINE_METHOD(FILE_LOAD_EXCEPTION, CREATE, Create, NoSig) + DEFINE_CLASS(VALUETASK_1, Tasks, ValueTask`1) DEFINE_METHOD(VALUETASK_1, GET_ISCOMPLETED, get_IsCompleted, NoSig) DEFINE_METHOD(VALUETASK_1, GET_RESULT, get_Result, NoSig) diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index 8dac8a5bba99e4..4a7af915216e03 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -374,8 +374,6 @@ DEFINE_METASIG_T(SM(PtrPtrChar_PtrPtrChar_Int_PtrException_RetVoid, P(P(u)) P(P( DEFINE_METASIG(SM(PtrChar_Int_PtrPtrChar_RetArrStr, P(u) i P(P(u)), a(s))) DEFINE_METASIG_T(IM(Str_Exception_RetVoid, s C(EXCEPTION), v)) DEFINE_METASIG(IM(Str_Str_RetVoid, s s, v)) -DEFINE_METASIG(IM(Str_Int_RetVoid, s i, v)) -DEFINE_METASIG(IM(Str_Str_Str_Int_RetVoid, s s s i, v)) DEFINE_METASIG_T(IM(Str_BindingFlags_Binder_Obj_ArrObj_ArrParameterModifier_CultureInfo_ArrStr_RetObj, \ s g(BINDING_FLAGS) C(BINDER) j a(j) a(g(PARAMETER_MODIFIER)) C(CULTURE_INFO) a(s), j)) DEFINE_METASIG_T(SM(Delegate_RetIntPtr, C(DELEGATE), I)) From 1b27f9ec9ad6b8d664a172388a327d96cfdbd0a3 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Tue, 24 Mar 2026 21:28:23 -0700 Subject: [PATCH 2/8] Convert clrex exception creation to UnmanagedCallersOnly pattern Refactor EEFileLoadException::GetFileLoadKind to use a switch statement. Add ArgumentExceptionKind and FileLoadExceptionKind enums for managed mapping. Update CreateThrowable methods to use UnmanagedCallersOnlyCaller. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../System/BadImageFormatException.CoreCLR.cs | 3 +- .../src/System/Exception.CoreCLR.cs | 21 ++- .../System/IO/FileLoadException.CoreCLR.cs | 20 ++- .../IO/FileNotFoundException.CoreCLR.cs | 3 +- .../src/System/TypeLoadException.CoreCLR.cs | 1 - src/coreclr/vm/clrex.cpp | 134 ++++++++++++------ src/coreclr/vm/metasig.h | 1 - 7 files changed, 124 insertions(+), 59 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/BadImageFormatException.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/BadImageFormatException.CoreCLR.cs index 6e44e7e1cfdd65..88a951412d6a05 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/BadImageFormatException.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/BadImageFormatException.CoreCLR.cs @@ -5,8 +5,7 @@ namespace System { public partial class BadImageFormatException { - // Do not delete: this is invoked from native code. - private BadImageFormatException(string? fileName, int hResult) + internal BadImageFormatException(string? fileName, int hResult) : base(null) { HResult = hResult; diff --git a/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs index 2db2a07c642641..8e8ffe7a73e3c8 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs @@ -397,8 +397,16 @@ internal static unsafe void CreateTargetInvocationException(Exception* pInnerExc } } + // See clrex.cpp for native version. + internal enum ArgumentExceptionKind + { + Argument, + ArgumentNull, + ArgumentOutOfRange + }; + [UnmanagedCallersOnly] - internal static unsafe void CreateArgumentException(Exception* pEx, bool isArgumentException, delegate* pCtor, char* pResourceName, char* pParamName, Exception* pException) + internal static unsafe void CreateArgumentException(ArgumentExceptionKind kind, char* pResourceName, char* pParamName, Exception* pThrowable, Exception* pException) { try { @@ -407,10 +415,13 @@ internal static unsafe void CreateArgumentException(Exception* pEx, bool isArgum // Note that ArgumentException takes arguments to its constructor in a different order, // for usability reasons. However it is inconsistent with our other exceptions. - if (isArgumentException) - pCtor(*pEx, message, paramName); - else - pCtor(*pEx, paramName, message); + *pThrowable = kind switch + { + ArgumentExceptionKind.Argument => new ArgumentException(message, paramName), + ArgumentExceptionKind.ArgumentNull => new ArgumentNullException(paramName, message), + ArgumentExceptionKind.ArgumentOutOfRange => new ArgumentOutOfRangeException(paramName, message), + _ => throw new InvalidOperationException() + }; } catch (Exception ex) { diff --git a/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs index 60b66a2ba35727..098f02d65b756e 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs @@ -36,13 +36,29 @@ internal static string FormatFileLoadExceptionMessage(string? fileName, int hRes [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "FileLoadException_GetMessageForHR")] private static partial void GetMessageForHR(int hresult, StringHandleOnStack retString); + // See clrex.cpp for native version. + internal enum FileLoadExceptionKind + { + FileLoad, + BadImageFormat, + FileNotFound, + OutOfMemory + } + [UnmanagedCallersOnly] - internal static unsafe void Create(char* pFileName, int hresult, object* pThrowable, Exception* pException) + internal static unsafe void Create(FileLoadExceptionKind kind, char* pFileName, int hresult, object* pThrowable, Exception* pException) { try { string? fileName = pFileName is not null ? new string(pFileName) : null; - *pThrowable = new FileLoadException(fileName, hresult); + *pThrowable = kind switch + { + FileLoadExceptionKind.BadImageFormat => new BadImageFormatException(fileName, hresult), + FileLoadExceptionKind.FileNotFound => new FileNotFoundException(fileName, hresult), + FileLoadExceptionKind.OutOfMemory => throw new OutOfMemoryException(), + FileLoadExceptionKind.FileLoad => new FileLoadException(fileName, hresult), + _ => throw new InvalidOperationException() + }; } catch (Exception ex) { diff --git a/src/coreclr/System.Private.CoreLib/src/System/IO/FileNotFoundException.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/IO/FileNotFoundException.CoreCLR.cs index fbd2a6d02e6953..15d54ec5b367c8 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/IO/FileNotFoundException.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/IO/FileNotFoundException.CoreCLR.cs @@ -5,8 +5,7 @@ namespace System.IO { public partial class FileNotFoundException { - // Do not delete: this is invoked from native code. - private FileNotFoundException(string? fileName, int hResult) + internal FileNotFoundException(string? fileName, int hResult) : base(null) { HResult = hResult; diff --git a/src/coreclr/System.Private.CoreLib/src/System/TypeLoadException.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/TypeLoadException.CoreCLR.cs index b33066cc34e1e1..eb13a78c9e2a50 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/TypeLoadException.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/TypeLoadException.CoreCLR.cs @@ -8,7 +8,6 @@ namespace System { public partial class TypeLoadException : SystemException { - // This is called from inside the EE. private TypeLoadException(string? className, string? assemblyName, string? messageArg, diff --git a/src/coreclr/vm/clrex.cpp b/src/coreclr/vm/clrex.cpp index f9e9ff0947fbc1..0494aae8780e70 100644 --- a/src/coreclr/vm/clrex.cpp +++ b/src/coreclr/vm/clrex.cpp @@ -1279,6 +1279,30 @@ BOOL EETypeAccessException::GetThrowableMessage(SString &result) // EEArgumentException is an EE exception subclass representing a bad argument // --------------------------------------------------------------------------- +// See Exception.CoreCLR.cs for managed mapping. +enum class ArgumentExceptionKind : int32_t +{ + Argument, + ArgumentNull, + ArgumentOutOfRange +}; + +static ArgumentExceptionKind GetArgumentExceptionKind(RuntimeExceptionKind reKind) +{ + LIMITED_METHOD_CONTRACT; + switch (reKind) + { + case kArgumentException: + return ArgumentExceptionKind::Argument; + case kArgumentNullException: + return ArgumentExceptionKind::ArgumentNull; + case kArgumentOutOfRangeException: + return ArgumentExceptionKind::ArgumentOutOfRange; + default: + UNREACHABLE(); + } +} + OBJECTREF EEArgumentException::CreateThrowable() { @@ -1299,25 +1323,13 @@ OBJECTREF EEArgumentException::CreateThrowable() gc.pThrowable = NULL; GCPROTECT_BEGIN(gc); - MethodTable *pMT = CoreLibBinder::GetException(m_kind); - gc.pThrowable = AllocateObject(pMT); - - MethodDesc* pMD = MemberLoader::FindMethod(gc.pThrowable->GetMethodTable(), - COR_CTOR_METHOD_NAME, &gsig_IM_Str_Str_RetVoid); - - if (!pMD) - { - MAKE_WIDEPTR_FROMUTF8(wzMethodName, COR_CTOR_METHOD_NAME); - COMPlusThrowNonLocalized(kMissingMethodException, wzMethodName); - } - UnmanagedCallersOnlyCaller createArgException(METHOD__EXCEPTION__CREATE_ARGUMENT_EXCEPTION); + ArgumentExceptionKind kind = GetArgumentExceptionKind(m_kind); createArgException.InvokeThrowing( - &gc.pThrowable, - m_kind == kArgumentException, - pMD->GetSingleCallableAddrOfCode(), - m_resourceName.GetUnicode(), - m_argumentName.GetUnicode()); + kind, + m_resourceName.IsEmpty() ? NULL : m_resourceName.GetUnicode(), + m_argumentName.IsEmpty() ? NULL : m_argumentName.GetUnicode(), + &gc.pThrowable); GCPROTECT_END(); @@ -1505,33 +1517,61 @@ RuntimeExceptionKind EEFileLoadException::GetFileLoadKind(HRESULT hr) if (Assembly::FileNotFound(hr)) return kFileNotFoundException; - else + + // Make sure this matches the list in rexcep.h + switch (hr) + { + case COR_E_BADIMAGEFORMAT: + case CLDB_E_FILE_OLDVER: + case CLDB_E_INDEX_NOTFOUND: + case CLDB_E_FILE_CORRUPT: + case COR_E_NEWER_RUNTIME: + case COR_E_ASSEMBLYEXPECTED: + case HRESULT_FROM_WIN32(ERROR_BAD_EXE_FORMAT): + case HRESULT_FROM_WIN32(ERROR_EXE_MARKED_INVALID): + case CORSEC_E_INVALID_IMAGE_FORMAT: + case HRESULT_FROM_WIN32(ERROR_NOACCESS): + case HRESULT_FROM_WIN32(ERROR_INVALID_ORDINAL): + case HRESULT_FROM_WIN32(ERROR_INVALID_DLL): + case HRESULT_FROM_WIN32(ERROR_FILE_CORRUPT): + case (HRESULT)IDS_CLASSLOAD_32BITCLRLOADING64BITASSEMBLY: + case COR_E_LOADING_REFERENCE_ASSEMBLY: + case META_E_BAD_SIGNATURE: + return kBadImageFormatException; + + case E_OUTOFMEMORY: + case NTE_NO_MEMORY: + return kOutOfMemoryException; + + default: + return kFileLoadException; + } +} + +// See FileLoadException.CoreCLR.cs for managed mapping. +enum class FileLoadExceptionKind : int32_t +{ + FileLoad, + BadImageFormat, + FileNotFound, + OutOfMemory +}; + +static FileLoadExceptionKind GetFileLoadExceptionKind(HRESULT hr) +{ + RuntimeExceptionKind kind = EEFileLoadException::GetFileLoadKind(hr); + switch (kind) { - // Make sure this matches the list in rexcep.h - if ((hr == COR_E_BADIMAGEFORMAT) || - (hr == CLDB_E_FILE_OLDVER) || - (hr == CLDB_E_INDEX_NOTFOUND) || - (hr == CLDB_E_FILE_CORRUPT) || - (hr == COR_E_NEWER_RUNTIME) || - (hr == COR_E_ASSEMBLYEXPECTED) || - (hr == HRESULT_FROM_WIN32(ERROR_BAD_EXE_FORMAT)) || - (hr == HRESULT_FROM_WIN32(ERROR_EXE_MARKED_INVALID)) || - (hr == CORSEC_E_INVALID_IMAGE_FORMAT) || - (hr == HRESULT_FROM_WIN32(ERROR_NOACCESS)) || - (hr == HRESULT_FROM_WIN32(ERROR_INVALID_ORDINAL)) || - (hr == HRESULT_FROM_WIN32(ERROR_INVALID_DLL)) || - (hr == HRESULT_FROM_WIN32(ERROR_FILE_CORRUPT)) || - (hr == (HRESULT) IDS_CLASSLOAD_32BITCLRLOADING64BITASSEMBLY) || - (hr == COR_E_LOADING_REFERENCE_ASSEMBLY) || - (hr == META_E_BAD_SIGNATURE)) - return kBadImageFormatException; - else - { - if ((hr == E_OUTOFMEMORY) || (hr == NTE_NO_MEMORY)) - return kOutOfMemoryException; - else - return kFileLoadException; - } + case kBadImageFormatException: + return FileLoadExceptionKind::BadImageFormat; + case kFileNotFoundException: + return FileLoadExceptionKind::FileNotFound; + case kOutOfMemoryException: + return FileLoadExceptionKind::OutOfMemory; + case kFileLoadException: + return FileLoadExceptionKind::FileLoad; + default: + UNREACHABLE(); } } @@ -1546,16 +1586,18 @@ OBJECTREF EEFileLoadException::CreateThrowable() } CONTRACTL_END; - struct { + struct + { OBJECTREF pNewException; } gc; gc.pNewException = NULL; GCPROTECT_BEGIN(gc); - LPCWSTR pFileName = m_name.GetUnicode(); UnmanagedCallersOnlyCaller createFileLoadEx(METHOD__FILE_LOAD_EXCEPTION__CREATE); - createFileLoadEx.InvokeThrowing(pFileName, (int)m_hr, &gc.pNewException); + + FileLoadExceptionKind kind = GetFileLoadExceptionKind(m_hr); + createFileLoadEx.InvokeThrowing(kind, pFileName, (int)m_hr, &gc.pNewException); _ASSERTE(gc.pNewException->GetMethodTable() == CoreLibBinder::GetException(m_kind)); GCPROTECT_END(); diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index 4a7af915216e03..6e0ccd49f6effd 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -373,7 +373,6 @@ DEFINE_METASIG(SM(Str_RetStr, s, s)) DEFINE_METASIG_T(SM(PtrPtrChar_PtrPtrChar_Int_PtrException_RetVoid, P(P(u)) P(P(u)) i P(C(EXCEPTION)), v)) DEFINE_METASIG(SM(PtrChar_Int_PtrPtrChar_RetArrStr, P(u) i P(P(u)), a(s))) DEFINE_METASIG_T(IM(Str_Exception_RetVoid, s C(EXCEPTION), v)) -DEFINE_METASIG(IM(Str_Str_RetVoid, s s, v)) DEFINE_METASIG_T(IM(Str_BindingFlags_Binder_Obj_ArrObj_ArrParameterModifier_CultureInfo_ArrStr_RetObj, \ s g(BINDING_FLAGS) C(BINDER) j a(j) a(g(PARAMETER_MODIFIER)) C(CULTURE_INFO) a(s), j)) DEFINE_METASIG_T(SM(Delegate_RetIntPtr, C(DELEGATE), I)) From 69e543ae57969f4bd164aabb8af437c2298b55ff Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Wed, 25 Mar 2026 10:24:17 -0700 Subject: [PATCH 3/8] Apply suggestions from code review Co-authored-by: Jan Kotas --- .../System.Private.CoreLib/src/System/Exception.CoreCLR.cs | 6 ++---- .../src/System/IO/FileLoadException.CoreCLR.cs | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs index 8e8ffe7a73e3c8..12559404472ba1 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs @@ -413,14 +413,12 @@ internal static unsafe void CreateArgumentException(ArgumentExceptionKind kind, string? message = pResourceName is not null ? SR.GetResourceString(new string(pResourceName)) : null; string? paramName = pParamName is not null ? new string(pParamName) : null; - // Note that ArgumentException takes arguments to its constructor in a different order, - // for usability reasons. However it is inconsistent with our other exceptions. + Debug.Assert(Enum.IsDefined(kind)); *pThrowable = kind switch { - ArgumentExceptionKind.Argument => new ArgumentException(message, paramName), ArgumentExceptionKind.ArgumentNull => new ArgumentNullException(paramName, message), ArgumentExceptionKind.ArgumentOutOfRange => new ArgumentOutOfRangeException(paramName, message), - _ => throw new InvalidOperationException() + _ /* ArgumentExceptionKind.Argument */ => new ArgumentException(message, paramName) }; } catch (Exception ex) diff --git a/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs index 098f02d65b756e..cc75cd10b916e5 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs @@ -51,13 +51,13 @@ internal static unsafe void Create(FileLoadExceptionKind kind, char* pFileName, try { string? fileName = pFileName is not null ? new string(pFileName) : null; + Debug.Assert(Enum.IsDefined(kind)); *pThrowable = kind switch { FileLoadExceptionKind.BadImageFormat => new BadImageFormatException(fileName, hresult), FileLoadExceptionKind.FileNotFound => new FileNotFoundException(fileName, hresult), FileLoadExceptionKind.OutOfMemory => throw new OutOfMemoryException(), - FileLoadExceptionKind.FileLoad => new FileLoadException(fileName, hresult), - _ => throw new InvalidOperationException() + _ /* FileLoadExceptionKind.FileLoad */ => new FileLoadException(fileName, hresult), }; } catch (Exception ex) From 7ea059c689e90aadf6ea2da701e73dec6c75fc12 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Wed, 25 Mar 2026 13:56:22 -0700 Subject: [PATCH 4/8] Update src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs --- .../src/System/IO/FileLoadException.CoreCLR.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs index cc75cd10b916e5..a5192a43c41d99 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs @@ -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.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; From a0894f71d764418919759bb324978c6ca6079934 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Wed, 25 Mar 2026 14:13:03 -0700 Subject: [PATCH 5/8] Apply suggestions from code review Co-authored-by: Aaron R Robinson --- .../System.Private.CoreLib/src/System/Exception.CoreCLR.cs | 2 +- .../src/System/IO/FileLoadException.CoreCLR.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs index 12559404472ba1..6df3107a85be3a 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs @@ -406,7 +406,7 @@ internal enum ArgumentExceptionKind }; [UnmanagedCallersOnly] - internal static unsafe void CreateArgumentException(ArgumentExceptionKind kind, char* pResourceName, char* pParamName, Exception* pThrowable, Exception* pException) + internal static unsafe void CreateArgumentException(ArgumentExceptionKind kind, char* pResourceName, char* pParamName, object* pThrowable, Exception* pException) { try { diff --git a/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs index a5192a43c41d99..927e08905606eb 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs @@ -57,7 +57,7 @@ internal static unsafe void Create(FileLoadExceptionKind kind, char* pFileName, { FileLoadExceptionKind.BadImageFormat => new BadImageFormatException(fileName, hresult), FileLoadExceptionKind.FileNotFound => new FileNotFoundException(fileName, hresult), - FileLoadExceptionKind.OutOfMemory => throw new OutOfMemoryException(), + FileLoadExceptionKind.OutOfMemory => new OutOfMemoryException(), _ /* FileLoadExceptionKind.FileLoad */ => new FileLoadException(fileName, hresult), }; } From 6a24d5e730f2b915867161b8c118102c84b66135 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Wed, 25 Mar 2026 16:58:15 -0700 Subject: [PATCH 6/8] Refactor exception handling in Exception.CoreCLR.cs and clrex.cpp to improve clarity and maintainability --- .../src/System/Exception.CoreCLR.cs | 2 +- src/coreclr/vm/clrex.cpp | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs index 6df3107a85be3a..f71851e59c63aa 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs @@ -403,7 +403,7 @@ internal enum ArgumentExceptionKind Argument, ArgumentNull, ArgumentOutOfRange - }; + } [UnmanagedCallersOnly] internal static unsafe void CreateArgumentException(ArgumentExceptionKind kind, char* pResourceName, char* pParamName, object* pThrowable, Exception* pException) diff --git a/src/coreclr/vm/clrex.cpp b/src/coreclr/vm/clrex.cpp index 0494aae8780e70..35e6535d7d1be2 100644 --- a/src/coreclr/vm/clrex.cpp +++ b/src/coreclr/vm/clrex.cpp @@ -1292,14 +1292,15 @@ static ArgumentExceptionKind GetArgumentExceptionKind(RuntimeExceptionKind reKin LIMITED_METHOD_CONTRACT; switch (reKind) { + default: + UNREACHABLE(); + __fallthrough; case kArgumentException: return ArgumentExceptionKind::Argument; case kArgumentNullException: return ArgumentExceptionKind::ArgumentNull; case kArgumentOutOfRangeException: return ArgumentExceptionKind::ArgumentOutOfRange; - default: - UNREACHABLE(); } } @@ -1568,10 +1569,11 @@ static FileLoadExceptionKind GetFileLoadExceptionKind(HRESULT hr) return FileLoadExceptionKind::FileNotFound; case kOutOfMemoryException: return FileLoadExceptionKind::OutOfMemory; - case kFileLoadException: - return FileLoadExceptionKind::FileLoad; default: UNREACHABLE(); + __fallthrough; + case kFileLoadException: + return FileLoadExceptionKind::FileLoad; } } From 0ca38bbe4dd9420aa0bbb4b8dc11272dd3651742 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Thu, 26 Mar 2026 11:03:53 -0700 Subject: [PATCH 7/8] Refactor exception kind switch statements for improved readability --- src/coreclr/vm/clrex.cpp | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/src/coreclr/vm/clrex.cpp b/src/coreclr/vm/clrex.cpp index 35e6535d7d1be2..2581f26d0daa16 100644 --- a/src/coreclr/vm/clrex.cpp +++ b/src/coreclr/vm/clrex.cpp @@ -1292,15 +1292,10 @@ static ArgumentExceptionKind GetArgumentExceptionKind(RuntimeExceptionKind reKin LIMITED_METHOD_CONTRACT; switch (reKind) { - default: - UNREACHABLE(); - __fallthrough; - case kArgumentException: - return ArgumentExceptionKind::Argument; - case kArgumentNullException: - return ArgumentExceptionKind::ArgumentNull; - case kArgumentOutOfRangeException: - return ArgumentExceptionKind::ArgumentOutOfRange; + case kArgumentException: return ArgumentExceptionKind::Argument; + case kArgumentNullException: return ArgumentExceptionKind::ArgumentNull; + case kArgumentOutOfRangeException: return ArgumentExceptionKind::ArgumentOutOfRange; + default: UNREACHABLE(); } } @@ -1563,17 +1558,11 @@ static FileLoadExceptionKind GetFileLoadExceptionKind(HRESULT hr) RuntimeExceptionKind kind = EEFileLoadException::GetFileLoadKind(hr); switch (kind) { - case kBadImageFormatException: - return FileLoadExceptionKind::BadImageFormat; - case kFileNotFoundException: - return FileLoadExceptionKind::FileNotFound; - case kOutOfMemoryException: - return FileLoadExceptionKind::OutOfMemory; - default: - UNREACHABLE(); - __fallthrough; - case kFileLoadException: - return FileLoadExceptionKind::FileLoad; + case kFileLoadException: return FileLoadExceptionKind::FileLoad; + case kBadImageFormatException: return FileLoadExceptionKind::BadImageFormat; + case kFileNotFoundException: return FileLoadExceptionKind::FileNotFound; + case kOutOfMemoryException: return FileLoadExceptionKind::OutOfMemory; + default: UNREACHABLE(); } } From 52f57851f5919749df7bb955e6f64a4bd0988ecb Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Thu, 26 Mar 2026 11:26:42 -0700 Subject: [PATCH 8/8] Add new call helpers for FileLoadException and TypeLoadException; update reverse thunk mappings --- .../vm/wasm/callhelpers-interp-to-managed.cpp | 7 +++ src/coreclr/vm/wasm/callhelpers-pinvoke.cpp | 6 ++- src/coreclr/vm/wasm/callhelpers-reverse.cpp | 54 ++++++++++++++++--- .../libs/Common/JavaScript/loader/dotnet.d.ts | 4 ++ 4 files changed, 64 insertions(+), 7 deletions(-) diff --git a/src/coreclr/vm/wasm/callhelpers-interp-to-managed.cpp b/src/coreclr/vm/wasm/callhelpers-interp-to-managed.cpp index b8df80682a9a17..e3cb2fbcbab2c3 100644 --- a/src/coreclr/vm/wasm/callhelpers-interp-to-managed.cpp +++ b/src/coreclr/vm/wasm/callhelpers-interp-to-managed.cpp @@ -289,6 +289,12 @@ namespace *((int64_t*)pRet) = (*fptr)(ARG_I32(0)); } + static void CallFunc_I32_I32_I32_RetI64(PCODE pcode, int8_t* pArgs, int8_t* pRet) + { + int64_t (*fptr)(int32_t, int32_t, int32_t) = (int64_t (*)(int32_t, int32_t, int32_t))pcode; + *((int64_t*)pRet) = (*fptr)(ARG_I32(0), ARG_I32(1), ARG_I32(2)); + } + static void CallFunc_I32_I32_I32_I64_RetI64(PCODE pcode, int8_t* pArgs, int8_t* pRet) { int64_t (*fptr)(int32_t, int32_t, int32_t, int64_t) = (int64_t (*)(int32_t, int32_t, int32_t, int64_t))pcode; @@ -516,6 +522,7 @@ const StringToWasmSigThunk g_wasmThunks[] = { { "innn", (void*)&CallFunc_IND_IND_IND_RetI32 }, { "l", (void*)&CallFunc_Void_RetI64 }, { "li", (void*)&CallFunc_I32_RetI64 }, + { "liii", (void*)&CallFunc_I32_I32_I32_RetI64 }, { "liiil", (void*)&CallFunc_I32_I32_I32_I64_RetI64 }, { "lil", (void*)&CallFunc_I32_I64_RetI64 }, { "lili", (void*)&CallFunc_I32_I64_I32_RetI64 }, diff --git a/src/coreclr/vm/wasm/callhelpers-pinvoke.cpp b/src/coreclr/vm/wasm/callhelpers-pinvoke.cpp index 3a1d25cab60eff..2be5428681fe54 100644 --- a/src/coreclr/vm/wasm/callhelpers-pinvoke.cpp +++ b/src/coreclr/vm/wasm/callhelpers-pinvoke.cpp @@ -135,6 +135,7 @@ extern "C" { int32_t SystemNative_ReadDir (void *, void *); int32_t SystemNative_ReadFromNonblocking (void *, void *, int32_t); int32_t SystemNative_ReadLink (void *, void *, int32_t); + int64_t SystemNative_ReadV (void *, void *, int32_t); void * SystemNative_Realloc (void *, void *); int32_t SystemNative_Rename (void *, void *); int32_t SystemNative_RmDir (void *); @@ -151,6 +152,7 @@ extern "C" { int32_t SystemNative_Unlink (void *); int32_t SystemNative_Write (void *, void *, int32_t); int32_t SystemNative_WriteToNonblocking (void *, void *, int32_t); + int64_t SystemNative_WriteV (void *, void *, int32_t); } // extern "C" static const Entry s_libSystem_Globalization_Native [] = { @@ -277,6 +279,7 @@ static const Entry s_libSystem_Native [] = { DllImportEntry(SystemNative_ReadDir) // System.Private.CoreLib DllImportEntry(SystemNative_ReadFromNonblocking) // System.Private.CoreLib DllImportEntry(SystemNative_ReadLink) // System.Private.CoreLib + DllImportEntry(SystemNative_ReadV) // System.Private.CoreLib DllImportEntry(SystemNative_Realloc) // System.Private.CoreLib DllImportEntry(SystemNative_Rename) // System.Private.CoreLib DllImportEntry(SystemNative_RmDir) // System.Private.CoreLib @@ -293,6 +296,7 @@ static const Entry s_libSystem_Native [] = { DllImportEntry(SystemNative_Unlink) // System.IO.MemoryMappedFiles, System.Private.CoreLib DllImportEntry(SystemNative_Write) // System.Console, System.Private.CoreLib DllImportEntry(SystemNative_WriteToNonblocking) // System.Private.CoreLib + DllImportEntry(SystemNative_WriteV) // System.Private.CoreLib }; static const Entry s_libSystem_Native_Browser [] = { @@ -317,7 +321,7 @@ typedef struct PInvokeTable { static PInvokeTable s_PInvokeTables[] = { {"libSystem.Globalization.Native", s_libSystem_Globalization_Native, 33}, {"libSystem.IO.Compression.Native", s_libSystem_IO_Compression_Native, 8}, - {"libSystem.Native", s_libSystem_Native, 92}, + {"libSystem.Native", s_libSystem_Native, 94}, {"libSystem.Native.Browser", s_libSystem_Native_Browser, 1}, {"libSystem.Runtime.InteropServices.JavaScript.Native", s_libSystem_Runtime_InteropServices_JavaScript_Native, 6} }; diff --git a/src/coreclr/vm/wasm/callhelpers-reverse.cpp b/src/coreclr/vm/wasm/callhelpers-reverse.cpp index a0d7b7d45a1dc2..236e9d14ee3c9a 100644 --- a/src/coreclr/vm/wasm/callhelpers-reverse.cpp +++ b/src/coreclr/vm/wasm/callhelpers-reverse.cpp @@ -274,6 +274,45 @@ static void Call_System_Private_CoreLib_System_Reflection_LoaderAllocator_Create ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Reflection_LoaderAllocator_Create_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_Reflection_LoaderAllocator_Create_I32_I32_RetVoid); } +static MethodDesc* MD_System_Private_CoreLib_System_IO_FileLoadException_Create_I32_I32_I32_I32_I32_RetVoid = nullptr; +static void Call_System_Private_CoreLib_System_IO_FileLoadException_Create_I32_I32_I32_I32_I32_RetVoid(int32_t arg0, void * arg1, int32_t arg2, void * arg3, void * arg4) +{ + int64_t args[5] = { (int64_t)arg0, (int64_t)arg1, (int64_t)arg2, (int64_t)arg3, (int64_t)arg4 }; + + // Lazy lookup of MethodDesc for the function export scenario. + if (!MD_System_Private_CoreLib_System_IO_FileLoadException_Create_I32_I32_I32_I32_I32_RetVoid) + { + LookupUnmanagedCallersOnlyMethodByName("System.IO.FileLoadException, System.Private.CoreLib", "Create", &MD_System_Private_CoreLib_System_IO_FileLoadException_Create_I32_I32_I32_I32_I32_RetVoid); + } + ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_IO_FileLoadException_Create_I32_I32_I32_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_IO_FileLoadException_Create_I32_I32_I32_I32_I32_RetVoid); +} + +static MethodDesc* MD_System_Private_CoreLib_System_TypeLoadException_Create_I32_I32_I32_I32_I32_I32_RetVoid = nullptr; +static void Call_System_Private_CoreLib_System_TypeLoadException_Create_I32_I32_I32_I32_I32_I32_RetVoid(void * arg0, void * arg1, void * arg2, int32_t arg3, void * arg4, void * arg5) +{ + int64_t args[6] = { (int64_t)arg0, (int64_t)arg1, (int64_t)arg2, (int64_t)arg3, (int64_t)arg4, (int64_t)arg5 }; + + // Lazy lookup of MethodDesc for the function export scenario. + if (!MD_System_Private_CoreLib_System_TypeLoadException_Create_I32_I32_I32_I32_I32_I32_RetVoid) + { + LookupUnmanagedCallersOnlyMethodByName("System.TypeLoadException, System.Private.CoreLib", "Create", &MD_System_Private_CoreLib_System_TypeLoadException_Create_I32_I32_I32_I32_I32_I32_RetVoid); + } + ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_TypeLoadException_Create_I32_I32_I32_I32_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_TypeLoadException_Create_I32_I32_I32_I32_I32_I32_RetVoid); +} + +static MethodDesc* MD_System_Private_CoreLib_System_Exception_CreateArgumentException_I32_I32_I32_I32_I32_RetVoid = nullptr; +static void Call_System_Private_CoreLib_System_Exception_CreateArgumentException_I32_I32_I32_I32_I32_RetVoid(int32_t arg0, void * arg1, void * arg2, void * arg3, void * arg4) +{ + int64_t args[5] = { (int64_t)arg0, (int64_t)arg1, (int64_t)arg2, (int64_t)arg3, (int64_t)arg4 }; + + // Lazy lookup of MethodDesc for the function export scenario. + if (!MD_System_Private_CoreLib_System_Exception_CreateArgumentException_I32_I32_I32_I32_I32_RetVoid) + { + LookupUnmanagedCallersOnlyMethodByName("System.Exception, System.Private.CoreLib", "CreateArgumentException", &MD_System_Private_CoreLib_System_Exception_CreateArgumentException_I32_I32_I32_I32_I32_RetVoid); + } + ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Exception_CreateArgumentException_I32_I32_I32_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_Exception_CreateArgumentException_I32_I32_I32_I32_I32_RetVoid); +} + static MethodDesc* MD_System_Private_CoreLib_System_Reflection_AssemblyName_CreateAssemblyName_I32_I32_I32_RetVoid = nullptr; static void Call_System_Private_CoreLib_System_Reflection_AssemblyName_CreateAssemblyName_I32_I32_I32_RetVoid(void * arg0, void * arg1, void * arg2) { @@ -790,17 +829,17 @@ static void Call_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContex ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_OnResourceResolve_I32_I32_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_OnResourceResolve_I32_I32_I32_I32_RetVoid); } -static MethodDesc* MD_System_Private_CoreLib_System_Threading_Thread_OnThreadExiting_I32_I32_RetVoid = nullptr; -static void Call_System_Private_CoreLib_System_Threading_Thread_OnThreadExiting_I32_I32_RetVoid(void * arg0, void * arg1) +static MethodDesc* MD_System_Private_CoreLib_System_Threading_Thread_OnThreadExited_I32_I32_RetVoid = nullptr; +static void Call_System_Private_CoreLib_System_Threading_Thread_OnThreadExited_I32_I32_RetVoid(void * arg0, void * arg1) { int64_t args[2] = { (int64_t)arg0, (int64_t)arg1 }; // Lazy lookup of MethodDesc for the function export scenario. - if (!MD_System_Private_CoreLib_System_Threading_Thread_OnThreadExiting_I32_I32_RetVoid) + if (!MD_System_Private_CoreLib_System_Threading_Thread_OnThreadExited_I32_I32_RetVoid) { - LookupUnmanagedCallersOnlyMethodByName("System.Threading.Thread, System.Private.CoreLib", "OnThreadExiting", &MD_System_Private_CoreLib_System_Threading_Thread_OnThreadExiting_I32_I32_RetVoid); + LookupUnmanagedCallersOnlyMethodByName("System.Threading.Thread, System.Private.CoreLib", "OnThreadExited", &MD_System_Private_CoreLib_System_Threading_Thread_OnThreadExited_I32_I32_RetVoid); } - ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Threading_Thread_OnThreadExiting_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_Threading_Thread_OnThreadExiting_I32_I32_RetVoid); + ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Threading_Thread_OnThreadExited_I32_I32_RetVoid, (int8_t*)args, sizeof(args), nullptr, (PCODE)&Call_System_Private_CoreLib_System_Threading_Thread_OnThreadExited_I32_I32_RetVoid); } static MethodDesc* MD_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_OnTypeResolve_I32_I32_I32_I32_RetVoid = nullptr; @@ -1064,6 +1103,9 @@ const ReverseThunkMapEntry g_ReverseThunks[] = { 4090197812, "ConvertToManaged#3:System.Private.CoreLib:System.StubHelpers:BSTRMarshaler", { &MD_System_Private_CoreLib_System_StubHelpers_BSTRMarshaler_ConvertToManaged_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_StubHelpers_BSTRMarshaler_ConvertToManaged_I32_I32_I32_RetVoid } }, { 1901425681, "ConvertToNative#2:System.Private.CoreLib:System.StubHelpers:BSTRMarshaler", { &MD_System_Private_CoreLib_System_StubHelpers_BSTRMarshaler_ConvertToNative_I32_I32_RetI32, (void*)&Call_System_Private_CoreLib_System_StubHelpers_BSTRMarshaler_ConvertToNative_I32_I32_RetI32 } }, { 1243134822, "Create#2:System.Private.CoreLib:System.Reflection:LoaderAllocator", { &MD_System_Private_CoreLib_System_Reflection_LoaderAllocator_Create_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Reflection_LoaderAllocator_Create_I32_I32_RetVoid } }, + { 1899576323, "Create#5:System.Private.CoreLib:System.IO:FileLoadException", { &MD_System_Private_CoreLib_System_IO_FileLoadException_Create_I32_I32_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_IO_FileLoadException_Create_I32_I32_I32_I32_I32_RetVoid } }, + { 1263271190, "Create#6:System.Private.CoreLib:System:TypeLoadException", { &MD_System_Private_CoreLib_System_TypeLoadException_Create_I32_I32_I32_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_TypeLoadException_Create_I32_I32_I32_I32_I32_I32_RetVoid } }, + { 509807279, "CreateArgumentException#5:System.Private.CoreLib:System:Exception", { &MD_System_Private_CoreLib_System_Exception_CreateArgumentException_I32_I32_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Exception_CreateArgumentException_I32_I32_I32_I32_I32_RetVoid } }, { 1570902419, "CreateAssemblyName#3:System.Private.CoreLib:System.Reflection:AssemblyName", { &MD_System_Private_CoreLib_System_Reflection_AssemblyName_CreateAssemblyName_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Reflection_AssemblyName_CreateAssemblyName_I32_I32_I32_RetVoid } }, { 3054399043, "CreateRuntimeWrappedException#3:System.Private.CoreLib:System:Exception", { &MD_System_Private_CoreLib_System_Exception_CreateRuntimeWrappedException_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Exception_CreateRuntimeWrappedException_I32_I32_I32_RetVoid } }, { 271519467, "CreateTargetInvocationException#3:System.Private.CoreLib:System:Exception", { &MD_System_Private_CoreLib_System_Exception_CreateTargetInvocationException_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Exception_CreateTargetInvocationException_I32_I32_I32_RetVoid } }, @@ -1101,7 +1143,7 @@ const ReverseThunkMapEntry g_ReverseThunks[] = { 3308959471, "OnFirstChanceException#2:System.Private.CoreLib:System:AppContext", { &MD_System_Private_CoreLib_System_AppContext_OnFirstChanceException_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_AppContext_OnFirstChanceException_I32_I32_RetVoid } }, { 3570701864, "OnProcessExit#1:System.Private.CoreLib:System:AppContext", { &MD_System_Private_CoreLib_System_AppContext_OnProcessExit_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_AppContext_OnProcessExit_I32_RetVoid } }, { 2158495436, "OnResourceResolve#4:System.Private.CoreLib:System.Runtime.Loader:AssemblyLoadContext", { &MD_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_OnResourceResolve_I32_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_OnResourceResolve_I32_I32_I32_I32_RetVoid } }, - { 771783454, "OnThreadExiting#2:System.Private.CoreLib:System.Threading:Thread", { &MD_System_Private_CoreLib_System_Threading_Thread_OnThreadExiting_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Threading_Thread_OnThreadExiting_I32_I32_RetVoid } }, + { 2049352127, "OnThreadExited#2:System.Private.CoreLib:System.Threading:Thread", { &MD_System_Private_CoreLib_System_Threading_Thread_OnThreadExited_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Threading_Thread_OnThreadExited_I32_I32_RetVoid } }, { 3572430398, "OnTypeResolve#4:System.Private.CoreLib:System.Runtime.Loader:AssemblyLoadContext", { &MD_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_OnTypeResolve_I32_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Runtime_Loader_AssemblyLoadContext_OnTypeResolve_I32_I32_I32_I32_RetVoid } }, { 4206970338, "OnUnhandledException#2:System.Private.CoreLib:System:AppContext", { &MD_System_Private_CoreLib_System_AppContext_OnUnhandledException_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_AppContext_OnUnhandledException_I32_I32_RetVoid } }, { 1873201650, "ParseAsAssemblySpec#3:System.Private.CoreLib:System.Reflection:AssemblyName", { &MD_System_Private_CoreLib_System_Reflection_AssemblyName_ParseAsAssemblySpec_I32_I32_I32_RetVoid, (void*)&Call_System_Private_CoreLib_System_Reflection_AssemblyName_ParseAsAssemblySpec_I32_I32_I32_RetVoid } }, diff --git a/src/native/libs/Common/JavaScript/loader/dotnet.d.ts b/src/native/libs/Common/JavaScript/loader/dotnet.d.ts index 0d8cd952ea62b3..1468d116b94289 100644 --- a/src/native/libs/Common/JavaScript/loader/dotnet.d.ts +++ b/src/native/libs/Common/JavaScript/loader/dotnet.d.ts @@ -48,6 +48,10 @@ interface DotnetHostBuilder { * @param config default values for the runtime configuration. It will be merged with the default values. */ withConfig(config: LoaderConfig): DotnetHostBuilder; + /** + * @deprecated This method is no longer supported and will be removed in a future version. + */ + withConfigSrc(configSrc: string): DotnetHostBuilder; /** * "command line" arguments for the Main() method. * @param args