@@ -128,7 +128,9 @@ private static void Copy(Array sourceArray, int sourceIndex, Array destinationAr
128128 if ( destinationIndex < 0 )
129129 throw new ArgumentOutOfRangeException ( nameof ( destinationIndex ) , "Value has to be >= 0." ) ;
130130
131- if ( FastCopy ( sourceArray , sourceIndex , destinationArray , destinationIndex , length ) )
131+ var src = sourceArray ;
132+ var dst = destinationArray ;
133+ if ( FastCopy ( ObjectHandleOnStack . Create ( ref src ) , sourceIndex , ObjectHandleOnStack . Create ( ref dst ) , destinationIndex , length ) )
132134 return ;
133135
134136 CopySlow ( sourceArray , sourceIndex , destinationArray , destinationIndex , length , reliable ) ;
@@ -168,7 +170,8 @@ private static void CopySlow(Array sourceArray, int sourceIndex, Array destinati
168170 if ( reliable )
169171 {
170172 if ( ! dst_type . Equals ( src_type ) &&
171- ! ( dst_type . IsPrimitive && src_type . IsPrimitive && CanChangePrimitive ( ref dst_type , ref src_type , true ) ) )
173+ ! ( dst_type . IsPrimitive && src_type . IsPrimitive &&
174+ CanChangePrimitive ( ObjectHandleOnStack . Create ( ref dst_type ) , ObjectHandleOnStack . Create ( ref src_type ) , true ) ) )
172175 {
173176 throw new ArrayTypeMismatchException ( SR . ArrayTypeMismatch_CantAssignType ) ;
174177 }
@@ -181,18 +184,25 @@ private static void CopySlow(Array sourceArray, int sourceIndex, Array destinati
181184 }
182185 }
183186
187+ Array src = sourceArray ;
188+ ObjectHandleOnStack src_handle = ObjectHandleOnStack . Create ( ref src ) ;
189+ Array dst = destinationArray ;
190+ ObjectHandleOnStack dst_handle = ObjectHandleOnStack . Create ( ref dst ) ;
191+ object ? srcval = null ;
192+ ObjectHandleOnStack val_handle = ObjectHandleOnStack . Create ( ref srcval ) ;
193+
184194 if ( ! ReferenceEquals ( sourceArray , destinationArray ) || source_pos > dest_pos )
185195 {
186196 for ( int i = 0 ; i < length ; i ++ )
187197 {
188- object srcval = sourceArray . GetValueImpl ( source_pos + i ) ;
198+ GetValueImpl ( src_handle , val_handle , source_pos + i ) ;
189199
190200 if ( dst_type_vt && ( srcval == null || ( src_type == typeof ( object ) && ! dst_elem_type . IsAssignableFrom ( srcval . GetType ( ) ) ) ) )
191201 throw new InvalidCastException ( SR . InvalidCast_DownCastArrayElement ) ;
192202
193203 try
194204 {
195- destinationArray . SetValueRelaxedImpl ( srcval , dest_pos + i ) ;
205+ SetValueRelaxedImpl ( dst_handle , val_handle , dest_pos + i ) ;
196206 }
197207 catch ( ArgumentException )
198208 {
@@ -204,11 +214,11 @@ private static void CopySlow(Array sourceArray, int sourceIndex, Array destinati
204214 {
205215 for ( int i = length - 1 ; i >= 0 ; i -- )
206216 {
207- object srcval = sourceArray . GetValueImpl ( source_pos + i ) ;
217+ GetValueImpl ( src_handle , val_handle , source_pos + i ) ;
208218
209219 try
210220 {
211- destinationArray . SetValueRelaxedImpl ( srcval , dest_pos + i ) ;
221+ SetValueRelaxedImpl ( dst_handle , val_handle , dest_pos + i ) ;
212222 }
213223 catch ( ArgumentException )
214224 {
@@ -254,9 +264,8 @@ private static bool CanAssignArrayElement(Type source, Type target)
254264 }
255265 else if ( source . IsPrimitive && target . IsPrimitive )
256266 {
257-
258267 // Allow primitive type widening
259- return CanChangePrimitive ( ref source , ref target , false ) ;
268+ return CanChangePrimitive ( ObjectHandleOnStack . Create ( ref source ) , ObjectHandleOnStack . Create ( ref target ) , false ) ;
260269 }
261270 else if ( ! source . IsValueType && ! source . IsPointer )
262271 {
@@ -319,15 +328,19 @@ private unsafe nint GetFlattenedIndex(ReadOnlySpan<int> indices)
319328 if ( GetType ( ) . GetElementType ( ) ! . IsPointer )
320329 throw new NotSupportedException ( SR . NotSupported_Type ) ;
321330
322- return GetValueImpl ( ( int ) index ) ;
331+ Array self = this ;
332+ object ? res = null ;
333+ GetValueImpl ( ObjectHandleOnStack . Create ( ref self ) , ObjectHandleOnStack . Create ( ref res ) , ( int ) index ) ;
334+ return res ;
323335 }
324336
325337 internal void InternalSetValue ( object ? value , nint index )
326338 {
327339 if ( GetType ( ) . GetElementType ( ) ! . IsPointer )
328340 throw new NotSupportedException ( SR . NotSupported_Type ) ;
329341
330- SetValueImpl ( value , ( int ) index ) ;
342+ Array self = this ;
343+ SetValueImpl ( ObjectHandleOnStack . Create ( ref self ) , ObjectHandleOnStack . Create ( ref value ) , ( int ) index ) ;
331344 }
332345
333346 public void Initialize ( )
@@ -351,68 +364,92 @@ public int GetUpperBound(int dimension)
351364 return GetLowerBound ( dimension ) + GetLength ( dimension ) - 1 ;
352365 }
353366
367+ internal CorElementType GetCorElementTypeOfElementType ( )
368+ {
369+ object arr = this ;
370+ return GetCorElementTypeOfElementTypeInternal ( ObjectHandleOnStack . Create ( ref arr ) ) ;
371+ }
372+
373+ private bool IsValueOfElementType ( object value )
374+ {
375+ object arr = this ;
376+ return IsValueOfElementTypeInternal ( ObjectHandleOnStack . Create ( ref arr ) , ObjectHandleOnStack . Create ( ref value ) ) ;
377+ }
378+
379+ [ Intrinsic ] // when dimension is `0` constant
380+ public int GetLength ( int dimension )
381+ {
382+ object arr = this ;
383+ return GetLengthInternal ( ObjectHandleOnStack . Create ( ref arr ) , dimension ) ;
384+ }
385+
386+ [ Intrinsic ] // when dimension is `0` constant
387+ public int GetLowerBound ( int dimension )
388+ {
389+ object arr = this ;
390+ return GetLowerBoundInternal ( ObjectHandleOnStack . Create ( ref arr ) , dimension ) ;
391+ }
392+
354393 [ Intrinsic ]
355394 internal int GetElementSize ( ) => GetElementSize ( ) ;
356395
357396 [ Intrinsic ]
358397 internal bool IsPrimitive ( ) => IsPrimitive ( ) ;
359398
360399 [ MethodImpl ( MethodImplOptions . InternalCall ) ]
361- internal extern CorElementType GetCorElementTypeOfElementType ( ) ;
400+ private static extern CorElementType GetCorElementTypeOfElementTypeInternal ( ObjectHandleOnStack arr ) ;
362401
363402 [ MethodImpl ( MethodImplOptions . InternalCall ) ]
364- private extern bool IsValueOfElementType ( object value ) ;
403+ private static extern bool IsValueOfElementTypeInternal ( ObjectHandleOnStack arr , ObjectHandleOnStack obj ) ;
365404
366405 [ MethodImplAttribute ( MethodImplOptions . InternalCall ) ]
367- private static extern bool CanChangePrimitive ( ref Type srcType , ref Type dstType , bool reliable ) ;
406+ private static extern bool CanChangePrimitive ( ObjectHandleOnStack srcType , ObjectHandleOnStack dstType , bool reliable ) ;
368407
369408 [ MethodImplAttribute ( MethodImplOptions . InternalCall ) ]
370- internal static extern bool FastCopy ( Array source , int source_idx , Array dest , int dest_idx , int length ) ;
409+ internal static extern bool FastCopy ( ObjectHandleOnStack source , int source_idx , ObjectHandleOnStack dest , int dest_idx , int length ) ;
371410
372- [ Intrinsic ] // when dimension is `0` constant
373411 [ MethodImplAttribute ( MethodImplOptions . InternalCall ) ]
374- public extern int GetLength ( int dimension ) ;
412+ private static extern int GetLengthInternal ( ObjectHandleOnStack arr , int dimension ) ;
375413
376- [ Intrinsic ] // when dimension is `0` constant
377414 [ MethodImplAttribute ( MethodImplOptions . InternalCall ) ]
378- public extern int GetLowerBound ( int dimension ) ;
415+ private static extern int GetLowerBoundInternal ( ObjectHandleOnStack arr , int dimension ) ;
379416
380417 // CAUTION! No bounds checking!
381418 [ MethodImplAttribute ( MethodImplOptions . InternalCall ) ]
382- private static extern void GetGenericValue_icall < T > ( ref Array self , int pos , out T value ) ;
419+ private static extern void GetGenericValue_icall < T > ( ObjectHandleOnStack self , int pos , out T value ) ;
383420
384421 // CAUTION! No bounds checking!
385422 [ MethodImplAttribute ( MethodImplOptions . InternalCall ) ]
386- private extern object GetValueImpl ( int pos ) ;
423+ private static extern void GetValueImpl ( ObjectHandleOnStack arr , ObjectHandleOnStack res , int pos ) ;
387424
388425 // CAUTION! No bounds checking!
389426 [ MethodImplAttribute ( MethodImplOptions . InternalCall ) ]
390- private static extern void SetGenericValue_icall < T > ( ref Array self , int pos , ref T value ) ;
427+ private static extern void SetGenericValue_icall < T > ( ObjectHandleOnStack arr , int pos , ref T value ) ;
391428
392429 [ Intrinsic ]
393430 private void GetGenericValueImpl < T > ( int pos , out T value )
394431 {
395432 Array self = this ;
396- GetGenericValue_icall ( ref self , pos , out value ) ;
433+ GetGenericValue_icall ( ObjectHandleOnStack . Create ( ref self ) , pos , out value ) ;
397434 }
398435
399436 [ Intrinsic ]
400437 private void SetGenericValueImpl < T > ( int pos , ref T value )
401438 {
402439 Array self = this ;
403- SetGenericValue_icall ( ref self , pos , ref value ) ;
440+ SetGenericValue_icall ( ObjectHandleOnStack . Create ( ref self ) , pos , ref value ) ;
404441 }
405442
406443 // CAUTION! No bounds checking!
407444 [ MethodImplAttribute ( MethodImplOptions . InternalCall ) ]
408- private extern void SetValueImpl ( object ? value , int pos ) ;
445+ private static extern void SetValueImpl ( ObjectHandleOnStack arr , ObjectHandleOnStack value , int pos ) ;
409446
410447 [ MethodImpl ( MethodImplOptions . InternalCall ) ]
411448 private static extern void InitializeInternal ( ObjectHandleOnStack arr ) ;
412449
413450 // CAUTION! No bounds checking!
414451 [ MethodImplAttribute ( MethodImplOptions . InternalCall ) ]
415- private extern void SetValueRelaxedImpl ( object ? value , int pos ) ;
452+ private static extern void SetValueRelaxedImpl ( ObjectHandleOnStack arr , ObjectHandleOnStack value , int pos ) ;
416453
417454#pragma warning disable CA1822
418455 /*
0 commit comments