From ef1e2ab328087c61a6878c1e84f4fc5d710aebce Mon Sep 17 00:00:00 2001 From: dotnet-bot Date: Fri, 30 Jan 2015 14:14:42 -0800 Subject: Initial commit to populate CoreCLR repo [tfs-changeset: 1407945] --- src/vm/tlbexport.h | 486 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 486 insertions(+) create mode 100644 src/vm/tlbexport.h (limited to 'src/vm/tlbexport.h') diff --git a/src/vm/tlbexport.h b/src/vm/tlbexport.h new file mode 100644 index 0000000000..7cfc19e377 --- /dev/null +++ b/src/vm/tlbexport.h @@ -0,0 +1,486 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// +//=========================================================================== +// File: TlbExport.h +// + +// +// Notes: Create a TypeLib from COM+ metadata. +//--------------------------------------------------------------------------- + + +#ifndef FEATURE_COMINTEROP +#error FEATURE_COMINTEROP is required for this file +#endif // FEATURE_COMINTEROP + +class ITypeCreateTypeLib2; +struct ICreateTypeInfo2; +struct ITypeInfo; +struct ITypeLibExporterNotifySink; + +class CDescPool; +struct ComMTMethodProps; +class ComMTMemberInfoMap; + +static LPCSTR szVariantClassFullQual = g_VariantClassName; + +//************************************************************************* +// Helper functions. +//************************************************************************* +HRESULT Utf2Quick( + LPCUTF8 pStr, // The string to convert. + CQuickArray &rStr, // The QuickArray to convert it into. + int iCurLen = 0); // Inital characters in the array to leave (default 0). + +//***************************************************************************** +// Signature utilities. +//***************************************************************************** +class MetaSigExport : public MetaSig +{ +public: + MetaSigExport(MethodDesc *pMD) : + MetaSig(pMD) + { + WRAPPER_NO_CONTRACT; + } + + BOOL IsVbRefType() + { + CONTRACT (BOOL) + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + } + CONTRACT_END; + + // Get the arg, and skip decorations. + SigPointer pt = GetArgProps(); + CorElementType mt; + if (FAILED(pt.PeekElemType(&mt))) + return FALSE; + + while (mt == ELEMENT_TYPE_BYREF || mt == ELEMENT_TYPE_PTR) + { + // Eat the one just examined, and peek at the next one. + if (FAILED(pt.GetElemType(NULL)) || FAILED(pt.PeekElemType(&mt))) + return FALSE; + } + + // Is it just Object? + if (mt == ELEMENT_TYPE_OBJECT) + RETURN TRUE; + + // A particular class? + if (mt == ELEMENT_TYPE_CLASS) + { + // Exclude "string". + if (pt.IsStringType(m_pModule, GetSigTypeContext())) + RETURN FALSE; + RETURN TRUE; + } + + // A particular valuetype? + if (mt == ELEMENT_TYPE_VALUETYPE) + { + // Include "variant". + if (pt.IsClass(m_pModule, szVariantClassFullQual, GetSigTypeContext())) + RETURN TRUE; + RETURN FALSE; + } + + // An array, a string, or POD. + RETURN FALSE; + } +}; // class MetaSigExport : public MetaSig + + +//************************************************************************* +// Class to convert COM+ metadata to a TypeLib. +//************************************************************************* +class TypeLibExporter +{ +private: + class CExportedTypesInfo + { + public: + MethodTable* pClass; // The class being exported. + ICreateTypeInfo2* pCTI; // The ICreateTypeInfo2 for the EE class. + ICreateTypeInfo2* pCTIClassItf; // The ICreateTypeInfo2 for the IClassX. + TYPEKIND tkind; // Typekind of the exported class. + bool bAutoProxy; // If true, oleaut32 is the interface's proxy. + }; + + class CExportedTypesHash : public CClosedHashEx + { + protected: + friend class CSortByToken; + friend class CSortByName; + + class CSortByToken : public CQuickSort + { + public: + CSortByToken(CExportedTypesInfo **pBase, int iCount) : + CQuickSort(pBase, iCount) + { + WRAPPER_NO_CONTRACT; + } + virtual int Compare(CExportedTypesInfo **ps1, CExportedTypesInfo **ps2); + }; + + class CSortByName : public CQuickSort + { + public: + CSortByName(CExportedTypesInfo **pBase, int iCount) : + CQuickSort(pBase, iCount) + { + WRAPPER_NO_CONTRACT; + } + virtual int Compare(CExportedTypesInfo **ps1, CExportedTypesInfo **ps2); + }; + + public: + typedef CClosedHashEx Base; + typedef CExportedTypesInfo T; + + CExportedTypesHash() : + Base(1009), + m_iCount(0), + m_Array(NULL) + { + WRAPPER_NO_CONTRACT; + } + + ~CExportedTypesHash() + { + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + SO_TOLERANT; + MODE_ANY; + } + CONTRACTL_END; + Clear(); + delete[] m_Array; + } + + virtual void Clear(); + + unsigned int Hash(const T *pData); + unsigned int Compare(const T *p1, T *p2); + ELEMENTSTATUS Status(T *p); + void SetStatus(T *p, ELEMENTSTATUS s); + void* GetKey(T *p); + + //@todo: move to CClosedHashEx + T* GetFirst() + { + WRAPPER_NO_CONTRACT; + return (T*)CClosedHashBase::GetFirst(); + } + T* GetNext(T*prev) + { + WRAPPER_NO_CONTRACT; + return (T*)CClosedHashBase::GetNext((BYTE*)prev); + } + + void InitArray(); + void UpdateArray(); + + T* operator[](ULONG ix) + { + CONTRACT (T*) + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + PRECONDITION(ix < m_iCount); + POSTCONDITION(CheckPointer(RETVAL)); + } + CONTRACT_END; + + RETURN m_Array[ix]; + } + int Count() + { + LIMITED_METHOD_CONTRACT; + return m_iCount; + } + + void SortByName(); + void SortByToken(); + + protected: + CExportedTypesInfo** m_Array; + ULONG m_iCount; + }; + +protected: + struct CErrorContext; + + class CHrefOfTIHashKey + { + public: + ITypeInfo* pITI; + HREFTYPE href; + }; + + class CHrefOfTIHash : public CClosedHash + { + public: + typedef CHrefOfTIHashKey T; + + CHrefOfTIHash() : + CClosedHash(101) + { + WRAPPER_NO_CONTRACT; + } + ~CHrefOfTIHash() + { + CONTRACTL { NOTHROW; SO_TOLERANT; } CONTRACTL_END; + Clear(); + } + + virtual void Clear(); + + unsigned int Hash(const T *pData); + unsigned int Hash(const void *pData) + { + WRAPPER_NO_CONTRACT; + return Hash((const T*)pData); + } + + unsigned int Compare(const T *p1, T *p2); + unsigned int Compare(const void *p1, BYTE *p2) + { + WRAPPER_NO_CONTRACT; + return Compare((const T*)p1, (T*)p2); + } + + ELEMENTSTATUS Status(T *p); + ELEMENTSTATUS Status(BYTE *p) + { + WRAPPER_NO_CONTRACT; + return Status((T*)p); + } + + void SetStatus(T *p, ELEMENTSTATUS s); + void SetStatus(BYTE *p, ELEMENTSTATUS s) + { + WRAPPER_NO_CONTRACT; + SetStatus((T*)p, s); + } + + void *GetKey(T *p); + void* GetKey(BYTE *p) + { + WRAPPER_NO_CONTRACT; + return GetKey((T*)p); + } + }; + + class CHrefOfClassHashKey + { + public: + MethodTable* pClass; + HREFTYPE href; + }; + + class CHrefOfClassHash : public CClosedHash + { + public: + typedef CHrefOfClassHashKey T; + + CHrefOfClassHash() : + CClosedHash(101) + { + WRAPPER_NO_CONTRACT; + } + ~CHrefOfClassHash() + { + WRAPPER_NO_CONTRACT; + Clear(); + } + + virtual void Clear(); + + unsigned int Hash(const T *pData); + unsigned int Hash(const void *pData) + { + WRAPPER_NO_CONTRACT; + return Hash((const T*)pData); + } + + + unsigned int Compare(const T *p1, T *p2); + unsigned int Compare(const void *p1, BYTE *p2) + { + WRAPPER_NO_CONTRACT; + return Compare((const T*)p1, (T*)p2); + } + + + ELEMENTSTATUS Status(T *p); + ELEMENTSTATUS Status(BYTE *p) + { + WRAPPER_NO_CONTRACT; + return Status((T*)p); + } + + + void SetStatus(T *p, ELEMENTSTATUS s); + void SetStatus(BYTE *p, ELEMENTSTATUS s) + { + WRAPPER_NO_CONTRACT; + SetStatus((T*)p, s); + } + + + void *GetKey(T *p); + void* GetKey(BYTE *p) + { + WRAPPER_NO_CONTRACT; + return GetKey((T*)p); + } + }; + + struct CErrorContext + { + CErrorContext() : + m_prev(0), + m_szAssembly(0), + m_tkType(mdTypeDefNil), + m_pScope(0), + m_szMember(0), + m_szParam(0), + m_ixParam(-1) + { + LIMITED_METHOD_CONTRACT; + } + + // The following variables hold context info for error reporting. + CErrorContext* m_prev; // A previous context. + LPCUTF8 m_szAssembly; // Current assembly name. + mdToken m_tkType; // Current type's metadata token. + IMDInternalImport *m_pScope; // Current type's scope. + LPCUTF8 m_szMember; // Current member's name. + LPCUTF8 m_szParam; // Current param's name. + int m_ixParam; // Current param index. + }; + +public: + TypeLibExporter(); + ~TypeLibExporter(); + + void Convert(Assembly *pAssembly, LPCWSTR szTlbName, ITypeLibExporterNotifySink *pNotify=0, int flags=0); + void LayOut(); + HRESULT GetTypeLib(REFGUID iid, IUnknown **ppTlb); + void ReleaseResources(); + +protected: + void PreLoadNames(); + + void UpdateBitness(Assembly* pAssembly); + HRESULT CheckBitness(Assembly* pAssembly); + + // TypeLib emit functions. + HRESULT TokenToHref(ICreateTypeInfo2 *pTI, MethodTable *pClass, mdToken tk, BOOL bWarnOnUsingIUnknown, HREFTYPE *pHref); + void GetWellKnownInterface(MethodTable *pClass, ITypeInfo **ppTI); + HRESULT EEClassToHref(ICreateTypeInfo2 *pTI, MethodTable *pClass, BOOL bWarnOnUsingIUnknown, HREFTYPE *pHref); + void StdOleTypeToHRef(ICreateTypeInfo2 *pCTI, REFGUID rGuid, HREFTYPE *pHref); + void ExportReferencedAssembly(Assembly *pAssembly); + + // Metadata import functions. + void AddModuleTypes(Module *pModule); + void AddAssemblyTypes(Assembly *pAssembly); + + void ConvertAllTypeDefs(); + HRESULT ConvertOneTypeDef(MethodTable *pClass); + + HRESULT GetTypeLibImportClassName(MethodTable *pClass, SString& pszName); + + void CreateITypeInfo(CExportedTypesInfo *pData, bool bNamespace=false, bool bResolveDup=true); + void CreateIClassXITypeInfo(CExportedTypesInfo *pData, bool bNamespace=false, bool bResolveDup=true); + void ConvertImplTypes(CExportedTypesInfo *pData); + void ConvertDetails(CExportedTypesInfo *pData); + + void ConvertInterfaceImplTypes(ICreateTypeInfo2 *pICTI, MethodTable *pClass); + void ConvertInterfaceDetails(ICreateTypeInfo2 *pICTI, MethodTable *pClass, int bAutoProxy); + void ConvertRecord(CExportedTypesInfo *pData); + void ConvertRecordBaseClass(CExportedTypesInfo *pData, MethodTable *pSubClass, ULONG &ixVar); + void ConvertEnum(ICreateTypeInfo2 *pICTI, MethodTable *pClass); + void ConvertClassImplTypes(ICreateTypeInfo2 *pICTI, ICreateTypeInfo2 *pIDefault, MethodTable *pClass); + void ConvertClassDetails(ICreateTypeInfo2 *pICTI, ICreateTypeInfo2 *pIDefault, MethodTable *pClass, int bAutoProxy); + + BOOL HasDefaultCtor(MethodTable *pMT); + + void ConvertIClassX(ICreateTypeInfo2 *pICTI, MethodTable *pClass, int bAutoProxy); + BOOL ConvertMethod(ICreateTypeInfo2 *pTI, ComMTMethodProps *pProps, ULONG iMD, ULONG ulIface); + BOOL ConvertFieldAsMethod(ICreateTypeInfo2 *pTI, ComMTMethodProps *pProps, ULONG iMD); + BOOL ConvertVariable(ICreateTypeInfo2 *pTI, MethodTable *pClass, mdFieldDef md, SString& sName, ULONG iMD); + BOOL ConvertEnumMember(ICreateTypeInfo2 *pTI, MethodTable *pClass, mdFieldDef md, SString& sName, ULONG iMD); + + // Error/status functions. + void InternalThrowHRWithContext(HRESULT hr, ...); + void FormatErrorContextString(CErrorContext *pContext, SString *pOut); + void FormatErrorContextString(SString *pOut); + void ReportError(HRESULT hr); + void ReportEvent(int ev, int hr, ...); + void ReportWarning(HRESULT hrReturn, HRESULT hrRpt, ...); + void PostClassLoadError(LPCUTF8 pszName, SString& message); + + // Utility functions. + void ClassHasIClassX(MethodTable *pClass, CorClassIfaceAttr *pRslt); + MethodTable * LoadClass(Module *pModule, mdToken tk); + TypeHandle LoadClass(Module *pModule, LPCUTF8 pszName); + HRESULT CorSigToTypeDesc(ICreateTypeInfo2 *pTI, MethodTable *pClass, PCCOR_SIGNATURE pbSig, PCCOR_SIGNATURE pbNativeSig, ULONG cbNativeSig, + ULONG *cbElem, TYPEDESC *ptdesc, CDescPool *ppool, BOOL bMethodSig, BOOL *pbByRef=0); + BOOL IsVbRefType(PCCOR_SIGNATURE pbSig, IMDInternalImport *pInternalImport); + + BOOL IsExportingAs64Bit(); + + void ArrayToTypeDesc(ICreateTypeInfo2 *pCTI, CDescPool *ppool, ArrayMarshalInfo *pArrayMarshalInfo, TYPEDESC *pElementTypeDesc); + + VARTYPE GetVtForIntPtr(); + VARTYPE GetVtForUIntPtr(); + + //BOOL ValidateSafeArrayElemVT(VARTYPE vt); + + BOOL GetDescriptionString(MethodTable *pClass, mdToken tk, BSTR &bstrDescr); + BOOL GetStringCustomAttribute(IMDInternalImport *pImport, LPCSTR szName, mdToken tk, BSTR &bstrDescr); + + BOOL GetAutomationProxyAttribute(IMDInternalImport *pImport, mdToken tk, int *bValue); + + TYPEKIND TKindFromClass(MethodTable *pClass); + +protected: + void GetRefTypeInfo(ICreateTypeInfo2 *pContainer, ITypeInfo *pReferenced, HREFTYPE *pHref); + + CHrefOfTIHash m_HrefHash; // Hashed table of HREFTYPEs of ITypeInfos + CHrefOfClassHash m_HrefOfClassHash; // Hashed table of HREFTYPEs of ITypeInfos + CErrorContext m_ErrorContext; + +private: + ClassLoader* m_pLoader; // Domain where the Module being converted was loaded + ITypeInfo* m_pIUnknown; // TypeInfo for IUnknown. + HREFTYPE m_hIUnknown; // href for IUnknown. + ITypeInfo* m_pIDispatch; // TypeInfo for IDispatch. + ITypeInfo* m_pGuid; // TypeInfo for GUID. + + ITypeLibExporterNotifySink* m_pNotify; // Notification callback. + + ICreateTypeLib2* m_pICreateTLB; // The created typelib. + + int m_flags; // Conversion flags. + int m_bAutomationProxy; // Should interfaces be marked such that oleaut32 is the proxy? + int m_bWarnedOfNonPublic; + + CExportedTypesHash m_Exports; + CExportedTypesHash m_InjectedExports; +}; + + +// eof ------------------------------------------------------------------------ -- cgit v1.2.3