[mini] Fix delegate trampoline virtual call via delgate Invoke (#18073)
* [mini] Fix delegate trampoline virtual call via delgate Invoke
If we need to jit the Invoke method of a delegate, we get tramp_info with a
NULL method.
Background: normally when we create a delegate around a virtual method,
handle_delegate_ctor will just create a virtual invoke trampoline with
mono_arch_get_delegate_virtual_invoke_impl which doesn't get here. But if
we're asked to compile the delegate's Invoke method, then compile_special ()
will create a tramp_info with a null method, and return a delegate trampoline.
That's the case here - we had
var del = SomeDelegate(obj.VirtualMethod);
var invoke_method = del.GetType().GetMethod ("Invoke");
invoke_method.Invoke (del, args);
or
var del = SomeDelegate(obj.VirtualMethod);
var another_del = OtherDelegate (del.Invoke);
another_del (args);
in both cases, we end up in mono_delegate_trampoline with tramp_info->method ==
NULL.
in the second case the IL is like this:
newobj instance void Derived::'.ctor'
ldvirtftn instance void class Base::VirtualMethod()
newobj instance void class SomeDelegate::'.ctor'(object, native int)
So delegate->target is a derived instance but delegate->method is some base
class method.
Addresses https://github.com/mono/mono/issues/17718
* [tests] Add tests for compiling delegate's Invoke method
Where the delegate calls a virtual method