@@ -720,14 +720,8 @@ FCIMPLEND
720720
721721
722722// Check we're allowed to create an array with the given element type.
723- void ArrayNative:: CheckElementType (TypeHandle elementType)
723+ static void CheckElementType (TypeHandle elementType)
724724{
725- // Checks apply recursively for arrays of arrays etc.
726- while (elementType.IsArray ())
727- {
728- elementType = elementType.GetArrayElementTypeHandle ();
729- }
730-
731725 // Check for simple types first.
732726 if (!elementType.IsTypeDesc ())
733727 {
@@ -738,7 +732,7 @@ void ArrayNative::CheckElementType(TypeHandle elementType)
738732 COMPlusThrow (kNotSupportedException , W (" NotSupported_ByRefLikeArray" ));
739733
740734 // Check for open generic types.
741- if (pMT->IsGenericTypeDefinition () || pMT-> ContainsGenericVariables ())
735+ if (pMT->ContainsGenericVariables ())
742736 COMPlusThrow (kNotSupportedException , W (" NotSupported_OpenType" ));
743737
744738 // Check for Void.
@@ -753,62 +747,67 @@ void ArrayNative::CheckElementType(TypeHandle elementType)
753747 }
754748}
755749
756- FCIMPL4 (Object*, ArrayNative::CreateInstance, ReflectClassBaseObject* pElementTypeUNSAFE , INT32 rank, INT32* pLengths, INT32* pLowerBounds)
750+ void QCALLTYPE Array_CreateInstance (QCall::TypeHandle pTypeHnd , INT32 rank, INT32* pLengths, INT32* pLowerBounds, BOOL createFromArrayType, QCall::ObjectHandleOnStack retArray )
757751{
758752 CONTRACTL {
759- FCALL_CHECK ;
753+ QCALL_CHECK ;
760754 PRECONDITION (rank > 0 );
761755 PRECONDITION (CheckPointer (pLengths));
762756 PRECONDITION (CheckPointer (pLowerBounds, NULL_OK));
763757 } CONTRACTL_END;
764758
765- OBJECTREF pRet = NULL ;
766-
767- REFLECTCLASSBASEREF pElementType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF (pElementTypeUNSAFE);
768-
769- // pLengths and pLowerBounds are pinned buffers. No need to protect them.
770- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT (pElementType);
771-
772- TypeHandle elementType (pElementType->GetType ());
759+ BEGIN_QCALL;
773760
774- CheckElementType (elementType );
761+ TypeHandle typeHnd = pTypeHnd. AsTypeHandle ( );
775762
776- CorElementType CorType = elementType.GetSignatureCorElementType ();
763+ if (createFromArrayType)
764+ {
765+ _ASSERTE ((INT32)typeHnd.GetRank () == rank);
766+ _ASSERTE (typeHnd.IsArray ());
777767
778- CorElementType kind = ELEMENT_TYPE_ARRAY;
768+ if (typeHnd.GetArrayElementTypeHandle ().ContainsGenericVariables ())
769+ COMPlusThrow (kNotSupportedException , W (" NotSupported_OpenType" ));
779770
780- // Is it ELEMENT_TYPE_SZARRAY array?
781- if (rank == 1 && (pLowerBounds == NULL || pLowerBounds[0 ] == 0 )
782- #ifdef FEATURE_64BIT_ALIGNMENT
783- // On platforms where 64-bit types require 64-bit alignment and don't obtain it naturally force us
784- // through the slow path where this will be handled.
785- && (CorType != ELEMENT_TYPE_I8)
786- && (CorType != ELEMENT_TYPE_U8)
787- && (CorType != ELEMENT_TYPE_R8)
788- #endif
789- )
790- {
791- // Shortcut for common cases
792- if (CorTypeInfo::IsPrimitiveType (CorType))
771+ if (!typeHnd.AsMethodTable ()->IsMultiDimArray ())
793772 {
794- pRet = AllocatePrimitiveArray (CorType,pLengths[0 ]);
773+ _ASSERTE (pLowerBounds == NULL || pLowerBounds[0 ] == 0 );
774+
775+ GCX_COOP ();
776+ retArray.Set (AllocateSzArray (typeHnd, pLengths[0 ]));
795777 goto Done;
796778 }
797- else
798- if (CorTypeInfo::IsObjRef (CorType))
779+ }
780+ else
781+ {
782+ CheckElementType (typeHnd);
783+
784+ // Is it ELEMENT_TYPE_SZARRAY array?
785+ if (rank == 1 && (pLowerBounds == NULL || pLowerBounds[0 ] == 0 ))
799786 {
800- pRet = AllocateObjectArray (pLengths[0 ],elementType);
801- goto Done;
787+ CorElementType corType = typeHnd.GetSignatureCorElementType ();
788+
789+ // Shortcut for common cases
790+ if (CorTypeInfo::IsPrimitiveType (corType))
791+ {
792+ GCX_COOP ();
793+ retArray.Set (AllocatePrimitiveArray (corType, pLengths[0 ]));
794+ goto Done;
795+ }
796+
797+ typeHnd = ClassLoader::LoadArrayTypeThrowing (typeHnd);
798+
799+ {
800+ GCX_COOP ();
801+ retArray.Set (AllocateSzArray (typeHnd, pLengths[0 ]));
802+ goto Done;
803+ }
802804 }
803805
804- kind = ELEMENT_TYPE_SZARRAY;
805- pLowerBounds = NULL ;
806+ // Find the Array class...
807+ typeHnd = ClassLoader::LoadArrayTypeThrowing (typeHnd, ELEMENT_TYPE_ARRAY, rank) ;
806808 }
807809
808810 {
809- // Find the Array class...
810- TypeHandle typeHnd = ClassLoader::LoadArrayTypeThrowing (elementType, kind, rank);
811-
812811 _ASSERTE (rank <= MAX_RANK); // Ensures that the stack buffer size allocations below won't overflow
813812
814813 DWORD boundsSize = 0 ;
@@ -834,15 +833,15 @@ FCIMPL4(Object*, ArrayNative::CreateInstance, ReflectClassBaseObject* pElementTy
834833 bounds[i] = pLengths[i];
835834 }
836835
837- pRet = AllocateArrayEx (typeHnd, bounds, boundsSize);
836+ {
837+ GCX_COOP ();
838+ retArray.Set (AllocateArrayEx (typeHnd, bounds, boundsSize));
839+ }
838840 }
839841
840842Done: ;
841- HELPER_METHOD_FRAME_END ();
842-
843- return OBJECTREFToObject (pRet);
843+ END_QCALL;
844844}
845- FCIMPLEND
846845
847846FCIMPL3 (void , ArrayNative::SetValue, ArrayBase* refThisUNSAFE, Object* objUNSAFE, INT_PTR flattenedIndex)
848847{
0 commit comments