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

Bump mixin from 0.7.10-SNAPSHOT to 0.8.5 #177

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

dependabot[bot]
Copy link

@dependabot dependabot bot commented on behalf of github Dec 2, 2021

Bumps mixin from 0.7.10-SNAPSHOT to 0.8.5.

Release notes

Sourced from mixin's releases.

Mixin 0.8.4

Sometimes new Mixin releases present an opportunity to discuss different aspects of Mixin which are not covered in detail in the docs, or limitations which exist are not well understood by mixin authors, leading them to experience behaviour they aren't anticipating. The topic of the 0.8 series has definitely bounced around the topic of Locals, in particular CallbackInjector's unique ability to capture locals, so I will discuss some of the changes to Locals later in these notes. But first, the headlines:

Features

Minecraft 1.17, ModLauncher 9, Java 16, Oh My!

Minecraft 1.17 represents a significant jump in technology, adopting as it does Java 16, a big jump from the previous Java 8. Those in the modding community who remember the jump to Java 8 from Java 6 will anticipate something of what that means. Mixin has been for some time rooted in that Java 8 land because the primary consumers are using Java 8 and and (in some cases) Java 6, so supporting newer language features hasn't been a high priority.

With the release of Mixin 0.8.4, the core functionality of Mixin now supports up to Java 13 (cheating a little since nothing of note changed between Java 11 and 13), the missing piece of the puzzle being nesting. Mixins applied to inner classes will now be properly added to the existing nest.

The internal version of ASM has been bumped to 9.x to track ModLauncher, which now provides access to class version literals up to Java 18, which have been duly contributed to the CompatibilityLevel enum, along with associated language feature flags. Records and sealed classes are now on the radar for support, but will not be immediately available as things are ahead of them in the feature queue.

Mixin itself is now built as as Java module, though classes in the final jar will still be compatible back as far as Java 8 without modification, Java 6 users will still need to compile from source.

Fixes and Improvements

Besides the internal restructuring to support Java 16 and ModLauncher 9, this release is primarily aimed at addressing some regressions introduced in version 0.8.3. One of my primary goals with Mixin is to make a library with stable, predictable behaviour - at least where this can be reasonably asserted - and some regressions in 0.8.3 I felt breached this threshold of acceptable change.

Version 0.8.4 does still bring some changes to the table, but the scope - and type - of these changes are now much more manageable with respect to 0.8.2.

Mixin 0.8.4 therefore represents the "what 0.8.3 should have been" release, and offers the promised improvements of the previous release, with fewer gotchas. Check out the release notes for 0.8.3 if you haven't already, as they cover the major changes and bugfixes since 0.8.2.

Local Variables in Mixins

This brings us on to the bonus topic of today's release notes: Locals.

Support for interacting with local variables has a long and storied past and has, during its tenure, overcome such obstactles as differing output from ASM in production vs. development. Yielding different results across different versions and platforms for ostensibly the same code. Failing to expose locals which seem intuitively in-scope at the capture point, and exposing others which shouldn't be. Accidentally capturing locals added by Mixin itself. The list goes on. I can say that the 0.8 series of Mixin definitely represents a high point in the general functionality of local capture.

Those who have been on board the Mixin train for a long time have observed the growing pains of locals and treat it with the air of an unexploded bomb which might detonate at any moment, and they are justified in doing so. However I realise that I have been negligent in assuming that this feeling prevails and therefore failing to provide the appropriate caveats and warnings around the use of locals. This is especially true recently since the state of Locals is objectively quite good, and belies the dangers of change over time that still lurk beneath the surface.

So why, if it's in such a good place, does it need to change at all?

I have two main goals for Locals in the long run:

  • Reveal locals that are intuitively in scope from the mixin author's perspective
  • Provide stable results even across different platforms and versions, for code which appears to change. Eg. reduce sensitivity to binary-level changes
  • Do all this with reasonable efficiency, eg. avoid going full-blown analytical decompiler, make an algorithm the works predictably even if it's not perfect

The reason for the first should be obvious, authors of mixins should have a reasonable expectation of being able to capture variables which appear to be in-scope based on reading the decompiled source. This reduces development effort and makes for a better experience.

The second goal is the reason that things are still changing: reducing binary sensitivity is a tricky thing to achieve given that it conflicts with the third goal somewhat, this is where tuning the algorithm comes into play.

The algorithm used by Locals does a relatively simple scan of target methods from top to bottom, weaving knowledge gained from the LVT (either explicit or computed), the stack map frames, and LOAD and STORE opcodes in the method itself together to create a not unreasonable view of the available local variables at any point in the method. However, the weight given to different information sources is where the tunables come in, as the entire algorithm is essentially a hueristic which tries to blend sometimes conflicting accounts of what is available and where.

If you're wondering why on earth different aspects of the method structure would disagree, and why there is no "universal truth" that can be easily reverse engineered from simply reading the bytecode, it's important to understand that no part of the runtime actually needs to know the information we're after, and the different mechanims in the bytecode (the instructions, the LVT and the stack map frames) have entirely different goals. The LVT is the closest thing we have to truth, and it's not even required at runtime since it's purely used for debugging. In fact in older versions of the game the LVT was stripped, and even to this day it is obfuscated.

Where am I going with this?

As I said above, Locals is in quite a good place right now, but tweaks and changes may still occur. This means that using Locals in a defensive manner is still - for the time being - important. The end goal is to achieve a level of repeatability between versions, platforms and binary changes that can provide a sense that captured locals will change when the code changes, in other words converging with the general contract of injectors as a whole.

... (truncated)

Commits

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot merge will merge this PR after your CI passes on it
  • @dependabot squash and merge will squash and merge this PR after your CI passes on it
  • @dependabot cancel merge will cancel a previously requested merge and block automerging
  • @dependabot reopen will reopen this PR if it is closed
  • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [mixin](https://github.com/SpongePowered/Mixin) from 0.7.10-SNAPSHOT to 0.8.5.
- [Release notes](https://github.com/SpongePowered/Mixin/releases)
- [Commits](https://github.com/SpongePowered/Mixin/commits/releases/0.8.5)

---
updated-dependencies:
- dependency-name: org.spongepowered:mixin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
@dependabot dependabot bot added the dependencies Pull requests that update a dependency file label Dec 2, 2021
@dependabot dependabot bot requested a review from josephworks December 2, 2021 04:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dependencies Pull requests that update a dependency file
Projects
None yet
Development

Successfully merging this pull request may close these issues.

0 participants