Closed stephan-gh closed 7 years ago
Yeah this has reared it's head multiple times in the past for various reasons, and it's usually a function of one of:
"Enhanced for" loops in Java are a pretty sticky one because they are normally decompiled to an iterator, so it's actually likely that the production one is "correct", for example if in the original code the two locals astring
and s2
don't exist or are initialised inside the foreach
loop, but the compiler optimises them outside the loop (putting them later in the locals table but earlier in the code) would be a totally plausible reason for that to happen).
Going to need to look into this in detail, as it's one of the most problematic things I've encountered to date and this looks like yet another corner case to deal with, yay funtimes. With luck it might be fixable by leaving the surrogate in place but just changing the injection logic to use new locals slots instead of reusing them like the current injector does.
Injection point: MinecraftServer.getTabCompletions on Minecraft 1.11 (see link for exact injection point).
Trying to inject at the first return with local variable capture results in two different signatures in the IDE and in production:
[Ljava/util/List;, Z, [Ljava/lang/String;, Ljava/lang/String;]
(correct)[Ljava/util/List;, Z, Ljava/util/List;, Ljava/util/Iterator;]
If I add an
@Inject
and a@Surrogate
for both signatures it works fine in the IDE. However, in production, it throws ajava.lang.VerifyError: Bad local variable type
.Full error: https://gist.github.com/Minecrell/ca35a3aa503c73265416f92ee8675876
Injector:
Is Mixin detecting something wrong here? It seems like the error occurs because Mixin is trying to assign a variable with a wrong type.