@@ -3515,7 +3515,7 @@ free_signature_pointer_pair (SignaturePointerPair *pair)
3515
3515
MonoMethod *
3516
3516
mono_marshal_get_delegate_invoke_internal (MonoMethod * method , gboolean callvirt , gboolean static_method_with_first_arg_bound , MonoMethod * target_method )
3517
3517
{
3518
- MonoMethodSignature * sig , * static_sig , * invoke_sig ;
3518
+ MonoMethodSignature * sig , * invoke_sig ;
3519
3519
int i ;
3520
3520
MonoMethodBuilder * mb ;
3521
3521
MonoMethod * res ;
@@ -3568,6 +3568,13 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt
3568
3568
subtype = WRAPPER_SUBTYPE_DELEGATE_INVOKE_BOUND ;
3569
3569
g_assert (!callvirt );
3570
3570
invoke_sig = mono_method_signature (target_method );
3571
+ /*
3572
+ * The wrapper has a different lifetime from the method to be invoked.
3573
+ * If the method is dynamic we don't want to be using its signature
3574
+ * in the wrapper since it could get freed early.
3575
+ */
3576
+ if (method_is_dynamic (target_method ))
3577
+ invoke_sig = mono_metadata_signature_dup_full (target_method -> klass -> image , invoke_sig );
3571
3578
}
3572
3579
3573
3580
/*
@@ -3595,7 +3602,11 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt
3595
3602
return res ;
3596
3603
cache_key = method -> klass ;
3597
3604
} else if (static_method_with_first_arg_bound ) {
3598
- cache = get_cache (& method -> klass -> image -> delegate_bound_static_invoke_cache ,
3605
+ GHashTable * * cache_ptr ;
3606
+
3607
+ cache_ptr = & mono_method_get_wrapper_cache (target_method )-> delegate_bound_static_invoke_cache ;
3608
+
3609
+ cache = get_cache (cache_ptr ,
3599
3610
(GHashFunc )mono_signature_hash ,
3600
3611
(GCompareFunc )mono_metadata_signature_equal );
3601
3612
/*
@@ -3633,10 +3644,10 @@ mono_marshal_get_delegate_invoke_internal (MonoMethod *method, gboolean callvirt
3633
3644
cache_key = sig ;
3634
3645
}
3635
3646
3636
- static_sig = mono_metadata_signature_dup_full ( method -> klass -> image , sig );
3637
- static_sig -> hasthis = 0 ;
3638
- if (! static_method_with_first_arg_bound )
3639
- invoke_sig = static_sig ;
3647
+ if (! static_method_with_first_arg_bound ) {
3648
+ invoke_sig = mono_metadata_signature_dup_full ( method -> klass -> image , sig ) ;
3649
+ invoke_sig -> hasthis = 0 ;
3650
+ }
3640
3651
3641
3652
if (static_method_with_first_arg_bound )
3642
3653
name = mono_signature_to_name (invoke_sig , "invoke_bound" );
@@ -12393,8 +12404,8 @@ mono_marshal_free_dynamic_wrappers (MonoMethod *method)
12393
12404
if (image -> wrapper_caches .delegate_abstract_invoke_cache )
12394
12405
g_hash_table_foreach_remove (image -> wrapper_caches .delegate_abstract_invoke_cache , signature_pointer_pair_matches_pointer , method );
12395
12406
// FIXME: Need to clear the caches in other images as well
12396
- if (image -> delegate_bound_static_invoke_cache )
12397
- g_hash_table_remove (image -> delegate_bound_static_invoke_cache , mono_method_signature (method ));
12407
+ if (image -> wrapper_caches . delegate_bound_static_invoke_cache )
12408
+ g_hash_table_remove (image -> wrapper_caches . delegate_bound_static_invoke_cache , mono_method_signature (method ));
12398
12409
12399
12410
if (marshal_mutex_initialized )
12400
12411
mono_marshal_unlock ();
0 commit comments