Skip to content

[2019-10] [mini] Fix delegate trampoline virtual call via delgate Invoke#18115

Merged
monojenkins merged 2 commits intomono:2019-10from
monojenkins:backport-pr-18073-to-2019-10
Dec 10, 2019
Merged

[2019-10] [mini] Fix delegate trampoline virtual call via delgate Invoke#18115
monojenkins merged 2 commits intomono:2019-10from
monojenkins:backport-pr-18073-to-2019-10

Conversation

@monojenkins
Copy link
Contributor

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 #17718

Backport of #18073.

/cc @lambdageek

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 mono#17718
Where the delegate calls a virtual method
@lewurm
Copy link
Contributor

lewurm commented Dec 10, 2019

@monojenkins squash

@monojenkins
Copy link
Contributor Author

Cannot squash because the following required status checks are not successful:

  • "Linux AArch64" state is "failure"

@lewurm
Copy link
Contributor

lewurm commented Dec 10, 2019

@monojenkins build Linux AArch64

@monojenkins monojenkins merged commit e6cd9a1 into mono:2019-10 Dec 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants