-
-
Notifications
You must be signed in to change notification settings - Fork 213
Description
I'm running into some issues where (as far as I can tell) 6f5dce1#diff-4bd581bd3412aebda2607dc2b9421fe52b2788cc301ca7049a3bcfeb1b1d035cL203 breaks some LVT sensitive uses such as https://github.com/MoriyaShiine/bewitchment/blob/1.16/src/main/java/moriyashiine/bewitchment/mixin/transformation/PlayerEntityMixin.java#L261 .
This example target method features a float in the descriptor, two float variables before the mixin at-location and a F_NEW frame between the variables and the at-location: FSTORE FSTORE F_NEW <at-loc>. The F_NEW frame moves those variables out of (JVM) scope by resetting the locals to only the method parameters. Older Mixin versions use the variables defined in the frame, where the only float is the method parameter, latest Mixin appears to include the two floats that went out of scope.
The example case breaks implicit LV selection (1 float -> 3 floats = ambiguous = InvalidImplicitDiscriminatorException), explicit specification with ordinal could easily start referencing the wrong LV slot in other cases. From my reading of the Mixin code it would treat F_CHOP differently from F_NEW even if both resulted in the same frame state.
Now since this is almost too easy, another case at https://github.com/Juuxel/Adorn/blob/1.16.5/src/main/java/juuxel/adorn/mixin/BubbleColumnBlockMixin.java#L25 does apparently quite the opposite. The target method features two returns, one with the requests LV in scope, the other without (F_NEW clears all locals before 2nd IRETURN). Old Mixin doesn't care, new Mixin can't find the out of scope local.
Since Mixin uses COMPUTE_FRAMES, it can and does resurrect out of scope LVs (at least some? uninit likely breaks) in some cases.
For a mod loader the problem is quite difficult to tackle, the mods can't be updated reasonably, even less so with retro packs that are otherwise perfectly compatible with the latest loader version. The status quo looks to remain inconsistent as the above examples exhibit opposite behaviors, indicating another incompatible change is in order.
Are LV references supposed to work off the frames, the entirety of initialized LV slots (considering all branches, IMO the best option) or all LV slots including uninitialized (probably invalid)? How should one deal with these incompatibilities (I don't have a good answer there)?