2
2
// The .NET Foundation licenses this file to you under the MIT license.
3
3
4
4
using System . Diagnostics ;
5
- using System . Numerics ;
6
- using System . Runtime . CompilerServices ;
7
5
using System . Runtime . InteropServices ;
8
- using System . Threading ;
9
6
10
7
namespace System . Runtime . CompilerServices
11
8
{
9
+ [ StackTraceHidden ]
10
+ [ DebuggerStepThrough ]
12
11
internal static unsafe class CastHelpers
13
12
{
14
13
// In coreclr the table is allocated and written to on the native side.
@@ -24,14 +23,12 @@ internal static unsafe class CastHelpers
24
23
private static extern ref byte Unbox_Helper ( void * toTypeHnd , object obj ) ;
25
24
26
25
[ MethodImpl ( MethodImplOptions . InternalCall ) ]
27
- private static extern void WriteBarrier ( ref object ? dst , object obj ) ;
26
+ private static extern void WriteBarrier ( ref object ? dst , object ? obj ) ;
28
27
29
28
// IsInstanceOf test used for unusual cases (naked type parameters, variant generic types)
30
29
// Unlike the IsInstanceOfInterface and IsInstanceOfClass functions,
31
30
// this test must deal with all kinds of type tests
32
31
[ DebuggerHidden ]
33
- [ StackTraceHidden ]
34
- [ DebuggerStepThrough ]
35
32
private static object ? IsInstanceOfAny ( void * toTypeHnd , object ? obj )
36
33
{
37
34
if ( obj != null )
@@ -63,8 +60,6 @@ internal static unsafe class CastHelpers
63
60
}
64
61
65
62
[ DebuggerHidden ]
66
- [ StackTraceHidden ]
67
- [ DebuggerStepThrough ]
68
63
private static object ? IsInstanceOfInterface ( void * toTypeHnd , object ? obj )
69
64
{
70
65
const int unrollSize = 4 ;
@@ -134,8 +129,6 @@ internal static unsafe class CastHelpers
134
129
}
135
130
136
131
[ DebuggerHidden ]
137
- [ StackTraceHidden ]
138
- [ DebuggerStepThrough ]
139
132
private static object ? IsInstanceOfClass ( void * toTypeHnd , object ? obj )
140
133
{
141
134
if ( obj == null || RuntimeHelpers . GetMethodTable ( obj ) == toTypeHnd )
@@ -184,8 +177,6 @@ internal static unsafe class CastHelpers
184
177
}
185
178
186
179
[ DebuggerHidden ]
187
- [ StackTraceHidden ]
188
- [ DebuggerStepThrough ]
189
180
[ MethodImpl ( MethodImplOptions . NoInlining ) ]
190
181
private static object ? IsInstance_Helper ( void * toTypeHnd , object obj )
191
182
{
@@ -207,8 +198,6 @@ internal static unsafe class CastHelpers
207
198
// Unlike the ChkCastInterface and ChkCastClass functions,
208
199
// this test must deal with all kinds of type tests
209
200
[ DebuggerHidden ]
210
- [ StackTraceHidden ]
211
- [ DebuggerStepThrough ]
212
201
internal static object ? ChkCastAny ( void * toTypeHnd , object ? obj )
213
202
{
214
203
CastResult result ;
@@ -237,8 +226,6 @@ internal static unsafe class CastHelpers
237
226
}
238
227
239
228
[ DebuggerHidden ]
240
- [ StackTraceHidden ]
241
- [ DebuggerStepThrough ]
242
229
[ MethodImpl ( MethodImplOptions . NoInlining ) ]
243
230
private static object ? ChkCast_Helper ( void * toTypeHnd , object obj )
244
231
{
@@ -253,8 +240,6 @@ internal static unsafe class CastHelpers
253
240
}
254
241
255
242
[ DebuggerHidden ]
256
- [ StackTraceHidden ]
257
- [ DebuggerStepThrough ]
258
243
private static object ? ChkCastInterface ( void * toTypeHnd , object ? obj )
259
244
{
260
245
const int unrollSize = 4 ;
@@ -321,8 +306,6 @@ internal static unsafe class CastHelpers
321
306
}
322
307
323
308
[ DebuggerHidden ]
324
- [ StackTraceHidden ]
325
- [ DebuggerStepThrough ]
326
309
private static object ? ChkCastClass ( void * toTypeHnd , object ? obj )
327
310
{
328
311
if ( obj == null || RuntimeHelpers . GetMethodTable ( obj ) == toTypeHnd )
@@ -336,8 +319,6 @@ internal static unsafe class CastHelpers
336
319
// Optimized helper for classes. Assumes that the trivial cases
337
320
// has been taken care of by the inlined check
338
321
[ DebuggerHidden ]
339
- [ StackTraceHidden ]
340
- [ DebuggerStepThrough ]
341
322
private static object ? ChkCastClassSpecial ( void * toTypeHnd , object obj )
342
323
{
343
324
MethodTable * mt = RuntimeHelpers . GetMethodTable ( obj ) ;
@@ -384,52 +365,53 @@ internal static unsafe class CastHelpers
384
365
}
385
366
386
367
[ DebuggerHidden ]
387
- [ StackTraceHidden ]
388
- [ DebuggerStepThrough ]
389
368
private static ref byte Unbox ( void * toTypeHnd , object obj )
390
369
{
391
- // this will throw NullReferenceException if obj is null, attributed to the user code, as expected .
370
+ // This will throw NullReferenceException if obj is null.
392
371
if ( RuntimeHelpers . GetMethodTable ( obj ) == toTypeHnd )
393
372
return ref obj . GetRawData ( ) ;
394
373
395
374
return ref Unbox_Helper ( toTypeHnd , obj ) ;
396
375
}
397
376
398
- internal struct ArrayElement
377
+ [ DebuggerHidden ]
378
+ private static void ThrowIndexOutOfRangeException ( )
399
379
{
400
- public object ? Value ;
380
+ throw new IndexOutOfRangeException ( ) ;
401
381
}
402
382
403
383
[ DebuggerHidden ]
404
- [ StackTraceHidden ]
405
- [ DebuggerStepThrough ]
406
- private static ref object ? ThrowArrayMismatchException ( )
384
+ private static void ThrowArrayMismatchException ( )
407
385
{
408
386
throw new ArrayTypeMismatchException ( ) ;
409
387
}
410
388
411
389
[ DebuggerHidden ]
412
- [ StackTraceHidden ]
413
- [ DebuggerStepThrough ]
414
- private static ref object ? LdelemaRef ( Array array , nint index , void * type )
390
+ private static ref object ? LdelemaRef ( object ? [ ] array , nint index , void * type )
415
391
{
416
- // this will throw appropriate exceptions if array is null or access is out of range.
417
- ref object ? element = ref Unsafe . As < ArrayElement [ ] > ( array ) [ index ] . Value ;
392
+ // This will throw NullReferenceException if array is null.
393
+ if ( ( nuint ) index >= ( uint ) array . Length )
394
+ ThrowIndexOutOfRangeException ( ) ;
395
+
396
+ Debug . Assert ( index >= 0 ) ;
397
+ ref object ? element = ref Unsafe . Add ( ref MemoryMarshal . GetArrayDataReference ( array ) , index ) ;
418
398
void * elementType = RuntimeHelpers . GetMethodTable ( array ) ->ElementType ;
419
399
420
- if ( elementType = = type )
421
- return ref element ;
400
+ if ( elementType ! = type )
401
+ ThrowArrayMismatchException ( ) ;
422
402
423
- return ref ThrowArrayMismatchException ( ) ;
403
+ return ref element ;
424
404
}
425
405
426
406
[ DebuggerHidden ]
427
- [ StackTraceHidden ]
428
- [ DebuggerStepThrough ]
429
- private static void StelemRef ( Array array , nint index , object ? obj )
407
+ private static void StelemRef ( object ? [ ] array , nint index , object ? obj )
430
408
{
431
- // this will throw appropriate exceptions if array is null or access is out of range.
432
- ref object ? element = ref Unsafe . As < ArrayElement [ ] > ( array ) [ index ] . Value ;
409
+ // This will throw NullReferenceException if array is null.
410
+ if ( ( nuint ) index >= ( uint ) array . Length )
411
+ ThrowIndexOutOfRangeException ( ) ;
412
+
413
+ Debug . Assert ( index >= 0 ) ;
414
+ ref object ? element = ref Unsafe . Add ( ref MemoryMarshal . GetArrayDataReference ( array ) , index ) ;
433
415
void * elementType = RuntimeHelpers . GetMethodTable ( array ) ->ElementType ;
434
416
435
417
if ( obj == null )
@@ -454,8 +436,6 @@ private static void StelemRef(Array array, nint index, object? obj)
454
436
}
455
437
456
438
[ DebuggerHidden ]
457
- [ StackTraceHidden ]
458
- [ DebuggerStepThrough ]
459
439
[ MethodImpl ( MethodImplOptions . NoInlining ) ]
460
440
private static void StelemRef_Helper ( ref object ? element , void * elementType , object obj )
461
441
{
@@ -470,20 +450,17 @@ private static void StelemRef_Helper(ref object? element, void* elementType, obj
470
450
}
471
451
472
452
[ DebuggerHidden ]
473
- [ StackTraceHidden ]
474
- [ DebuggerStepThrough ]
475
453
private static void StelemRef_Helper_NoCacheLookup ( ref object ? element , void * elementType , object obj )
476
454
{
477
455
Debug . Assert ( obj != null ) ;
478
456
479
457
obj = IsInstanceOfAny_NoCacheLookup ( elementType , obj ) ;
480
- if ( obj ! = null )
458
+ if ( obj = = null )
481
459
{
482
- WriteBarrier ( ref element , obj ) ;
483
- return ;
460
+ ThrowArrayMismatchException ( ) ;
484
461
}
485
462
486
- throw new ArrayTypeMismatchException ( ) ;
463
+ WriteBarrier ( ref element , obj ) ;
487
464
}
488
465
}
489
466
}
0 commit comments