@@ -2424,6 +2424,44 @@ emit_missing_method_error (MonoMethodBuilder *mb, MonoError *failure, const char
2424
2424
}
2425
2425
}
2426
2426
2427
+ static MonoMethodSignature *
2428
+ update_signature (MonoMethod * accessor_method )
2429
+ {
2430
+ MonoClass * accessor_method_class_instance = accessor_method -> klass ;
2431
+ MonoClass * accessor_method_class = mono_class_get_generic_type_definition (accessor_method_class_instance );
2432
+
2433
+ const char * accessor_method_name = accessor_method -> name ;
2434
+
2435
+ gpointer iter = NULL ;
2436
+ MonoMethod * m = NULL ;
2437
+ while ((m = mono_class_get_methods (accessor_method_class , & iter ))) {
2438
+ if (!m )
2439
+ continue ;
2440
+
2441
+ if (strcmp (m -> name , accessor_method_name ))
2442
+ continue ;
2443
+
2444
+ return mono_metadata_signature_dup_full (get_method_image (m ), mono_method_signature_internal (m ));
2445
+ }
2446
+ g_assert_not_reached ();
2447
+ }
2448
+
2449
+ static MonoMethod *
2450
+ inflate_method (MonoClass * klass , MonoMethod * method , MonoMethod * accessor_method , MonoError * error )
2451
+ {
2452
+ MonoMethod * result = method ;
2453
+ MonoGenericContext context = { NULL , NULL };
2454
+ if (mono_class_is_ginst (klass ))
2455
+ context .class_inst = mono_class_get_generic_class (klass )-> context .class_inst ;
2456
+ if (accessor_method -> is_inflated )
2457
+ context .method_inst = mono_method_get_context (accessor_method )-> method_inst ;
2458
+ if ((context .class_inst != NULL ) || (context .method_inst != NULL ))
2459
+ result = mono_class_inflate_generic_method_checked (method , & context , error );
2460
+ mono_error_assert_ok (error );
2461
+
2462
+ return result ;
2463
+ }
2464
+
2427
2465
static void
2428
2466
emit_unsafe_accessor_ctor_wrapper (MonoMethodBuilder * mb , MonoMethod * accessor_method , MonoMethodSignature * sig , MonoGenericContext * ctx , MonoUnsafeAccessorKind kind , const char * member_name )
2429
2467
{
@@ -2442,12 +2480,17 @@ emit_unsafe_accessor_ctor_wrapper (MonoMethodBuilder *mb, MonoMethod *accessor_m
2442
2480
return ;
2443
2481
}
2444
2482
2445
- MonoMethodSignature * member_sig = ctor_sig_from_accessor_sig (mb , sig , ctx );
2446
-
2447
2483
MonoClass * target_class = mono_class_from_mono_type_internal (target_type );
2448
2484
2449
2485
ERROR_DECL (find_method_error );
2450
- MonoClass * in_class = mono_class_is_ginst (target_class ) ? mono_class_get_generic_class (target_class )-> container_class : target_class ;
2486
+ if (accessor_method -> is_inflated ) {
2487
+ sig = update_signature (accessor_method );
2488
+ }
2489
+
2490
+ MonoMethodSignature * member_sig = ctor_sig_from_accessor_sig (mb , sig , ctx );
2491
+
2492
+ MonoClass * in_class = mono_class_get_generic_type_definition (target_class );
2493
+
2451
2494
MonoMethod * target_method = mono_unsafe_accessor_find_ctor (in_class , member_sig , target_class , find_method_error );
2452
2495
if (!is_ok (find_method_error ) || target_method == NULL ) {
2453
2496
if (mono_error_get_error_code (find_method_error ) == MONO_ERROR_GENERIC )
@@ -2457,6 +2500,9 @@ emit_unsafe_accessor_ctor_wrapper (MonoMethodBuilder *mb, MonoMethod *accessor_m
2457
2500
mono_error_cleanup (find_method_error );
2458
2501
return ;
2459
2502
}
2503
+
2504
+ target_method = inflate_method (target_class , target_method , accessor_method , find_method_error );
2505
+
2460
2506
g_assert (target_method -> klass == target_class );
2461
2507
2462
2508
emit_unsafe_accessor_ldargs (mb , sig , 0 );
@@ -2478,11 +2524,9 @@ emit_unsafe_accessor_method_wrapper (MonoMethodBuilder *mb, MonoMethod *accessor
2478
2524
mono_mb_emit_exception_full (mb , "System" , "BadImageFormatException" , "Invalid usage of UnsafeAccessorAttribute." );
2479
2525
return ;
2480
2526
}
2481
- gboolean hasthis = kind == MONO_UNSAFE_ACCESSOR_METHOD ;
2482
- MonoType * target_type = sig -> params [0 ];
2483
-
2484
- MonoMethodSignature * member_sig = method_sig_from_accessor_sig (mb , hasthis , sig , ctx );
2485
2527
2528
+ MonoType * target_type = sig -> params [0 ];
2529
+ gboolean hasthis = kind == MONO_UNSAFE_ACCESSOR_METHOD ;
2486
2530
MonoClass * target_class = mono_class_from_mono_type_internal (target_type );
2487
2531
2488
2532
if (hasthis && m_class_is_valuetype (target_class ) && !m_type_is_byref (target_type )) {
@@ -2491,7 +2535,14 @@ emit_unsafe_accessor_method_wrapper (MonoMethodBuilder *mb, MonoMethod *accessor
2491
2535
}
2492
2536
2493
2537
ERROR_DECL (find_method_error );
2494
- MonoClass * in_class = mono_class_is_ginst (target_class ) ? mono_class_get_generic_class (target_class )-> container_class : target_class ;
2538
+ if (accessor_method -> is_inflated ) {
2539
+ sig = update_signature (accessor_method );
2540
+ }
2541
+
2542
+ MonoMethodSignature * member_sig = method_sig_from_accessor_sig (mb , hasthis , sig , ctx );
2543
+
2544
+ MonoClass * in_class = mono_class_get_generic_type_definition (target_class );
2545
+
2495
2546
MonoMethod * target_method = NULL ;
2496
2547
if (!ctor_as_method )
2497
2548
target_method = mono_unsafe_accessor_find_method (in_class , member_name , member_sig , target_class , find_method_error );
@@ -2505,11 +2556,15 @@ emit_unsafe_accessor_method_wrapper (MonoMethodBuilder *mb, MonoMethod *accessor
2505
2556
mono_error_cleanup (find_method_error );
2506
2557
return ;
2507
2558
}
2559
+
2560
+ target_method = inflate_method (target_class , target_method , accessor_method , find_method_error );
2561
+
2508
2562
if (!hasthis && target_method -> klass != target_class ) {
2509
2563
emit_missing_method_error (mb , find_method_error , member_name );
2510
2564
return ;
2511
2565
}
2512
- g_assert (target_method -> klass == target_class ); // are instance methods allowed to be looked up using inheritance?
2566
+
2567
+ g_assert (target_method -> klass == target_class );
2513
2568
2514
2569
emit_unsafe_accessor_ldargs (mb , sig , !hasthis ? 1 : 0 );
2515
2570
0 commit comments