-
Notifications
You must be signed in to change notification settings - Fork 65
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
Remapping java reflect/invoke calls #70
Comments
I will argue this is a complex work. I think we would have a complete list of what method can be used for reflection first before any further discussion. |
The main ones that I found by looking at jdk javadocs:
For unsafe, only Another category of classes worthy of notice is the The strategy for looking up is to find class definition and string-taking methods and evaluate them. |
@sfPlayer1 How is the feasibility of this? I think we might include another flag for the remapper builder (and a corresponding command line flag) for such remapping. |
This would be a reasonable extension I think, could even go as far as handling dynamic reflection by injecting some remapping runtime bits. Static reflection remapping needs some analysis to associate type and string constants (LDC) with the actual reflection lookup method (Class.forName etc). Even some simple bytecode shapes that are easy to cover already go a long way in making reflection convenient. The class defining ones aren't particularly important. The |
Just to clarify the goal for this. Do you want to "remap" all the reflections including void reflect_helper(Stirng className) {
Class.forName(className)
} or just string literal one like this Class.forName("bla/bla/MyClass"); but not the first example. |
The first is the dynamic case, which would require insertion of some runtime logic, the second is the static case and can be done directly (Class.forName uses dot-form btw). Supporting both would be nice, starting with only the 2nd is perfectly adequate. Either way, it is an open ended feature request that will have to wait until there's time for it. |
Yeah, Imo a first step before implementing either cases may be emitting warnings for such encountered class definition/reflection calls and noticing that remapping may not handle these perfectly, which can indicate most of the first case scenarios (unless they depend on some third-party libraries that is outside of remapping). The handling of second case should be easy once bytecode analysis is done. |
Here's my idea, this extension will contain two parts, one is an extension of tiny-remapper, the second one is a runtime which doing the string literal remap for the runtime. The tiny-remapper extension will redirect all method calls mentioned above to a static method in the runtime package, and let the runtime do the actual remapping. It will be the user's responsibility to add a runtime jar & correct mapping file to the classpath (which will be integrated into the loom). Some questions remain, what if a jar is remapped multiple times, then the loom will need to merge the current mapping file & the mapping file in the jar. This also means the jar needs to distribute with a mapping file in jar to have the runtime remapping capiblity. |
I'd focus on statically determinable reflection remapping first, the dynamic part poses some legal challenged when proprietary mappings like mojang's are used and bundled with the jar (which is also what'd make it easiest to handle..). |
In tiny remapper, as far as I know, currently we do not handle reflect and invokes.
This may be a problem as Minecraft does use reflection and method handles, namely to interact with LWJGL. Hence, if lwjgl for a minecraft client is remapped, the game will fail because of reflection issues.
The remapping IMO should be done as such:
Class.forName
callsClassLoader.defineClass
, return the stub APIs to ensure correctnessAfter these steps are done, the remapping should be good. Please point out other edge cases.
A way to test such remapping may be testing with bukkit plugins like protocollib which uses bytebuddy (that reflects to get
ClassLoader.defineClass
). Other plugins using reflection may be good targets to test against as well.The text was updated successfully, but these errors were encountered: