From 44ce2feecbdb5c9da10dc5aa6dea3abd4c08ed5c Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Wed, 21 Apr 2021 13:37:21 -0700 Subject: [PATCH] Simplify some CallConv logic (#51596) * Simplify some CallConv logic Reuse the CallConvBuilder class in more places Unify CharSet logic for UnmanagedFunctionPointer and DllImport * Add needed cast. * Explicitly handle the 0 case for the CorNativeLinkType enum. * Comment update. * Review feedback. * Update dllimport.cpp Style feedback. --- src/coreclr/vm/dllimport.cpp | 121 ++++++++++++++++++++--------------- src/coreclr/vm/dllimportcallback.cpp | 11 +--- src/coreclr/vm/jitinterface.cpp | 16 ++--- src/coreclr/vm/siginfo.cpp | 113 +++++++++++++++++++------------- src/coreclr/vm/siginfo.hpp | 117 ++++++++++++++------------------- 5 files changed, 197 insertions(+), 181 deletions(-) diff --git a/src/coreclr/vm/dllimport.cpp b/src/coreclr/vm/dllimport.cpp index 7324dfd..dbc66ea 100644 --- a/src/coreclr/vm/dllimport.cpp +++ b/src/coreclr/vm/dllimport.cpp @@ -2529,6 +2529,40 @@ namespace return CallConvWinApiSentinel; } } + + // Convert a CorNativeLinkType into an unambiguous usable value. + bool TryRemapLinkType(_In_ CorNativeLinkType value, _Out_ CorNativeLinkType* nlt) + { + LIMITED_METHOD_CONTRACT; + _ASSERTE(nlt != NULL); + + // Handle case where the value is not in the defined enumeration. + if ((int)value == 0) + value = nltAnsi; + + switch (value) + { + case nltAnsi: + *nlt = nltAnsi; + break; + case nltUnicode: + *nlt = nltUnicode; + break; + case nltAuto: +#ifdef TARGET_WINDOWS + *nlt = nltUnicode; +#else + *nlt = nltAnsi; // We don't have a utf8 charset in metadata so ANSI == UTF-8 off-Windows +#endif + break; + default: + return false; + } + + // Validate we remapped to a usable value. + _ASSERTE(*nlt == nltAnsi || *nlt == nltUnicode); + return true; + } } void PInvokeStaticSigInfo::PreInit(Module* pModule, MethodTable * pMT) @@ -2655,28 +2689,14 @@ PInvokeStaticSigInfo::PInvokeStaticSigInfo(MethodDesc* pMD, ThrowOnError throwOn IfFailGo(ParseKnownCaNamedArgs(ca, namedArgs, lengthof(namedArgs))); callConv = (CorPinvokeMap)(args[0].val.u4 << 8); - CorNativeLinkType nlt = (CorNativeLinkType)0; - // XXX Tue 07/19/2005 - // Keep in sync with the handling of CorPInvokeMap in - // PInvokeStaticSigInfo::DllImportInit. - switch( namedArgs[MDA_CharSet].val.u4 ) + CorNativeLinkType nlt; + if (!TryRemapLinkType((CorNativeLinkType)namedArgs[MDA_CharSet].val.u4, &nlt)) { - case 0: - case nltAnsi: - nlt = nltAnsi; break; - case nltUnicode: - nlt = nltUnicode; break; - case nltAuto: -#ifdef TARGET_WINDOWS - nlt = nltUnicode; -#else - nlt = nltAnsi; // We don't have a utf8 charset in metadata yet, but ANSI == UTF-8 off-Windows -#endif - break; - default: - hr = E_FAIL; goto ErrExit; + hr = E_FAIL; + goto ErrExit; } + SetCharSet ( nlt ); SetBestFitMapping (namedArgs[MDA_BestFitMapping].val.u1); SetThrowOnUnmappableChar (namedArgs[MDA_ThrowOnUnmappableChar].val.u1); @@ -2684,7 +2704,6 @@ PInvokeStaticSigInfo::PInvokeStaticSigInfo(MethodDesc* pMD, ThrowOnError throwOn SetLinkFlags ((CorNativeLinkFlags)(nlfLastError | GetLinkFlags())); } - ErrExit: if (hr != S_OK) SetError(IDS_EE_NDIRECT_BADNATL); @@ -2709,7 +2728,7 @@ PInvokeStaticSigInfo::PInvokeStaticSigInfo( PreInit(pModule, NULL); m_sig = sig; SetIsStatic (!(MetaSig::GetCallingConvention(pModule, sig) & IMAGE_CEE_CS_CALLCONV_HASTHIS)); - InitCallConv(CorInfoCallConvExtension::Managed, FALSE); + InitCallConv(CallConvWinApiSentinel, FALSE); ReportErrors(); } @@ -2749,7 +2768,7 @@ void PInvokeStaticSigInfo::DllImportInit(MethodDesc* pMD, LPCUTF8 *ppLibName, LP BestGuessNDirectDefaults(pMD); #endif - InitCallConv(CorInfoCallConvExtension::Managed, pMD->IsVarArg()); + InitCallConv(CallConvWinApiSentinel, pMD->IsVarArg()); return; } @@ -2790,26 +2809,29 @@ void PInvokeStaticSigInfo::DllImportInit(MethodDesc* pMD, LPCUTF8 *ppLibName, LP if (mappingFlags & pmNoMangle) SetLinkFlags ((CorNativeLinkFlags)(GetLinkFlags() | nlfNoMangle)); - // Keep in sync with the handling of CorNativeLinkType in - // PInvokeStaticSigInfo::PInvokeStaticSigInfo. - // charset : CorPinvoke -> CorNativeLinkType CorPinvokeMap charSetMask = (CorPinvokeMap)(mappingFlags & (pmCharSetNotSpec | pmCharSetAnsi | pmCharSetUnicode | pmCharSetAuto)); - if (charSetMask == pmCharSetNotSpec || charSetMask == pmCharSetAnsi) + CorNativeLinkType nlt = nltMaxValue; // Initialize to invalid value + switch (charSetMask) { - SetCharSet (nltAnsi); - } - else if (charSetMask == pmCharSetUnicode) - { - SetCharSet (nltUnicode); + case pmCharSetNotSpec: + case pmCharSetAnsi: + nlt = nltAnsi; + break; + case pmCharSetUnicode: + nlt = nltUnicode; + break; + case pmCharSetAuto: + nlt = nltAuto; + break; + default: + _ASSERTE("Unknown CharSet mask value"); + break; } - else if (charSetMask == pmCharSetAuto) + + if (TryRemapLinkType(nlt, &nlt)) { -#ifdef TARGET_WINDOWS - SetCharSet(nltUnicode); -#else - SetCharSet(nltAnsi); // We don't have a utf8 charset in metadata yet, but ANSI == UTF-8 off-Windows -#endif + SetCharSet(nlt); } else { @@ -2966,19 +2988,16 @@ void PInvokeStaticSigInfo::InitCallConv(CorInfoCallConvExtension callConv, BOOL { STANDARD_VM_CONTRACT; - CorInfoCallConvExtension sigCallConv = CallConvWinApiSentinel; - bool suppressGCTransition; + CallConvBuilder builder; UINT errorResID; - HRESULT hr = MetaSig::TryGetUnmanagedCallingConventionFromModOpt(GetScopeHandle(m_pModule), m_sig.GetRawSig(), m_sig.GetRawSigLen(), &sigCallConv, &suppressGCTransition, &errorResID); + HRESULT hr = MetaSig::TryGetUnmanagedCallingConventionFromModOpt(GetScopeHandle(m_pModule), m_sig.GetRawSig(), m_sig.GetRawSigLen(), &builder, &errorResID); if (FAILED(hr)) { // Set an error message specific to P/Invokes or UnmanagedFunction for bad format. SetError(hr == COR_E_BADIMAGEFORMAT ? IDS_EE_NDIRECT_BADNATL : errorResID); } - else if (hr == S_FALSE) - { - sigCallConv = CallConvWinApiSentinel; - } + + CorInfoCallConvExtension sigCallConv = builder.GetCurrentCallConv(); // Validate that either no specific calling convention is provided or that the signature calling convention // matches the DllImport calling convention. @@ -5923,23 +5942,19 @@ PCODE GetILStubForCalli(VASigCookie *pVASigCookie, MethodDesc *pMD) } else { - CorInfoCallConvExtension callConvMaybe; + CallConvBuilder builder; UINT errorResID; - bool suppressGCTransition = false; - HRESULT hr = MetaSig::TryGetUnmanagedCallingConventionFromModOpt(GetScopeHandle(pVASigCookie->pModule), signature.GetRawSig(), signature.GetRawSigLen(), &callConvMaybe, &suppressGCTransition, &errorResID); + HRESULT hr = MetaSig::TryGetUnmanagedCallingConventionFromModOpt(GetScopeHandle(pVASigCookie->pModule), signature.GetRawSig(), signature.GetRawSigLen(), &builder, &errorResID); if (FAILED(hr)) COMPlusThrowHR(hr, errorResID); - if (hr == S_OK) - { - unmgdCallConv = callConvMaybe; - } - else + unmgdCallConv = builder.GetCurrentCallConv(); + if (unmgdCallConv == CallConvBuilder::UnsetValue) { unmgdCallConv = MetaSig::GetDefaultUnmanagedCallingConvention(); } - if (suppressGCTransition) + if (builder.IsCurrentCallConvModSet(CallConvBuilder::CALL_CONV_MOD_SUPPRESSGCTRANSITION)) { dwStubFlags |= NDIRECTSTUB_FL_SUPPRESSGCTRANSITION; } diff --git a/src/coreclr/vm/dllimportcallback.cpp b/src/coreclr/vm/dllimportcallback.cpp index db67425..52fb2f6 100644 --- a/src/coreclr/vm/dllimportcallback.cpp +++ b/src/coreclr/vm/dllimportcallback.cpp @@ -640,18 +640,11 @@ bool TryGetCallingConventionFromUnmanagedCallersOnly(MethodDesc* pMD, CorInfoCal } } - CallConvBuilder::CallConvModifiers modifiers; - callConvBuilder.GetCurrentCallConv(callConvLocal, modifiers); - - if (callConvLocal == CallConvBuilder::DefaultValue) + callConvLocal = callConvBuilder.GetCurrentCallConv(); + if (callConvLocal == CallConvBuilder::UnsetValue) { callConvLocal = MetaSig::GetDefaultUnmanagedCallingConvention(); } - - if (modifiers & CallConvBuilder::CALL_CONV_MOD_MEMBERFUNCTION) - { - callConvLocal = MetaSig::GetMemberFunctionUnmanagedCallingConventionVariant(callConvLocal); - } } *pCallConv = callConvLocal; return true; diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 11dfd7f..68f311a 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9901,21 +9901,21 @@ namespace return CorInfoCallConvExtension::Fastcall; case IMAGE_CEE_CS_CALLCONV_UNMANAGED: { - CorInfoCallConvExtension callConvMaybe; + CallConvBuilder builder; UINT errorResID; - HRESULT hr = MetaSig::TryGetUnmanagedCallingConventionFromModOpt(mod, pSig, cbSig, &callConvMaybe, pSuppressGCTransition, &errorResID); + HRESULT hr = MetaSig::TryGetUnmanagedCallingConventionFromModOpt(mod, pSig, cbSig, &builder, &errorResID); if (FAILED(hr)) COMPlusThrowHR(hr, errorResID); - if (hr == S_OK) + CorInfoCallConvExtension callConvLocal = builder.GetCurrentCallConv(); + if (callConvLocal == CallConvBuilder::UnsetValue) { - return callConvMaybe; - } - else - { - return MetaSig::GetDefaultUnmanagedCallingConvention(); + callConvLocal = MetaSig::GetDefaultUnmanagedCallingConvention(); } + + *pSuppressGCTransition = builder.IsCurrentCallConvModSet(CallConvBuilder::CALL_CONV_MOD_SUPPRESSGCTRANSITION); + return callConvLocal; } case IMAGE_CEE_CS_CALLCONV_NATIVEVARARG: return CorInfoCallConvExtension::C; diff --git a/src/coreclr/vm/siginfo.cpp b/src/coreclr/vm/siginfo.cpp index 2616540..e458f0d 100644 --- a/src/coreclr/vm/siginfo.cpp +++ b/src/coreclr/vm/siginfo.cpp @@ -5320,20 +5320,17 @@ MetaSig::TryGetUnmanagedCallingConventionFromModOpt( _In_ CORINFO_MODULE_HANDLE pModule, _In_ PCCOR_SIGNATURE pSig, _In_ ULONG cSig, - _Out_ CorInfoCallConvExtension *callConvOut, - _Out_ bool* suppressGCTransitionOut, + _Inout_ CallConvBuilder* builder, _Out_ UINT *errorResID) { CONTRACTL { STANDARD_VM_CHECK; - PRECONDITION(callConvOut != NULL); - PRECONDITION(suppressGCTransitionOut != NULL); + PRECONDITION(builder != NULL); PRECONDITION(errorResID != NULL); } CONTRACTL_END - *suppressGCTransitionOut = false; HRESULT hr; // Instantiations aren't relevant here @@ -5349,9 +5346,7 @@ MetaSig::TryGetUnmanagedCallingConventionFromModOpt( PCCOR_SIGNATURE pWalk = sigPtr.GetPtr(); _ASSERTE(pWalk <= pSig + cSig); - *callConvOut = CorInfoCallConvExtension::Managed; - - CallConvBuilder callConvBuilder; + CallConvBuilder& callConvBuilder = *builder; while ((pWalk < (pSig + cSig)) && ((*pWalk == ELEMENT_TYPE_CMOD_OPT) || (*pWalk == ELEMENT_TYPE_CMOD_REQD))) { BOOL fIsOptional = (*pWalk == ELEMENT_TYPE_CMOD_OPT); @@ -5387,24 +5382,7 @@ MetaSig::TryGetUnmanagedCallingConventionFromModOpt( } } - CallConvBuilder::CallConvModifiers modifiers; - callConvBuilder.GetCurrentCallConv(*callConvOut, modifiers); - - *suppressGCTransitionOut = ((modifiers & CallConvBuilder::CALL_CONV_MOD_SUPPRESSGCTRANSITION) != 0); - - if (modifiers & CallConvBuilder::CALL_CONV_MOD_MEMBERFUNCTION) - { - if (*callConvOut == CallConvBuilder::DefaultValue) - { - // In this case, the only specified calling convention is CallConvMemberFunction. - // Set *callConvOut to the default unmanaged calling convention. - *callConvOut = MetaSig::GetDefaultUnmanagedCallingConvention(); - } - - *callConvOut = MetaSig::GetMemberFunctionUnmanagedCallingConventionVariant(*callConvOut); - } - - return *callConvOut != CallConvBuilder::DefaultValue ? S_OK : S_FALSE; + return S_OK; } // According to ECMA-335, type name strings are UTF-8. Since we are @@ -5415,7 +5393,7 @@ MetaSig::TryGetUnmanagedCallingConventionFromModOpt( namespace { - // Function to compute if a char string begins with another string. + // Function to compute if a char string begins with another char string. bool BeginsWith(size_t s1Len, const char* s1, size_t s2Len, const char* s2) { WRAPPER_NO_CONTRACT; @@ -5426,6 +5404,12 @@ namespace return (0 == strncmp(s1, s2, s2Len)); } + // Function to compute if a char string is equal to another char string. + bool Equals(size_t s1Len, const char* s1, size_t s2Len, const char* s2) + { + return (s1Len == s2Len) && (0 == strcmp(s1, s2)); + } + // All base calling conventions and modifiers should be defined below. // The declaration macros will then be used to construct static data to // be read when parsing strings from metadata. @@ -5445,6 +5429,7 @@ namespace const char* Name; const size_t NameLength; const FLAGTYPE Flag; + bool (* const Matches)(size_t s1Len, const char* s1, size_t s2Len, const char* s2); }; const TypeWithFlag FullyQualifiedTypeBaseCallConvs[] = @@ -5452,7 +5437,8 @@ namespace #define BASE_CALL_CONV(name, flag) { \ MAKE_FULLY_QUALIFIED_CALLCONV_TYPE_NAME_PREFIX(name), \ lengthof(MAKE_FULLY_QUALIFIED_CALLCONV_TYPE_NAME_PREFIX(name)) - 1, \ - CorInfoCallConvExtension::flag }, + CorInfoCallConvExtension::flag, \ + BeginsWith }, DECLARE_BASE_CALL_CONVS @@ -5464,7 +5450,8 @@ namespace #define BASE_CALL_CONV(name, flag) { \ name, \ lengthof(name) - 1, \ - CorInfoCallConvExtension::flag }, + CorInfoCallConvExtension::flag, \ + Equals }, DECLARE_BASE_CALL_CONVS @@ -5476,7 +5463,8 @@ namespace #define CALL_CONV_MODIFIER(name, flag) { \ MAKE_FULLY_QUALIFIED_CALLCONV_TYPE_NAME_PREFIX(name), \ lengthof(MAKE_FULLY_QUALIFIED_CALLCONV_TYPE_NAME_PREFIX(name)) - 1, \ - CallConvBuilder::flag }, + CallConvBuilder::flag, \ + BeginsWith }, DECLARE_MOD_CALL_CONVS @@ -5488,7 +5476,8 @@ namespace #define CALL_CONV_MODIFIER(name, flag) { \ name, \ lengthof(name) - 1, \ - CallConvBuilder::flag }, + CallConvBuilder::flag, \ + Equals }, DECLARE_MOD_CALL_CONVS @@ -5510,25 +5499,27 @@ namespace // Check if the type is a base calling convention. for (size_t i = 0; i < BASECOUNT; ++i) { - if (!BeginsWith(typeLength, typeName, baseTypes[i].NameLength, baseTypes[i].Name)) + const TypeWithFlag& entry = baseTypes[i]; + if (!entry.Matches(typeLength, typeName, entry.NameLength, entry.Name)) continue; // If the base calling convention is already set, then we are observing an error. - if (state.CallConvBase != CallConvBuilder::DefaultValue) + if (state.CallConvBase != CallConvBuilder::UnsetValue) return false; - state.CallConvBase = baseTypes[i].Flag; + state.CallConvBase = entry.Flag; return true; } // Check if the type is a modifier calling convention. for (size_t i = 0; i < MODCOUNT; ++i) { - if (!BeginsWith(typeLength, typeName, modTypes[i].NameLength, modTypes[i].Name)) + const TypeWithFlag& entry = modTypes[i]; + if (!entry.Matches(typeLength, typeName, entry.NameLength, entry.Name)) continue; // Combine the current modifier with the existing ones. - state.CallConvModifiers = (CallConvBuilder::CallConvModifiers)(state.CallConvModifiers | modTypes[i].Flag); + state.CallConvModifiers = (CallConvBuilder::CallConvModifiers)(state.CallConvModifiers | entry.Flag); return true; } @@ -5536,12 +5527,30 @@ namespace // we don't know anything about. return true; } + + CorInfoCallConvExtension GetMemberFunctionUnmanagedCallingConventionVariant(CorInfoCallConvExtension baseCallConv) + { + switch (baseCallConv) + { + case CorInfoCallConvExtension::C: + return CorInfoCallConvExtension::CMemberFunction; + case CorInfoCallConvExtension::Stdcall: + return CorInfoCallConvExtension::StdcallMemberFunction; + case CorInfoCallConvExtension::Fastcall: + return CorInfoCallConvExtension::FastcallMemberFunction; + case CorInfoCallConvExtension::Thiscall: + return CorInfoCallConvExtension::Thiscall; + default: + _ASSERTE("Calling convention is not an unmanaged base calling convention."); + return baseCallConv; + } + } } -const CorInfoCallConvExtension CallConvBuilder::DefaultValue = CorInfoCallConvExtension::Managed; +const CorInfoCallConvExtension CallConvBuilder::UnsetValue = CorInfoCallConvExtension::Managed; CallConvBuilder::CallConvBuilder() - : _state{ DefaultValue , CALL_CONV_MOD_NONE } + : _state{ UnsetValue , CALL_CONV_MOD_NONE } { LIMITED_METHOD_CONTRACT; } @@ -5584,13 +5593,31 @@ bool CallConvBuilder::AddTypeName( TypeModCallConvs); } -void CallConvBuilder::GetCurrentCallConv( - _Out_ CorInfoCallConvExtension &baseCallConv, - _Out_ CallConvModifiers &modsCallConv) +CorInfoCallConvExtension CallConvBuilder::GetCurrentCallConv() const +{ + LIMITED_METHOD_CONTRACT; + + if (IsCurrentCallConvModSet(CallConvBuilder::CALL_CONV_MOD_MEMBERFUNCTION)) + { + CorInfoCallConvExtension baseMaybe = _state.CallConvBase; + if (baseMaybe == CallConvBuilder::UnsetValue) + { + // In this case, the only specified calling convention is CallConvMemberFunction. + // When the Member function modifier is defined with no base type, we assume + // the default unmanaged calling convention. + baseMaybe = MetaSig::GetDefaultUnmanagedCallingConvention(); + } + + return GetMemberFunctionUnmanagedCallingConventionVariant(baseMaybe); + } + + return _state.CallConvBase; +} + +bool CallConvBuilder::IsCurrentCallConvModSet(_In_ CallConvModifiers mod) const { LIMITED_METHOD_CONTRACT; - baseCallConv = _state.CallConvBase; - modsCallConv = _state.CallConvModifiers; + return (mod & _state.CallConvModifiers) != CALL_CONV_MOD_NONE; } //--------------------------------------------------------------------------------------- diff --git a/src/coreclr/vm/siginfo.hpp b/src/coreclr/vm/siginfo.hpp index 271c8e4..c41abe9 100644 --- a/src/coreclr/vm/siginfo.hpp +++ b/src/coreclr/vm/siginfo.hpp @@ -506,6 +506,53 @@ private: TokenPairList *m_pNext; }; // class TokenPairList +// Attempts to parse the provided calling convention names to construct a +// calling convention with known modifiers. +// +// The Add* functions return false if the type is known but cannot be applied. +// Otherwise, they return true. +class CallConvBuilder final +{ +public: + enum CallConvModifiers + { + CALL_CONV_MOD_NONE = 0, + CALL_CONV_MOD_SUPPRESSGCTRANSITION = 0x1, + CALL_CONV_MOD_MEMBERFUNCTION = 0x2 + }; + + struct State + { + CorInfoCallConvExtension CallConvBase; + CallConvModifiers CallConvModifiers; + }; + +private: + State _state; + +public: + // The initial "unset" base calling convention. + static const CorInfoCallConvExtension UnsetValue; + + CallConvBuilder(); + + // Add a fully qualified type name to the calling convention computation. + bool AddFullyQualifiedTypeName( + _In_ size_t typeLength, + _In_z_ LPCSTR typeName); + + // Add a simple type name to the calling convention computation. + bool AddTypeName( + _In_ size_t typeLength, + _In_z_ LPCSTR typeName); + + // Get the currently computed calling convention value. + CorInfoCallConvExtension GetCurrentCallConv() const; + + // Check if the modifier is set on the computed calling convention. + bool IsCurrentCallConvModSet(_In_ CallConvModifiers mod) const; +}; + //--------------------------------------------------------------------------------------- // class MetaSig @@ -784,8 +831,7 @@ class MetaSig // Gets the unmanaged calling convention by reading any modopts. // // Returns: - // S_OK - Calling convention was read from modopt - // S_FALSE - Calling convention was not read from modopt + // S_OK - No errors // COR_E_BADIMAGEFORMAT - Signature had an invalid format // COR_E_INVALIDPROGRAM - Program is considered invalid (more // than one calling convention specified) @@ -794,8 +840,7 @@ class MetaSig _In_ CORINFO_MODULE_HANDLE pModule, _In_ PCCOR_SIGNATURE pSig, _In_ ULONG cSig, - _Out_ CorInfoCallConvExtension *callConvOut, - _Out_ bool* suppressGCTransitionOut, + _Inout_ CallConvBuilder *builder, _Out_ UINT *errorResID); static CorInfoCallConvExtension GetDefaultUnmanagedCallingConvention() @@ -807,24 +852,6 @@ class MetaSig #endif // !TARGET_UNIX } - static CorInfoCallConvExtension GetMemberFunctionUnmanagedCallingConventionVariant(CorInfoCallConvExtension baseCallConv) - { - switch (baseCallConv) - { - case CorInfoCallConvExtension::C: - return CorInfoCallConvExtension::CMemberFunction; - case CorInfoCallConvExtension::Stdcall: - return CorInfoCallConvExtension::StdcallMemberFunction; - case CorInfoCallConvExtension::Fastcall: - return CorInfoCallConvExtension::FastcallMemberFunction; - case CorInfoCallConvExtension::Thiscall: - return CorInfoCallConvExtension::Thiscall; - default: - _ASSERTE("Calling convention is not an unmanaged base calling convention."); - return baseCallConv; - } - } - //------------------------------------------------------------------ // Like NextArg, but return only normalized type (enums flattned to // underlying type ... @@ -1184,52 +1211,6 @@ public: BYTE m_CallConv; }; // class MetaSig -// Attempts to parse the provided calling convention names to construct a -// calling convention with known modifiers. -// -// The Add* functions return false if the type is known but cannot be applied. -// Otherwise, they return true. -class CallConvBuilder final -{ -public: - enum CallConvModifiers - { - CALL_CONV_MOD_NONE = 0, - CALL_CONV_MOD_SUPPRESSGCTRANSITION = 0x1, - CALL_CONV_MOD_MEMBERFUNCTION = 0x2 - }; - - struct State - { - CorInfoCallConvExtension CallConvBase; - CallConvModifiers CallConvModifiers; - }; - -private: - State _state; - -public: - // The initial "unset" base calling convention. - static const CorInfoCallConvExtension DefaultValue; - - CallConvBuilder(); - - // Add a fully qualified type name to the calling convention computation. - bool AddFullyQualifiedTypeName( - _In_ size_t typeLength, - _In_z_ LPCSTR typeName); - - // Add a simple type name to the calling convention computation. - bool AddTypeName( - _In_ size_t typeLength, - _In_z_ LPCSTR typeName); - - // Get the currently computed calling convention values. - void GetCurrentCallConv( - _Out_ CorInfoCallConvExtension &baseCallConv, - _Out_ CallConvModifiers &modsCallConv); -}; - BOOL IsTypeRefOrDef(LPCSTR szClassName, Module *pModule, mdToken token); #if defined(FEATURE_TYPEEQUIVALENCE) && !defined(DACCESS_COMPILE) -- 2.7.4