Skip to content

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

Merged
lewurm merged 2 commits intomono:masterfrom
lambdageek:fix-gh-17718
Dec 10, 2019
Merged

[mini] Fix delegate trampoline virtual call via delgate Invoke#18073
lewurm merged 2 commits intomono:masterfrom
lambdageek:fix-gh-17718

Conversation

@lambdageek
Copy link
Member

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

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
@lambdageek lambdageek marked this pull request as ready for review December 6, 2019 18:55
@lambdageek lambdageek changed the title [draft] [mini] Fix delegate trampoline virtual call via delgate Invoke [mini] Fix delegate trampoline virtual call via delgate Invoke Dec 6, 2019
@lewurm
Copy link
Contributor

lewurm commented Dec 9, 2019

Looks good to me. @BrzVlad could have a look at it too?

@SamMonoRT SamMonoRT requested a review from BrzVlad December 9, 2019 21:51
@lewurm lewurm merged commit 7704bd1 into mono:master Dec 10, 2019
@lewurm
Copy link
Contributor

lewurm commented Dec 10, 2019

@monojenkins backport 2019-12

@lambdageek
Copy link
Member Author

@monojenkins backport to 2019-10

monojenkins added a commit that referenced this pull request Dec 10, 2019
…oke (#18115)

[2019-10] [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 #17718



Backport of #18073.

/cc @lambdageek
ManickaP pushed a commit to ManickaP/runtime that referenced this pull request Jan 20, 2020
…mono#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/mono#17718

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

Where the delegate calls a virtual method


Commit migrated from mono/mono@7704bd1
joncham pushed a commit to Unity-Technologies/mono that referenced this pull request Mar 16, 2021
…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
joncham added a commit to Unity-Technologies/mono that referenced this pull request Mar 17, 2021
…8422

[mini] Fix delegate trampoline virtual call via delgate Invoke (mono#18073)
dtomar-rythmos pushed a commit to Unity-Technologies/mono that referenced this pull request Apr 8, 2021
…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
dtomar-rythmos pushed a commit to Unity-Technologies/mono that referenced this pull request Apr 8, 2021
…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
dtomar-rythmos pushed a commit to Unity-Technologies/mono that referenced this pull request Apr 8, 2021
…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
dtomar-rythmos added a commit to Unity-Technologies/mono that referenced this pull request Apr 12, 2021
…8422

[mini] Fix delegate trampoline virtual call via delgate Invoke (mono#18073)
dtomar-rythmos added a commit to Unity-Technologies/mono that referenced this pull request Apr 12, 2021
…8422

[mini] Fix delegate trampoline virtual call via delgate Invoke (mono#18073)
dtomar-rythmos added a commit to Unity-Technologies/mono that referenced this pull request Apr 12, 2021
…8422

[mini] Fix delegate trampoline virtual call via delgate Invoke (mono#18073)
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