Skip to content

[mini] Fix delegate trampoline virtual call via delgate Invoke (#18073)#1426

Merged
dtomar-rythmos merged 1 commit intounity-2019.4-mbefrom
unity-2019.4-fix-1188422
Apr 12, 2021
Merged

[mini] Fix delegate trampoline virtual call via delgate Invoke (#18073)#1426
dtomar-rythmos merged 1 commit intounity-2019.4-mbefrom
unity-2019.4-fix-1188422

Conversation

@dtomar-rythmos
Copy link

  • [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 mono#17718

  • [tests] Add tests for compiling delegate's Invoke method

Where the delegate calls a virtual method

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

* [tests] Add tests for compiling delegate's Invoke method

Where the delegate calls a virtual method
@unity-cla-assistant
Copy link
Collaborator

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@dtomar-rythmos dtomar-rythmos merged commit 80e6f67 into unity-2019.4-mbe Apr 12, 2021
@dtomar-rythmos dtomar-rythmos deleted the unity-2019.4-fix-1188422 branch April 12, 2021 05:34
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.

4 participants