@@ -2371,6 +2371,44 @@ emit_missing_method_error (MonoMethodBuilder *mb, MonoError *failure, const char
2371
2371
}
2372
2372
}
2373
2373
2374
+ static MonoMethodSignature *
2375
+ update_signature (MonoMethod * accessor_method )
2376
+ {
2377
+ MonoClass * accessor_method_class_instance = accessor_method -> klass ;
2378
+ MonoClass * accessor_method_class = mono_class_get_generic_type_definition (accessor_method_class_instance );
2379
+
2380
+ const char * accessor_method_name = accessor_method -> name ;
2381
+
2382
+ gpointer iter = NULL ;
2383
+ MonoMethod * m = NULL ;
2384
+ while ((m = mono_class_get_methods (accessor_method_class , & iter ))) {
2385
+ if (!m )
2386
+ continue ;
2387
+
2388
+ if (strcmp (m -> name , accessor_method_name ))
2389
+ continue ;
2390
+
2391
+ return mono_metadata_signature_dup_full (get_method_image (m ), mono_method_signature_internal (m ));
2392
+ }
2393
+ g_assert_not_reached ();
2394
+ }
2395
+
2396
+ static MonoMethod *
2397
+ inflate_method (MonoClass * klass , MonoMethod * method , MonoMethod * accessor_method , MonoError * error )
2398
+ {
2399
+ MonoMethod * result = method ;
2400
+ MonoGenericContext context = { NULL , NULL };
2401
+ if (mono_class_is_ginst (klass ))
2402
+ context .class_inst = mono_class_get_generic_class (klass )-> context .class_inst ;
2403
+ if (accessor_method -> is_inflated )
2404
+ context .method_inst = mono_method_get_context (accessor_method )-> method_inst ;
2405
+ if ((context .class_inst != NULL ) || (context .method_inst != NULL ))
2406
+ result = mono_class_inflate_generic_method_checked (method , & context , error );
2407
+ mono_error_assert_ok (error );
2408
+
2409
+ return result ;
2410
+ }
2411
+
2374
2412
static void
2375
2413
emit_unsafe_accessor_ctor_wrapper (MonoMethodBuilder * mb , MonoMethod * accessor_method , MonoMethodSignature * sig , MonoGenericContext * ctx , MonoUnsafeAccessorKind kind , const char * member_name )
2376
2414
{
@@ -2389,12 +2427,17 @@ emit_unsafe_accessor_ctor_wrapper (MonoMethodBuilder *mb, MonoMethod *accessor_m
2389
2427
return ;
2390
2428
}
2391
2429
2392
- MonoMethodSignature * member_sig = ctor_sig_from_accessor_sig (mb , sig , ctx );
2393
-
2394
2430
MonoClass * target_class = mono_class_from_mono_type_internal (target_type );
2395
2431
2396
2432
ERROR_DECL (find_method_error );
2397
- MonoClass * in_class = mono_class_is_ginst (target_class ) ? mono_class_get_generic_class (target_class )-> container_class : target_class ;
2433
+ if (accessor_method -> is_inflated ) {
2434
+ sig = update_signature (accessor_method );
2435
+ }
2436
+
2437
+ MonoMethodSignature * member_sig = ctor_sig_from_accessor_sig (mb , sig , ctx );
2438
+
2439
+ MonoClass * in_class = mono_class_get_generic_type_definition (target_class );
2440
+
2398
2441
MonoMethod * target_method = mono_unsafe_accessor_find_ctor (in_class , member_sig , target_class , find_method_error );
2399
2442
if (!is_ok (find_method_error ) || target_method == NULL ) {
2400
2443
if (mono_error_get_error_code (find_method_error ) == MONO_ERROR_GENERIC )
@@ -2404,6 +2447,9 @@ emit_unsafe_accessor_ctor_wrapper (MonoMethodBuilder *mb, MonoMethod *accessor_m
2404
2447
mono_error_cleanup (find_method_error );
2405
2448
return ;
2406
2449
}
2450
+
2451
+ target_method = inflate_method (target_class , target_method , accessor_method , find_method_error );
2452
+
2407
2453
g_assert (target_method -> klass == target_class );
2408
2454
2409
2455
emit_unsafe_accessor_ldargs (mb , sig , 0 );
@@ -2425,11 +2471,9 @@ emit_unsafe_accessor_method_wrapper (MonoMethodBuilder *mb, MonoMethod *accessor
2425
2471
mono_mb_emit_exception_full (mb , "System" , "BadImageFormatException" , "Invalid usage of UnsafeAccessorAttribute." );
2426
2472
return ;
2427
2473
}
2428
- gboolean hasthis = kind == MONO_UNSAFE_ACCESSOR_METHOD ;
2429
- MonoType * target_type = sig -> params [0 ];
2430
-
2431
- MonoMethodSignature * member_sig = method_sig_from_accessor_sig (mb , hasthis , sig , ctx );
2432
2474
2475
+ MonoType * target_type = sig -> params [0 ];
2476
+ gboolean hasthis = kind == MONO_UNSAFE_ACCESSOR_METHOD ;
2433
2477
MonoClass * target_class = mono_class_from_mono_type_internal (target_type );
2434
2478
2435
2479
if (hasthis && m_class_is_valuetype (target_class ) && !m_type_is_byref (target_type )) {
@@ -2438,7 +2482,14 @@ emit_unsafe_accessor_method_wrapper (MonoMethodBuilder *mb, MonoMethod *accessor
2438
2482
}
2439
2483
2440
2484
ERROR_DECL (find_method_error );
2441
- MonoClass * in_class = mono_class_is_ginst (target_class ) ? mono_class_get_generic_class (target_class )-> container_class : target_class ;
2485
+ if (accessor_method -> is_inflated ) {
2486
+ sig = update_signature (accessor_method );
2487
+ }
2488
+
2489
+ MonoMethodSignature * member_sig = method_sig_from_accessor_sig (mb , hasthis , sig , ctx );
2490
+
2491
+ MonoClass * in_class = mono_class_get_generic_type_definition (target_class );
2492
+
2442
2493
MonoMethod * target_method = NULL ;
2443
2494
if (!ctor_as_method )
2444
2495
target_method = mono_unsafe_accessor_find_method (in_class , member_name , member_sig , target_class , find_method_error );
@@ -2452,11 +2503,15 @@ emit_unsafe_accessor_method_wrapper (MonoMethodBuilder *mb, MonoMethod *accessor
2452
2503
mono_error_cleanup (find_method_error );
2453
2504
return ;
2454
2505
}
2506
+
2507
+ target_method = inflate_method (target_class , target_method , accessor_method , find_method_error );
2508
+
2455
2509
if (!hasthis && target_method -> klass != target_class ) {
2456
2510
emit_missing_method_error (mb , find_method_error , member_name );
2457
2511
return ;
2458
2512
}
2459
- g_assert (target_method -> klass == target_class ); // are instance methods allowed to be looked up using inheritance?
2513
+
2514
+ g_assert (target_method -> klass == target_class );
2460
2515
2461
2516
emit_unsafe_accessor_ldargs (mb , sig , !hasthis ? 1 : 0 );
2462
2517
0 commit comments