diff options
author | Jeremy Koritzinsky <jkoritzinsky@gmail.com> | 2019-03-05 20:54:49 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-05 20:54:49 -0800 |
commit | 400b472f3333fd2a5371fcab7c34c2892b6324c6 (patch) | |
tree | 24d947afe421113e43c29bfae48a414e887794e4 /src/vm/methodtablebuilder.cpp | |
parent | 3662d02bb222728ebed70d6d73f89a63c9910ffb (diff) | |
download | coreclr-400b472f3333fd2a5371fcab7c34c2892b6324c6.tar.gz coreclr-400b472f3333fd2a5371fcab7c34c2892b6324c6.tar.bz2 coreclr-400b472f3333fd2a5371fcab7c34c2892b6324c6.zip |
Move HasLayoutMetadata to methodtablebuilder.cpp (#23015)
* Move HasLayoutMetadata to methodtablebuilder.cpp
* Collapse auto case into unicode case.
* Remove ancient workaround for Managed C++ compiler bug.
Diffstat (limited to 'src/vm/methodtablebuilder.cpp')
-rw-r--r-- | src/vm/methodtablebuilder.cpp | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp index 72aa6f5cf6..d0045411db 100644 --- a/src/vm/methodtablebuilder.cpp +++ b/src/vm/methodtablebuilder.cpp @@ -11839,6 +11839,94 @@ MethodTableBuilder::GatherGenericsInfo( bmtGenericsInfo->typeContext = typeContext; } // MethodTableBuilder::GatherGenericsInfo +//======================================================================= +// This is invoked from the class loader while building the internal structures for a type +// This function should check if explicit layout metadata exists. +// +// Returns: +// TRUE - yes, there's layout metadata +// FALSE - no, there's no layout. +// fail - throws a typeload exception +// +// If TRUE, +// *pNLType gets set to nltAnsi or nltUnicode +// *pPackingSize declared packing size +// *pfExplicitoffsets offsets explicit in metadata or computed? +//======================================================================= +BOOL HasLayoutMetadata(Assembly* pAssembly, IMDInternalImport* pInternalImport, mdTypeDef cl, MethodTable* pParentMT, BYTE* pPackingSize, BYTE* pNLTType, BOOL* pfExplicitOffsets) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_ANY; + PRECONDITION(CheckPointer(pInternalImport)); + PRECONDITION(CheckPointer(pPackingSize)); + PRECONDITION(CheckPointer(pNLTType)); + PRECONDITION(CheckPointer(pfExplicitOffsets)); + } + CONTRACTL_END; + + HRESULT hr; + ULONG clFlags; + + if (FAILED(pInternalImport->GetTypeDefProps(cl, &clFlags, NULL))) + { + pAssembly->ThrowTypeLoadException(pInternalImport, cl, IDS_CLASSLOAD_BADFORMAT); + } + + if (IsTdAutoLayout(clFlags)) + { + return FALSE; + } + else if (IsTdSequentialLayout(clFlags)) + { + *pfExplicitOffsets = FALSE; + } + else if (IsTdExplicitLayout(clFlags)) + { + *pfExplicitOffsets = TRUE; + } + else + { + pAssembly->ThrowTypeLoadException(pInternalImport, cl, IDS_CLASSLOAD_BADFORMAT); + } + + // We now know this class has seq. or explicit layout. Ensure the parent does too. + if (pParentMT && !(pParentMT->IsObjectClass() || pParentMT->IsValueTypeClass()) && !(pParentMT->HasLayout())) + pAssembly->ThrowTypeLoadException(pInternalImport, cl, IDS_CLASSLOAD_BADFORMAT); + + if (IsTdAnsiClass(clFlags)) + { + *pNLTType = nltAnsi; + } + else if (IsTdUnicodeClass(clFlags) || IsTdAutoClass(clFlags)) + { + *pNLTType = nltUnicode; + } + else + { + pAssembly->ThrowTypeLoadException(pInternalImport, cl, IDS_CLASSLOAD_BADFORMAT); + } + + DWORD dwPackSize; + hr = pInternalImport->GetClassPackSize(cl, &dwPackSize); + if (FAILED(hr) || dwPackSize == 0) + dwPackSize = DEFAULT_PACKING_SIZE; + + // This has to be reduced to a BYTE value, so we had better make sure it fits. If + // not, we'll throw an exception instead of trying to munge the value to what we + // think the user might want. + if (!FitsInU1((UINT64)(dwPackSize))) + { + pAssembly->ThrowTypeLoadException(pInternalImport, cl, IDS_CLASSLOAD_BADFORMAT); + } + + *pPackingSize = (BYTE)dwPackSize; + + return TRUE; +} + //--------------------------------------------------------------------------------------- // // This service is called for normal classes -- and for the pseudo class we invent to |