Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow injecting in constructors and class initializers #267

Closed
Runemoro opened this issue Jun 24, 2018 · 1 comment
Closed

Allow injecting in constructors and class initializers #267

Runemoro opened this issue Jun 24, 2018 · 1 comment

Comments

@Runemoro
Copy link
Contributor

I'd like to inject some code in the following constructor, right before findAmbiguities https://paste.dimdev.org/febovazuwi.java, but Mixin doesn't allow me to do this since the only valid injection point is RETURN.

My options are:

  • Redirect the call to findAmbiguities and add the code before (luckily in this case I have access to field_197062_b from a redirect, but this isn't always the case)
  • Use ASM to inject my code where I want

According to the documentation, the reason for this is:

The only Injection Point supported for constructors is the RETURN injector This restriction is imposed because there is no other sensible way to be sure that the class is fully initialised before calling your handler code.

But I don't expect the class to be fully initialized when my code gets called! The only thing that needs to be initialized is field_197062_b, and it obviously is in this case.

The documentation also states:

However at the bytecode level constructors are much more delicate. Since a compiled method represents a mish-mash of the original constructor code, any field initialisers for the class (duplicated in all constructors), and in some cases synthetic (compiler-generated) code as well (for example in Enum constructors). Because of their nature, they represent a minefield for bytecode-level transformations.

In this case this isn't a problem since there is only one call to findAmbiguities in the whole class, so the injection point is clear.

I'm not sure how determining the injection point could be difficult, since the <init> method generated is always in the same order as the field initializers and initializer blocks, but even if it was, I could still disassemble the class file and look at the method and see which ordinal/slice I need to make a safe injection point.

@Mumfrey
Copy link
Member

Mumfrey commented Jun 25, 2018

No sorry, there is no way I'm going to allow injecting into constructors beyond the ones which are already supported. You can redirect the call to findAmbiguities for this use-case. Frankly I'd rather prohibit operations on the constructor altogether but the functionality is too essential.

Don't forget you can redirect field accesses, constants and object constructors as well and those provide a good hook point for other functionality. The existing capabilities cover 99% of the use-cases and the remaining 1% aren't worth the potential pitfalls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants