Move HasLayoutMetadata to methodtablebuilder.cpp (#23015)
authorJeremy Koritzinsky <jkoritzinsky@gmail.com>
Wed, 6 Mar 2019 04:54:49 +0000 (20:54 -0800)
committerGitHub <noreply@github.com>
Wed, 6 Mar 2019 04:54:49 +0000 (20:54 -0800)
* Move HasLayoutMetadata to methodtablebuilder.cpp

* Collapse auto case into unicode case.

* Remove ancient workaround for Managed C++ compiler bug.

src/vm/fieldmarshaler.cpp
src/vm/fieldmarshaler.h
src/vm/methodtablebuilder.cpp

index 5e231f7..6d4ff96 100644 (file)
@@ -56,133 +56,6 @@ static const NFTDataBaseEntry NFTDataBase[] =
     #include "nsenums.h"
 };
 
-
-//=======================================================================
-// 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;
-#ifdef _DEBUG
-    clFlags = 0xcccccccc;
-#endif
-    
-    if (FAILED(pInternalImport->GetTypeDefProps(cl, &clFlags, NULL)))
-    {
-        pAssembly->ThrowTypeLoadException(pInternalImport, cl, IDS_CLASSLOAD_BADFORMAT);
-    }
-    
-    if (IsTdAutoLayout(clFlags))
-    {
-        // <BUGNUM>workaround for B#104780 - VC fails to set SequentialLayout on some classes
-        // with ClassSize. Too late to fix compiler for V1.
-        //
-        // To compensate, we treat AutoLayout classes as Sequential if they
-        // meet all of the following criteria:
-        //
-        //    - ClassSize present and nonzero.
-        //    - No instance fields declared
-        //    - Base class is System.ValueType.
-        //</BUGNUM>
-        ULONG cbTotalSize = 0;
-        if (SUCCEEDED(pInternalImport->GetClassTotalSize(cl, &cbTotalSize)) && cbTotalSize != 0)
-        {
-            if (pParentMT && pParentMT->IsValueTypeClass())
-            {
-                MDEnumHolder hEnumField(pInternalImport);
-                if (SUCCEEDED(pInternalImport->EnumInit(mdtFieldDef, cl, &hEnumField)))
-                {
-                    ULONG numFields = pInternalImport->EnumGetCount(&hEnumField);
-                    if (numFields == 0)
-                    {
-                        *pfExplicitOffsets = FALSE;
-                        *pNLTType = nltAnsi;
-                        *pPackingSize = 1;
-                        return TRUE;
-                    }
-                }
-            }
-        }
-        
-        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))
-    {
-        *pNLTType = nltUnicode;
-    }
-    else if (IsTdAutoClass(clFlags))
-    {
-        // We no longer support Win9x so TdAuto always maps to Unicode.
-        *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;
-}
-
 #ifdef _PREFAST_
 #pragma warning(push)
 #pragma warning(disable:21000) // Suppress PREFast warning about overly large function
index e838358..e3eba6c 100644 (file)
@@ -119,25 +119,6 @@ VOID ParseNativeType(Module*    pModule,
 BOOL IsFieldBlittable(FieldMarshaler* pFM);
 
 //=======================================================================
-// This is invoked from the class loader while building the data structures for a type.
-// This function checks if explicit layout metadata exists.
-//
-// Returns:
-//  TRUE    - yes, there's layout metadata
-//  FALSE   - no, there's no layout.
-//  fail    - throws a typeload exception
-//
-// If S_OK,
-//   *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);
-
-
-//=======================================================================
 // This function returns TRUE if the type passed in is either a value class or a class and if it has layout information 
 // and is marshalable. In all other cases it will return FALSE. 
 //=======================================================================
index 72aa6f5..d004541 100644 (file)
@@ -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