summaryrefslogtreecommitdiff
path: root/src/vm
diff options
context:
space:
mode:
authorRyan Byington <ryanbyi@microsoft.com>2015-04-28 17:53:30 -0700
committerRyan Byington <ryanbyi@microsoft.com>2015-04-28 17:53:30 -0700
commitfb68f332e9123d74bd1cc7187be000bc3cbf67d2 (patch)
treee8aca912b70dd791502d977beb6262e264dda1e2 /src/vm
parent2fd35925a66be17a46467050751c309b93f2013b (diff)
downloadcoreclr-fb68f332e9123d74bd1cc7187be000bc3cbf67d2.tar.gz
coreclr-fb68f332e9123d74bd1cc7187be000bc3cbf67d2.tar.bz2
coreclr-fb68f332e9123d74bd1cc7187be000bc3cbf67d2.zip
Updating WinRT Projections to use Facades
WinRT projections currently depend on implementation assemblies like System.Uri living in System.dll. System.Uri has already been moved out of System.dll to Internal.Uri.dll which breaks the projection for System.Uri. This change updates the WinRT projection to understand Facades like System.Runtime to resolve System.Uri. When we load a type like System.Uri we need to know if it is a projected type. We currently do this by comparing the namespace plus type name and assembly however this only works because we know the implementation assembly at compile time. I am changing it so that we use ClassLoader to resolve the typedef and assembly and compare the resolved assembly with the current one. Also removing the cached assemblies as they don’t add a lot of value anymore. [tfs-changeset: 1461733]
Diffstat (limited to 'src/vm')
-rw-r--r--src/vm/appdomain.cpp151
-rw-r--r--src/vm/appdomain.hpp16
-rw-r--r--src/vm/class.cpp2
-rw-r--r--src/vm/classnames.h12
-rw-r--r--src/vm/clsload.cpp33
-rw-r--r--src/vm/clsload.hpp10
-rw-r--r--src/vm/interoputil.cpp88
-rw-r--r--src/vm/methodtablebuilder.cpp49
-rw-r--r--src/vm/winrtredirector.h14
-rw-r--r--src/vm/winrttypenameconverter.cpp144
-rw-r--r--src/vm/winrttypenameconverter.h5
11 files changed, 252 insertions, 272 deletions
diff --git a/src/vm/appdomain.cpp b/src/vm/appdomain.cpp
index 4c02f35f7f..64bd4410bf 100644
--- a/src/vm/appdomain.cpp
+++ b/src/vm/appdomain.cpp
@@ -4865,11 +4865,6 @@ AppDomain::AppDomain()
m_pLicenseInteropHelperMT = NULL;
m_COMorRemotingFlag = COMorRemoting_NotInitialized;
memset(m_rpCLRTypes, 0, sizeof(m_rpCLRTypes));
- m_pSystemDll = nullptr;
- m_pSystemRuntimeWindowsRuntimeDll = nullptr;
- m_pSystemRuntimeWindowsRuntimeUIXamlDll = nullptr;
- m_pSystemNumericsVectors = nullptr;
- m_pInternalUri = nullptr;
#endif // FEATURE_COMINTEROP
m_pUMEntryThunkCache = NULL;
@@ -5912,106 +5907,10 @@ MethodTable* AppDomain::LoadRedirectedType(WinMDAdapter::RedirectedTypeIndex ind
CLASS_LOAD_EXACTPARENTS).GetMethodTable();
}
}
-
-bool AppDomain::FindRedirectedAssembly(Assembly* pAssembly, WinMDAdapter::FrameworkAssemblyIndex* pIndex)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pAssembly));
- PRECONDITION(CheckPointer(pIndex));
- }
- CONTRACTL_END;
-
- DomainAssembly *pDomainAssembly = pAssembly->GetDomainAssembly();
-
- if (pDomainAssembly->IsSystem())
- {
- *pIndex = WinMDAdapter::FrameworkAssembly_Mscorlib;
- return true;
- }
- else if (pDomainAssembly == m_pSystemDll)
- {
- *pIndex = WinMDAdapter::FrameworkAssembly_System;
- return true;
- }
- else if (pDomainAssembly == m_pSystemRuntimeWindowsRuntimeDll)
- {
- *pIndex = WinMDAdapter::FrameworkAssembly_SystemRuntimeWindowsRuntime;
- return true;
- }
- else if (pDomainAssembly == m_pSystemRuntimeWindowsRuntimeUIXamlDll)
- {
- *pIndex = WinMDAdapter::FrameworkAssembly_SystemRuntimeWindowsRuntimeUIXaml;
- return true;
- }
- else if (pDomainAssembly == m_pSystemNumericsVectors)
- {
- *pIndex = WinMDAdapter::FrameworkAssembly_SystemNumericsVectors;
- return true;
- }
- else if (pDomainAssembly == m_pInternalUri)
- {
- *pIndex = WinMDAdapter::FrameworkAssembly_InternalUri;
- return true;
- }
-
- return false;
-}
-
#endif //FEATURE_COMINTEROP
#endif //!DACCESS_COMPILE
-
-#ifdef FEATURE_COMINTEROP
-BOOL AppDomain::FindRedirectedAssemblyFromIndexIfLoaded(WinMDAdapter::FrameworkAssemblyIndex index, Assembly ** ppAssembly)
-{
- LIMITED_METHOD_CONTRACT;
-
- // If new redirected assemblies are added, this function probably needs to be updated
- C_ASSERT(WinMDAdapter::FrameworkAssembly_Count == 6);
-
- DomainAssembly * pDomainAssembly = NULL;
-
- if (index == WinMDAdapter::FrameworkAssembly_Mscorlib)
- {
- *ppAssembly = SystemDomain::SystemAssembly();
- return TRUE;
- }
- else if (index == WinMDAdapter::FrameworkAssembly_System)
- {
- pDomainAssembly = m_pSystemDll;
- }
- else if (index == WinMDAdapter::FrameworkAssembly_SystemRuntimeWindowsRuntime)
- {
- pDomainAssembly = m_pSystemRuntimeWindowsRuntimeDll;
- }
- else if (index == WinMDAdapter::FrameworkAssembly_SystemRuntimeWindowsRuntimeUIXaml)
- {
- pDomainAssembly = m_pSystemRuntimeWindowsRuntimeUIXamlDll;
- }
- else if (index == WinMDAdapter::FrameworkAssembly_SystemNumericsVectors)
- {
- pDomainAssembly = m_pSystemNumericsVectors;
- }
- else if (index == WinMDAdapter::FrameworkAssembly_InternalUri)
- {
- pDomainAssembly = m_pInternalUri;
- }
-
- if (pDomainAssembly != NULL)
- {
- *ppAssembly = pDomainAssembly->GetAssembly();
- return TRUE;
- }
-
- *ppAssembly = NULL;
- return FALSE;
-}
-
-#endif // FEATURE_COMINTEROP
-
#ifndef DACCESS_COMPILE
void AppDomain::CreateSecurityDescriptor()
@@ -6084,56 +5983,6 @@ void AppDomain::AddAssembly(DomainAssembly * assem)
// If empty space not found, simply add to end of list
IfFailThrow(m_Assemblies.Append_Unlocked(assem));
}
-
-#ifdef FEATURE_COMINTEROP
- // See if this is one of the well-known assemblies that we look for
- if (m_pSystemDll == nullptr && IsPlatformAssembly("System", assem))
- {
- m_pSystemDll = assem;
- return;
- }
-
- if (m_pSystemRuntimeWindowsRuntimeDll == nullptr && IsPlatformAssembly("System.Runtime.WindowsRuntime", assem))
- {
- m_pSystemRuntimeWindowsRuntimeDll = assem;
- return;
- }
- if (m_pSystemRuntimeWindowsRuntimeUIXamlDll == nullptr && IsPlatformAssembly("System.Runtime.WindowsRuntime.UI.Xaml", assem))
- {
- m_pSystemRuntimeWindowsRuntimeUIXamlDll = assem;
- return;
- }
- if (m_pSystemNumericsVectors == nullptr)
- {
- PEAssembly *pPEAssembly = assem->GetFile();
-
- if (strcmp("System.Numerics.Vectors", pPEAssembly->GetSimpleName()) == 0)
- {
- DWORD cbPublicKey;
- const BYTE *pbPublicKey = static_cast<const BYTE *>(pPEAssembly->GetPublicKey(&cbPublicKey));
-
- if (cbPublicKey == sizeof(s_pbContractPublicKey) && memcmp(pbPublicKey, s_pbContractPublicKey, cbPublicKey) == 0)
- {
- m_pSystemNumericsVectors = assem;
- }
- }
- }
- if (m_pInternalUri == nullptr)
- {
- PEAssembly *pPEAssembly = assem->GetFile();
-
- if (strcmp("Internal.Uri", pPEAssembly->GetSimpleName()) == 0)
- {
- DWORD cbPublicKey;
- const BYTE *pbPublicKey = static_cast<const BYTE *>(pPEAssembly->GetPublicKey(&cbPublicKey));
-
- if (cbPublicKey == sizeof(s_pbContractPublicKey) && memcmp(pbPublicKey, s_pbContractPublicKey, cbPublicKey) == 0)
- {
- m_pInternalUri = assem;
- }
- }
- }
-#endif // FEATURE_COMINTEROP
}
void AppDomain::RemoveAssembly_Unlocked(DomainAssembly * pAsm)
diff --git a/src/vm/appdomain.hpp b/src/vm/appdomain.hpp
index 49e6a72759..a48cafbac9 100644
--- a/src/vm/appdomain.hpp
+++ b/src/vm/appdomain.hpp
@@ -2103,7 +2103,6 @@ public:
HRESULT GetComIPForExposedObject(IUnknown **pComIP);
MethodTable *GetRedirectedType(WinMDAdapter::RedirectedTypeIndex index);
- bool FindRedirectedAssembly(Assembly* pAssembly, WinMDAdapter::FrameworkAssemblyIndex* pIndex);
#endif // FEATURE_COMINTEROP
@@ -3409,21 +3408,6 @@ private:
COMorRemotingFlag m_COMorRemotingFlag;
OBJECTHANDLE m_hndMissing; //Handle points to Missing.Value Object which is used for [Optional] arg scenario during IDispatch CCW Call
- PTR_DomainAssembly m_pSystemDll; // System.dll loaded into this domain
- PTR_DomainAssembly m_pSystemRuntimeWindowsRuntimeDll; // System.Runtime.WindowsRuntime.dll loaded into this domain
- PTR_DomainAssembly m_pSystemRuntimeWindowsRuntimeUIXamlDll; // System.Runtime.WindowsRuntime.UI.Xaml.dll loaded into this domain
- PTR_DomainAssembly m_pSystemNumericsVectors; // System.Numerics.Vectors.dll loaded into this domain
- PTR_DomainAssembly m_pInternalUri; // Internal.Uri.dll loaded into this domain
-public:
- BOOL FindRedirectedAssemblyFromIndexIfLoaded(WinMDAdapter::FrameworkAssemblyIndex index, Assembly** ppAssembly);
-
- BOOL IsSystemDll(Assembly *pAssembly)
- {
- LIMITED_METHOD_CONTRACT;
- return (m_pSystemDll != NULL && m_pSystemDll->GetCurrentAssembly() == pAssembly);
- }
-private:
-
MethodTable* m_rpCLRTypes[WinMDAdapter::RedirectedTypeIndex_Count];
MethodTable* LoadRedirectedType(WinMDAdapter::RedirectedTypeIndex index, WinMDAdapter::FrameworkAssemblyIndex assembly);
diff --git a/src/vm/class.cpp b/src/vm/class.cpp
index 108016537e..932f8bed00 100644
--- a/src/vm/class.cpp
+++ b/src/vm/class.cpp
@@ -3782,7 +3782,7 @@ HRESULT EEClass::WriteCompactLayoutTypeFlags(ICompactLayoutWriter *pICLW)
_ASSERTE("MDIL Compiler has determined that a winrt type needs per-type-RCW data, but is not a platform type." &&
(GetMethodTable()->GetModule()->GetAssembly()->GetManifestFile()->IsProfileAssembly() ||
GetMethodTable()->GetModule()->GetAssembly()->IsWinMD() ||
- GetAppDomain()->IsSystemDll(GetMethodTable()->GetModule()->GetAssembly())));
+ GetWinRTRedirectedTypeIndex() != WinMDAdapter::RedirectedTypeIndex_Invalid));
#endif
#ifdef _DEBUG
if (GetMethodTable()->GetModule()->GetAssembly()->IsWinMD())
diff --git a/src/vm/classnames.h b/src/vm/classnames.h
index fe75f7aa52..8d53eb0216 100644
--- a/src/vm/classnames.h
+++ b/src/vm/classnames.h
@@ -52,7 +52,19 @@
#define g_ICommandName "System.Windows.Input.ICommand"
#define g_ComObjectName "__ComObject"
#define g_RuntimeClassName "RuntimeClass"
+#define g_INotifyCollectionChanged_WinRTName "System.Runtime.InteropServices.WindowsRuntime.INotifyCollectionChanged_WinRT"
+#define g_NotifyCollectionChangedToManagedAdapterName "System.Runtime.InteropServices.WindowsRuntime.NotifyCollectionChangedToManagedAdapter"
+#define g_NotifyCollectionChangedToWinRTAdapterName "System.Runtime.InteropServices.WindowsRuntime.NotifyCollectionChangedToWinRTAdapter"
+#define g_INotifyPropertyChanged_WinRTName "System.Runtime.InteropServices.WindowsRuntime.INotifyPropertyChanged_WinRT"
+#define g_NotifyPropertyChangedToManagedAdapterName "System.Runtime.InteropServices.WindowsRuntime.NotifyPropertyChangedToManagedAdapter"
+#define g_NotifyPropertyChangedToWinRTAdapterName "System.Runtime.InteropServices.WindowsRuntime.NotifyPropertyChangedToWinRTAdapter"
+#define g_ICommand_WinRTName "System.Runtime.InteropServices.WindowsRuntime.ICommand_WinRT"
+#define g_ICommandToManagedAdapterName "System.Runtime.InteropServices.WindowsRuntime.ICommandToManagedAdapter"
+#define g_ICommandToWinRTAdapterName "System.Runtime.InteropServices.WindowsRuntime.ICommandToWinRTAdapter"
+#define g_NotifyCollectionChangedEventHandler_WinRT "System.Runtime.InteropServices.WindowsRuntime.NotifyCollectionChangedEventHandler_WinRT"
+#define g_PropertyChangedEventHandler_WinRT_Name "System.Runtime.InteropServices.WindowsRuntime.PropertyChangedEventHandler_WinRT"
#endif // FEATURE_COMINTEROP
+
#ifdef FEATURE_REMOTING
#define g_ContextBoundObjectClassName "System.ContextBoundObject"
#endif
diff --git a/src/vm/clsload.cpp b/src/vm/clsload.cpp
index 59ceddd9e8..2798ce2c77 100644
--- a/src/vm/clsload.cpp
+++ b/src/vm/clsload.cpp
@@ -3069,11 +3069,38 @@ ClassLoader::ResolveTokenToTypeDefThrowing(
{
nameHandle.SetTokenNotToLoad(tdAllTypes);
}
-
+
+ return ResolveNameToTypeDefThrowing(pFoundRefModule, &nameHandle, ppTypeDefModule, pTypeDefToken, loadFlag, pfUsesTypeForwarder);
+}
+
+/*static*/
+BOOL
+ClassLoader::ResolveNameToTypeDefThrowing(
+ Module * pModule,
+ NameHandle * pName,
+ Module ** ppTypeDefModule,
+ mdTypeDef * pTypeDefToken,
+ Loader::LoadFlag loadFlag,
+ BOOL * pfUsesTypeForwarder) // The semantic of this parameter: TRUE if a type forwarder is found. It is never set to FALSE.
+{
+ CONTRACT(BOOL)
+ {
+ if (FORBIDGC_LOADER_USE_ENABLED()) NOTHROW; else THROWS;
+ if (FORBIDGC_LOADER_USE_ENABLED()) GC_NOTRIGGER; else GC_TRIGGERS;
+ MODE_ANY;
+ if (FORBIDGC_LOADER_USE_ENABLED()) FORBID_FAULT; else { INJECT_FAULT(COMPlusThrowOM()); }
+ PRECONDITION(CheckPointer(pModule));
+ PRECONDITION(CheckPointer(pName));
+ SUPPORTS_DAC;
+ }
+ CONTRACT_END;
+
+ TypeHandle typeHnd;
mdToken foundTypeDef;
Module * pFoundModule;
mdExportedType foundExportedType;
- Module * pSourceModule = pFoundRefModule;
+ Module * pSourceModule = pModule;
+ Module * pFoundRefModule = pModule;
for (UINT32 nTypeForwardingChainSize = 0; nTypeForwardingChainSize < const_cMaxTypeForwardingChainSize; nTypeForwardingChainSize++)
{
@@ -3081,7 +3108,7 @@ ClassLoader::ResolveTokenToTypeDefThrowing(
pFoundModule = NULL;
foundExportedType = mdTokenNil;
if (!pSourceModule->GetClassLoader()->FindClassModuleThrowing(
- &nameHandle,
+ pName,
&typeHnd,
&foundTypeDef,
&pFoundModule,
diff --git a/src/vm/clsload.hpp b/src/vm/clsload.hpp
index 2b56a8e20e..5a16245be0 100644
--- a/src/vm/clsload.hpp
+++ b/src/vm/clsload.hpp
@@ -733,6 +733,16 @@ public:
mdTypeDef * pTypeDefToken,
Loader::LoadFlag loadFlag = Loader::Load,
BOOL * pfUsesTypeForwarder = NULL);
+
+ // Resolve a name to a TypeDef
+ // Return FALSE if operation failed (e.g. type does not exist)
+ // *pfUsesTypeForwarder is set to TRUE if a type forwarder is found. It is never set to FALSE.
+ static BOOL ResolveNameToTypeDefThrowing(Module * pTypeRefModule,
+ NameHandle * pName,
+ Module ** ppTypeDefModule,
+ mdTypeDef * pTypeDefToken,
+ Loader::LoadFlag loadFlag = Loader::Load,
+ BOOL * pfUsesTypeForwarder = NULL);
#endif // !BINDER
static void EnsureLoaded(TypeHandle typeHnd, ClassLoadLevel level = CLASS_LOADED);
diff --git a/src/vm/interoputil.cpp b/src/vm/interoputil.cpp
index 6dbc7c1e50..efdc12a0e3 100644
--- a/src/vm/interoputil.cpp
+++ b/src/vm/interoputil.cpp
@@ -295,20 +295,44 @@ static const BinderMethodID s_stubsDisposableToClosable[] =
METHOD__IDISPOSABLE_TO_ICLOSABLE_ADAPTER__CLOSE
};
+#ifdef FEATURE_CORECLR
+#define FX_PLATFORM_KEY g_CoreClrKeyToken
+#else
+#define FX_PLATFORM_KEY g_ECMAKeyToken
+#endif
+
+DEFINE_ASM_QUAL_TYPE_NAME(NCCWINRT_ASM_QUAL_TYPE_NAME, g_INotifyCollectionChanged_WinRTName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, FX_PLATFORM_KEY);
+DEFINE_ASM_QUAL_TYPE_NAME(NCCMA_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedToManagedAdapterName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, FX_PLATFORM_KEY);
+DEFINE_ASM_QUAL_TYPE_NAME(NCCWA_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedToWinRTAdapterName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, FX_PLATFORM_KEY);
+DEFINE_ASM_QUAL_TYPE_NAME(NPCWINRT_ASM_QUAL_TYPE_NAME, g_INotifyPropertyChanged_WinRTName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, FX_PLATFORM_KEY);
+DEFINE_ASM_QUAL_TYPE_NAME(NPCMA_ASM_QUAL_TYPE_NAME, g_NotifyPropertyChangedToManagedAdapterName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, FX_PLATFORM_KEY);
+DEFINE_ASM_QUAL_TYPE_NAME(NPCWA_ASM_QUAL_TYPE_NAME, g_NotifyPropertyChangedToWinRTAdapterName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, FX_PLATFORM_KEY);
+DEFINE_ASM_QUAL_TYPE_NAME(CMDWINRT_ASM_QUAL_TYPE_NAME, g_ICommand_WinRTName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, FX_PLATFORM_KEY);
+DEFINE_ASM_QUAL_TYPE_NAME(CMDMA_ASM_QUAL_TYPE_NAME, g_ICommandToManagedAdapterName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, FX_PLATFORM_KEY);
+DEFINE_ASM_QUAL_TYPE_NAME(CMDWA_ASM_QUAL_TYPE_NAME, g_ICommandToWinRTAdapterName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, FX_PLATFORM_KEY);
+DEFINE_ASM_QUAL_TYPE_NAME(NCCEHWINRT_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedEventHandler_WinRT, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, FX_PLATFORM_KEY);
+DEFINE_ASM_QUAL_TYPE_NAME(PCEHWINRT_ASM_QUAL_TYPE_NAME, g_PropertyChangedEventHandler_WinRT_Name, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, FX_PLATFORM_KEY);
+
const WinRTInterfaceRedirector::NonMscorlibRedirectedInterfaceInfo WinRTInterfaceRedirector::s_rNonMscorlibInterfaceInfos[3] =
{
- { WinMDAdapter::FrameworkAssembly_System, W("System.Runtime.InteropServices.WindowsRuntime.INotifyCollectionChanged_WinRT"),
- W("System.Runtime.InteropServices.WindowsRuntime.NotifyCollectionChangedToManagedAdapter"),
- W("System.Runtime.InteropServices.WindowsRuntime.NotifyCollectionChangedToWinRTAdapter"),
- s_stubNamesNotifyCollectionChanged },
- { WinMDAdapter::FrameworkAssembly_System, W("System.Runtime.InteropServices.WindowsRuntime.INotifyPropertyChanged_WinRT"),
- W("System.Runtime.InteropServices.WindowsRuntime.NotifyPropertyChangedToManagedAdapter"),
- W("System.Runtime.InteropServices.WindowsRuntime.NotifyPropertyChangedToWinRTAdapter"),
- s_stubNamesNotifyPropertyChanged },
- { WinMDAdapter::FrameworkAssembly_System, W("System.Runtime.InteropServices.WindowsRuntime.ICommand_WinRT"),
- W("System.Runtime.InteropServices.WindowsRuntime.ICommandToManagedAdapter"),
- W("System.Runtime.InteropServices.WindowsRuntime.ICommandToWinRTAdapter"),
- s_stubNamesICommand },
+ {
+ NCCWINRT_ASM_QUAL_TYPE_NAME,
+ NCCMA_ASM_QUAL_TYPE_NAME,
+ NCCWA_ASM_QUAL_TYPE_NAME,
+ s_stubNamesNotifyCollectionChanged
+ },
+ {
+ NPCWINRT_ASM_QUAL_TYPE_NAME,
+ NPCMA_ASM_QUAL_TYPE_NAME,
+ NPCWA_ASM_QUAL_TYPE_NAME,
+ s_stubNamesNotifyPropertyChanged
+ },
+ {
+ CMDWINRT_ASM_QUAL_TYPE_NAME,
+ CMDMA_ASM_QUAL_TYPE_NAME,
+ CMDWA_ASM_QUAL_TYPE_NAME,
+ s_stubNamesICommand
+ },
};
#define SYSTEMDLL__INOTIFYCOLLECTIONCHANGED ((BinderClassID)(WinRTInterfaceRedirector::NON_MSCORLIB_MARKER | 0))
@@ -6065,31 +6089,14 @@ MethodTable *WinRTInterfaceRedirector::GetWinRTTypeForRedirectedInterfaceIndex(W
{
// the redirected interface lives in some other Framework assembly
const NonMscorlibRedirectedInterfaceInfo *pInfo = &s_rNonMscorlibInterfaceInfos[id & ~NON_MSCORLIB_MARKER];
- RETURN LoadTypeFromRedirectedAssembly(pInfo->m_AssemblyIndex, pInfo->m_wzWinRTInterfaceTypeName);
- }
-}
+ SString assemblyQualifiedTypeName(SString::Utf8, pInfo->m_szWinRTInterfaceAssemblyQualifiedTypeName);
-//
-MethodTable *WinRTInterfaceRedirector::LoadTypeFromRedirectedAssembly(WinMDAdapter::FrameworkAssemblyIndex index, LPCWSTR wzTypeName)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
+ RETURN TypeName::GetTypeFromAsmQualifiedName(assemblyQualifiedTypeName.GetUnicode(), FALSE).GetMethodTable();
}
- CONTRACTL_END;
-
- Assembly *pAssembly;
-
- if (!::GetAppDomain()->FindRedirectedAssemblyFromIndexIfLoaded(index, &pAssembly))
- return NULL;
-
- return TypeName::GetTypeFromAssembly(wzTypeName, pAssembly).GetMethodTable();
}
//
-MethodDesc *WinRTInterfaceRedirector::LoadMethodFromRedirectedAssembly(WinMDAdapter::FrameworkAssemblyIndex index, LPCWSTR wzTypeName, LPCUTF8 szMethodName)
+MethodDesc *WinRTInterfaceRedirector::LoadMethodFromRedirectedAssembly(LPCUTF8 szAssemblyQualifiedTypeName, LPCUTF8 szMethodName)
{
CONTRACTL
{
@@ -6099,7 +6106,9 @@ MethodDesc *WinRTInterfaceRedirector::LoadMethodFromRedirectedAssembly(WinMDAdap
}
CONTRACTL_END;
- MethodTable *pMT = LoadTypeFromRedirectedAssembly(index, wzTypeName);
+ SString assemblyQualifiedTypeName(SString::Utf8, szAssemblyQualifiedTypeName);
+
+ MethodTable *pMT = TypeName::GetTypeFromAsmQualifiedName(assemblyQualifiedTypeName.GetUnicode(), FALSE).GetMethodTable();
return MemberLoader::FindMethodByName(pMT, szMethodName);
}
@@ -6215,8 +6224,7 @@ MethodDesc *WinRTInterfaceRedirector::GetStubMethodForRedirectedInterface(WinMDA
const NonMscorlibRedirectedInterfaceInfo *pInfo = &s_rNonMscorlibInterfaceInfos[pStubInfo->m_WinRTInterface & ~NON_MSCORLIB_MARKER];
pMD = LoadMethodFromRedirectedAssembly(
- pInfo->m_AssemblyIndex,
- (interopKind == TypeHandle::Interop_NativeToManaged) ? pInfo->m_wzWinRTStubClassTypeName : pInfo->m_wzCLRStubClassTypeName,
+ (interopKind == TypeHandle::Interop_NativeToManaged) ? pInfo->m_szWinRTStubClassAssemblyQualifiedTypeName : pInfo->m_szCLRStubClassAssemblyQualifiedTypeName,
pInfo->m_rszMethodNames[method]);
}
@@ -6368,16 +6376,14 @@ MethodTable *WinRTDelegateRedirector::GetWinRTTypeForRedirectedDelegateIndex(Win
case WinMDAdapter::RedirectedTypeIndex_System_Collections_Specialized_NotifyCollectionChangedEventHandler:
{
- Assembly *pAssembly;
- VERIFY(::GetAppDomain()->FindRedirectedAssemblyFromIndexIfLoaded(WinMDAdapter::FrameworkAssembly_System, &pAssembly));
- return TypeName::GetTypeFromAssembly(W("System.Runtime.InteropServices.WindowsRuntime.NotifyCollectionChangedEventHandler_WinRT"), pAssembly).GetMethodTable();
+ SString assemblyQualifiedTypeName(SString::Utf8, NCCEHWINRT_ASM_QUAL_TYPE_NAME);
+ return TypeName::GetTypeFromAsmQualifiedName(assemblyQualifiedTypeName.GetUnicode(), FALSE).GetMethodTable();
}
case WinMDAdapter::RedirectedTypeIndex_System_ComponentModel_PropertyChangedEventHandler:
{
- Assembly *pAssembly;
- VERIFY(::GetAppDomain()->FindRedirectedAssemblyFromIndexIfLoaded(WinMDAdapter::FrameworkAssembly_System, &pAssembly));
- return TypeName::GetTypeFromAssembly(W("System.Runtime.InteropServices.WindowsRuntime.PropertyChangedEventHandler_WinRT"), pAssembly).GetMethodTable();
+ SString assemblyQualifiedTypeName(SString::Utf8, PCEHWINRT_ASM_QUAL_TYPE_NAME);
+ return TypeName::GetTypeFromAsmQualifiedName(assemblyQualifiedTypeName.GetUnicode(), FALSE).GetMethodTable();
}
default:
diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp
index db099e2996..02846290f1 100644
--- a/src/vm/methodtablebuilder.cpp
+++ b/src/vm/methodtablebuilder.cpp
@@ -58,20 +58,6 @@ const char* FormatSig(MethodDesc* pMD, LoaderHeap *pHeap, AllocMemTracker *pamTr
unsigned g_dupMethods = 0;
#endif // _DEBUG
-#ifdef FEATURE_COMINTEROP
-WinMDAdapter::RedirectedTypeIndex CalculateWinRTRedirectedTypeIndex(IMDInternalImport * pInternalImport, Module * pModule, mdTypeDef cl)
-{
- STANDARD_VM_CONTRACT;
-
- Assembly * pAssembly = pModule->GetAssembly();
- WinMDAdapter::FrameworkAssemblyIndex assemblyIndex;
- if (!GetAppDomain()->FindRedirectedAssembly(pAssembly, &assemblyIndex))
- return WinMDAdapter::RedirectedTypeIndex_Invalid;
-
- return WinRTTypeNameConverter::GetRedirectedTypeIndexByName(pInternalImport, cl, assemblyIndex);
-}
-#endif // FEATURE_COMINTEROP
-
//==========================================================================
// This function is very specific about how it constructs a EEClass. It first
// determines the necessary size of the vtable and the number of statics that
@@ -262,8 +248,8 @@ MethodTableBuilder::CreateClass( Module *pModule,
}
}
- WinMDAdapter::RedirectedTypeIndex redirectedTypeIndex;
- redirectedTypeIndex = CalculateWinRTRedirectedTypeIndex(pInternalImport, pModule, cl);
+ WinMDAdapter::RedirectedTypeIndex redirectedTypeIndex;
+ redirectedTypeIndex = WinRTTypeNameConverter::GetRedirectedTypeIndexByName(pModule, cl);
if (redirectedTypeIndex != WinMDAdapter::RedirectedTypeIndex_Invalid)
{
EnsureOptionalFieldsAreAllocated(pEEClass, pamTracker, pAllocator->GetLowFrequencyHeap());
@@ -11741,30 +11727,29 @@ VOID MethodTableBuilder::CheckForSpecialTypes()
}
}
}
- else if (GetAppDomain()->IsSystemDll(pModule->GetAssembly()))
+ else if ((IsInterface() || IsDelegate()) &&
+ IsTdPublic(GetHalfBakedClass()->GetAttrClass()) &&
+ GetHalfBakedClass()->GetWinRTRedirectedTypeIndex() != WinMDAdapter::RedirectedTypeIndex_Invalid)
{
// 7. System.Collections.Specialized.INotifyCollectionChanged
// 8. System.Collections.Specialized.NotifyCollectionChangedEventHandler
// 9. System.ComponentModel.INotifyPropertyChanged
// 10. System.ComponentModel.PropertyChangedEventHandler
// 11. System.Windows.Input.ICommand
- if ((IsInterface() || IsDelegate()) && IsTdPublic(GetHalfBakedClass()->GetAttrClass()))
+ LPCUTF8 pszClassName;
+ LPCUTF8 pszClassNamespace;
+ if (SUCCEEDED(pMDImport->GetNameOfTypeDef(GetCl(), &pszClassName, &pszClassNamespace)))
{
- LPCUTF8 pszClassName;
- LPCUTF8 pszClassNamespace;
- if (SUCCEEDED(pMDImport->GetNameOfTypeDef(GetCl(), &pszClassName, &pszClassNamespace)))
- {
- LPUTF8 pszFullyQualifiedName = NULL;
- MAKE_FULLY_QUALIFIED_NAME(pszFullyQualifiedName, pszClassNamespace, pszClassName);
+ LPUTF8 pszFullyQualifiedName = NULL;
+ MAKE_FULLY_QUALIFIED_NAME(pszFullyQualifiedName, pszClassNamespace, pszClassName);
- if (strcmp(pszFullyQualifiedName, g_INotifyCollectionChangedName) == 0 ||
- strcmp(pszFullyQualifiedName, g_NotifyCollectionChangedEventHandlerName) == 0 ||
- strcmp(pszFullyQualifiedName, g_INotifyPropertyChangedName) == 0 ||
- strcmp(pszFullyQualifiedName, g_PropertyChangedEventHandlerName) == 0 ||
- strcmp(pszFullyQualifiedName, g_ICommandName) == 0)
- {
- bmtProp->fNeedsRCWPerTypeData = true;
- }
+ if (strcmp(pszFullyQualifiedName, g_INotifyCollectionChangedName) == 0 ||
+ strcmp(pszFullyQualifiedName, g_NotifyCollectionChangedEventHandlerName) == 0 ||
+ strcmp(pszFullyQualifiedName, g_INotifyPropertyChangedName) == 0 ||
+ strcmp(pszFullyQualifiedName, g_PropertyChangedEventHandlerName) == 0 ||
+ strcmp(pszFullyQualifiedName, g_ICommandName) == 0)
+ {
+ bmtProp->fNeedsRCWPerTypeData = true;
}
}
}
diff --git a/src/vm/winrtredirector.h b/src/vm/winrtredirector.h
index 2ab807c88e..595eeb7e86 100644
--- a/src/vm/winrtredirector.h
+++ b/src/vm/winrtredirector.h
@@ -36,12 +36,9 @@ public:
// Returns MethodTable (typical instantiation) of the Framework copy of the specified redirected WinRT interface.
static MethodTable *GetWinRTTypeForRedirectedInterfaceIndex(WinMDAdapter::RedirectedTypeIndex index);
-
- // Loads a type from the given Framework assembly.
- static MethodTable *LoadTypeFromRedirectedAssembly(WinMDAdapter::FrameworkAssemblyIndex index, LPCWSTR wzTypeName);
-
+
// Loads a method from the given Framework assembly.
- static MethodDesc *LoadMethodFromRedirectedAssembly(WinMDAdapter::FrameworkAssemblyIndex index, LPCWSTR wzTypeName, LPCUTF8 szMethodName);
+ static MethodDesc *LoadMethodFromRedirectedAssembly(LPCUTF8 szAssemblyQualifiedTypeName, LPCUTF8 szMethodName);
// Lists WinRT-legal types assignable from .NET reference types that are projected from WinRT structures/arrays/delegates.
enum WinRTLegalStructureBaseType
@@ -120,10 +117,9 @@ private:
struct NonMscorlibRedirectedInterfaceInfo
{
- const WinMDAdapter::FrameworkAssemblyIndex m_AssemblyIndex;
- const LPCWSTR m_wzWinRTInterfaceTypeName;
- const LPCWSTR m_wzCLRStubClassTypeName;
- const LPCWSTR m_wzWinRTStubClassTypeName;
+ const LPCUTF8 m_szWinRTInterfaceAssemblyQualifiedTypeName;
+ const LPCUTF8 m_szCLRStubClassAssemblyQualifiedTypeName;
+ const LPCUTF8 m_szWinRTStubClassAssemblyQualifiedTypeName;
const LPCUTF8 *m_rszMethodNames;
};
diff --git a/src/vm/winrttypenameconverter.cpp b/src/vm/winrttypenameconverter.cpp
index f3108a83ac..dfb38cc657 100644
--- a/src/vm/winrttypenameconverter.cpp
+++ b/src/vm/winrttypenameconverter.cpp
@@ -17,7 +17,6 @@
#include "winrttypenameconverter.h"
#include "typeresolution.h"
-
struct RedirectedTypeNames
{
LPCSTR szClrNamespace;
@@ -36,6 +35,48 @@ static const RedirectedTypeNames g_redirectedTypeNames[WinMDAdapter::RedirectedT
#undef DEFINE_PROJECTED_TYPE
+struct RedirectedTypeNamesKey
+{
+ RedirectedTypeNamesKey(LPCSTR szNamespace, LPCSTR szName) :
+ m_szNamespace(szNamespace),
+ m_szName(szName)
+ {
+ LIMITED_METHOD_CONTRACT;
+ }
+
+ LPCSTR m_szNamespace;
+ LPCSTR m_szName;
+};
+
+class RedirectedTypeNamesTraits : public NoRemoveSHashTraits< DefaultSHashTraits<const RedirectedTypeNames *> >
+{
+public:
+ typedef RedirectedTypeNamesKey key_t;
+
+ static key_t GetKey(element_t e)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return RedirectedTypeNamesKey(e->szClrNamespace, e->szClrName);
+ }
+ static BOOL Equals(key_t k1, key_t k2)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return (strcmp(k1.m_szName, k2.m_szName) == 0) && (strcmp(k1.m_szNamespace, k2.m_szNamespace) == 0);
+ }
+ static count_t Hash(key_t k)
+ {
+ LIMITED_METHOD_CONTRACT;
+ // Only use the Name when calculating the hash value. Many redirected types share the same namespace so
+ // there isn't a lot of value in using the namespace when calculating the hash value.
+ return HashStringA(k.m_szName);
+ }
+
+ static const element_t Null() { LIMITED_METHOD_CONTRACT; return NULL; }
+ static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e == NULL; }
+};
+
+typedef SHash< RedirectedTypeNamesTraits > RedirectedTypeNamesHashTable;
+static RedirectedTypeNamesHashTable * s_pRedirectedTypeNamesHashTable = NULL;
//
// Return the redirection index and type kind if the MethodTable* is a redirected type
@@ -580,33 +621,104 @@ bool WinRTTypeNameConverter::IsRedirectedType(MethodTable *pMT, WinMDAdapter::Wi
// static
WinMDAdapter::RedirectedTypeIndex WinRTTypeNameConverter::GetRedirectedTypeIndexByName(
- IMDInternalImport *pMDImport,
- mdTypeDef token,
- WinMDAdapter::FrameworkAssemblyIndex assemblyIndex)
+ Module *pModule,
+ mdTypeDef token)
{
CONTRACTL
{
STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pMDImport));
+ PRECONDITION(CheckPointer(pModule));
}
CONTRACTL_END;
+ // If the redirected type hashtable has not been initialized initialize it
+ if (s_pRedirectedTypeNamesHashTable == NULL)
+ {
+ NewHolder<RedirectedTypeNamesHashTable> pRedirectedTypeNamesHashTable = new RedirectedTypeNamesHashTable();
+ pRedirectedTypeNamesHashTable->Reallocate(2 * COUNTOF(g_redirectedTypeNames));
+
+ for (int i = 0; i < COUNTOF(g_redirectedTypeNames); ++i)
+ {
+ pRedirectedTypeNamesHashTable->Add(&(g_redirectedTypeNames[i]));
+ }
+
+ if (InterlockedCompareExchangeT(&s_pRedirectedTypeNamesHashTable, pRedirectedTypeNamesHashTable.GetValue(), NULL) == NULL)
+ {
+ pRedirectedTypeNamesHashTable.SuppressRelease();
+ }
+ }
+
+ IMDInternalImport *pInternalImport = pModule->GetMDImport();
LPCSTR szName;
LPCSTR szNamespace;
- IfFailThrow(pMDImport->GetNameOfTypeDef(token, &szName, &szNamespace));
+ IfFailThrow(pInternalImport->GetNameOfTypeDef(token, &szName, &szNamespace));
- // Check each of the redirected types to see if it is our type
- for (int i = 0; i < COUNTOF(g_redirectedTypeNames); ++i)
+ const RedirectedTypeNames *const * ppRedirectedNames = s_pRedirectedTypeNamesHashTable->LookupPtr(RedirectedTypeNamesKey(szNamespace, szName));
+ if (ppRedirectedNames == NULL)
{
- // Do the fast checks first
- if (g_redirectedTypeNames[i].assembly == assemblyIndex)
+ return WinMDAdapter::RedirectedTypeIndex_Invalid;
+ }
+
+ UINT redirectedTypeIndex = (UINT)(*ppRedirectedNames - g_redirectedTypeNames);
+ _ASSERTE(redirectedTypeIndex < COUNTOF(g_redirectedTypeNames));
+
+ // If the redirected assembly is mscorlib just compare it directly. This is necessary because
+ // WinMDAdapter::GetExtraAssemblyRefProps does not support mscorlib
+ if (g_redirectedTypeNames[redirectedTypeIndex].assembly == WinMDAdapter::FrameworkAssembly_Mscorlib)
+ {
+ return MscorlibBinder::GetModule()->GetAssembly() == pModule->GetAssembly() ?
+ (WinMDAdapter::RedirectedTypeIndex)redirectedTypeIndex :
+ WinMDAdapter::RedirectedTypeIndex_Invalid;
+ }
+
+ LPCSTR pSimpleName;
+ AssemblyMetaDataInternal context;
+ const BYTE * pbKeyToken;
+ DWORD cbKeyTokenLength;
+ DWORD dwFlags;
+ WinMDAdapter::GetExtraAssemblyRefProps(
+ g_redirectedTypeNames[redirectedTypeIndex].assembly,
+ &pSimpleName,
+ &context,
+ &pbKeyToken,
+ &cbKeyTokenLength,
+ &dwFlags);
+
+ AssemblySpec spec;
+ IfFailThrow(spec.Init(
+ pSimpleName,
+ &context,
+ pbKeyToken,
+ cbKeyTokenLength,
+ dwFlags));
+ Assembly* pRedirectedAssembly = spec.LoadAssembly(
+ FILE_LOADED,
+ NULL, // pLoadSecurity
+ FALSE); // fThrowOnFileNotFound
+
+ if (pRedirectedAssembly == NULL)
+ {
+ return WinMDAdapter::RedirectedTypeIndex_Invalid;
+ }
+
+ // Resolve the name in the redirected assembly to the actual type def and assembly
+ NameHandle nameHandle(szNamespace, szName);
+ nameHandle.SetTokenNotToLoad(tdAllTypes);
+ Module * pTypeDefModule;
+ mdTypeDef typeDefToken;
+
+ if (ClassLoader::ResolveNameToTypeDefThrowing(
+ pRedirectedAssembly->GetManifestModule(),
+ &nameHandle,
+ &pTypeDefModule,
+ &typeDefToken,
+ Loader::DontLoad))
+ {
+ // Finally check if the assembly from this type def token mathes the assembly type forwareded from the
+ // redirected assembly
+ if (pTypeDefModule->GetAssembly() == pModule->GetAssembly())
{
- // This is in the right assembly, see if the name matches
- if (strcmp(g_redirectedTypeNames[i].szClrName, szName) == 0 &&
- strcmp(g_redirectedTypeNames[i].szClrNamespace, szNamespace) == 0)
- {
- return (WinMDAdapter::RedirectedTypeIndex)i;
- }
+ return (WinMDAdapter::RedirectedTypeIndex)redirectedTypeIndex;
}
}
diff --git a/src/vm/winrttypenameconverter.h b/src/vm/winrttypenameconverter.h
index 53cb5ebfe0..4648ccb15e 100644
--- a/src/vm/winrttypenameconverter.h
+++ b/src/vm/winrttypenameconverter.h
@@ -75,9 +75,8 @@ public :
// calculate the redirected type index at EEClass creation time.
//
static WinMDAdapter::RedirectedTypeIndex GetRedirectedTypeIndexByName(
- IMDInternalImport *pMDImport,
- mdTypeDef token,
- WinMDAdapter::FrameworkAssemblyIndex assemblyIndex);
+ Module *pModule,
+ mdTypeDef token);
public :
//==============================================================================================
// WinRT -> Managed