diff --git a/gradle.properties b/gradle.properties index 9f073668..6130fb87 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ packaging=jar description=Mixin (LegacyModdingMC fork) url=https://github.com/LegacyModdingMC organization=LegacyModdingMC -buildVersion=0.15.0 +buildVersion=0.15.3 upstreamMixinVersion=0.8.7 buildType=RELEASE asmVersion=9.6 diff --git a/src/main/java/org/spongepowered/asm/mixin/MixinEnvironment.java b/src/main/java/org/spongepowered/asm/mixin/MixinEnvironment.java index 3c963397..17c1151e 100644 --- a/src/main/java/org/spongepowered/asm/mixin/MixinEnvironment.java +++ b/src/main/java/org/spongepowered/asm/mixin/MixinEnvironment.java @@ -1080,7 +1080,17 @@ static String getSupportedVersions() { } return sb.toString(); } - + + public static CompatibilityLevel forClassVersion(int version) { + CompatibilityLevel latest = null; + for (CompatibilityLevel level : values()) { + if (level.getClassVersion() >= version) { + return level; + } + latest = level; + } + return latest; + } } /** diff --git a/src/main/java/org/spongepowered/asm/mixin/injection/points/BeforeNew.java b/src/main/java/org/spongepowered/asm/mixin/injection/points/BeforeNew.java index 14850b2d..845d6e78 100644 --- a/src/main/java/org/spongepowered/asm/mixin/injection/points/BeforeNew.java +++ b/src/main/java/org/spongepowered/asm/mixin/injection/points/BeforeNew.java @@ -118,7 +118,7 @@ public BeforeNew(InjectionPointData data) { } ITargetSelectorConstructor targetSelector = (ITargetSelectorConstructor)member; this.target = targetSelector.toCtorType(); - this.desc = org.spongepowered.asm.mixin.FabricUtil.getCompatibility(data.getContext()) >= org.spongepowered.asm.mixin.FabricUtil.COMPATIBILITY_0_14_0 ? targetSelector.toCtorDesc() : null; + this.desc = targetSelector.toCtorDesc(); } /** diff --git a/src/main/java/org/spongepowered/asm/mixin/injection/struct/Constructor.java b/src/main/java/org/spongepowered/asm/mixin/injection/struct/Constructor.java index 943edadf..615b6c28 100644 --- a/src/main/java/org/spongepowered/asm/mixin/injection/struct/Constructor.java +++ b/src/main/java/org/spongepowered/asm/mixin/injection/struct/Constructor.java @@ -113,10 +113,6 @@ public void inspect(Initialiser initialiser) { for (AbstractInsnNode initialiserInsn : initialiser.getInsns()) { if (initialiserInsn.getOpcode() == Opcodes.PUTFIELD) { - FieldInsnNode fieldInsn = (FieldInsnNode)initialiserInsn; - if (!fieldInsn.owner.equals(this.targetName)) { - continue; - } this.mixinInitialisedFields.add(Constructor.fieldKey((FieldInsnNode)initialiserInsn)); } } diff --git a/src/main/java/org/spongepowered/asm/mixin/injection/struct/Target.java b/src/main/java/org/spongepowered/asm/mixin/injection/struct/Target.java index 912b833e..87f44b56 100644 --- a/src/main/java/org/spongepowered/asm/mixin/injection/struct/Target.java +++ b/src/main/java/org/spongepowered/asm/mixin/injection/struct/Target.java @@ -44,6 +44,7 @@ import org.spongepowered.asm.mixin.transformer.ClassInfo; import org.spongepowered.asm.util.Bytecode; import org.spongepowered.asm.util.Constants; +import org.spongepowered.asm.util.Counter; import org.spongepowered.asm.util.Locals.SyntheticLocalVariableNode; /** @@ -460,12 +461,17 @@ public int[] generateArgMap(Type[] args, int start, boolean fresh) { if (this.argMapVars == null) { this.argMapVars = new ArrayList(); } - + int[] argMap = new int[args.length]; - for (int arg = start, index = 0; arg < args.length; arg++) { + Counter index = new Counter(); + for (int arg = start; arg < args.length; arg++) { int size = args[arg].getSize(); - argMap[arg] = fresh ? this.allocateLocals(size) : this.allocateArgMapLocal(index, size); - index += size; + if (fresh) { + argMap[arg] = this.allocateLocals(size); + index.value += size; + } else { + argMap[arg] = this.allocateArgMapLocal(index, size); + } } return argMap; } @@ -481,35 +487,40 @@ public int[] generateArgMap(Type[] args, int start, boolean fresh) { * @param size Size of variable * @return local offset to use */ - private int allocateArgMapLocal(int index, int size) { - // Allocate extra space if we've reached the end - if (index >= this.argMapVars.size()) { - int base = this.allocateLocals(size); - for (int offset = 0; offset < size; offset++) { - this.argMapVars.add(Integer.valueOf(base + offset)); + private int allocateArgMapLocal(Counter index, int size) { + boolean isLastSlotFree = index.value < this.argMapVars.size(); + while (index.value < this.argMapVars.size()) { + int local = this.argMapVars.get(index.value); + if (size == 1) { + index.value++; + return local; } - return base; - } - - int local = this.argMapVars.get(index); - - // Allocate extra space if the variable is oversize - if (size > 1 && index + size > this.argMapVars.size()) { - int nextLocal = this.allocateLocals(1); - if (nextLocal == local + 1) { - // Next allocated was contiguous, so we can continue - this.argMapVars.add(Integer.valueOf(nextLocal)); + int nextIndex = index.value + 1; + if (nextIndex < this.argMapVars.size() && local + 1 == this.argMapVars.get(nextIndex)) { + // We own the next slot so this is a safe place to store a double-width type. + // We've consumed the next slot so increment the next available index. + index.value += 2; return local; } - - // Next allocated was not contiguous, allocate a new local slot so - // that indexes are contiguous - this.argMapVars.set(index, Integer.valueOf(nextLocal)); - this.argMapVars.add(Integer.valueOf(this.allocateLocals(1))); - return nextLocal; + index.value++; } - - return local; + // We don't have anywhere to store the arg. + int newLocal = this.allocateLocal(); + this.argMapVars.add(newLocal); + index.value++; + if (size == 1) { + return newLocal; + } + if (isLastSlotFree && newLocal == this.argMapVars.get(this.argMapVars.size() - 2) + 1) { + // We own the preceding local as well, and it is not yet used by this argMap, so we can store our + // double-width type there. + return newLocal - 1; + } + // Allocate 1 more local so we can fit the double-width type. We know it will follow directly from the + // previous one. + this.argMapVars.add(this.allocateLocal()); + index.value++; + return newLocal; } /** diff --git a/src/main/java/org/spongepowered/asm/mixin/transformer/MixinApplicatorInterface.java b/src/main/java/org/spongepowered/asm/mixin/transformer/MixinApplicatorInterface.java index 99aec8db..830736ff 100644 --- a/src/main/java/org/spongepowered/asm/mixin/transformer/MixinApplicatorInterface.java +++ b/src/main/java/org/spongepowered/asm/mixin/transformer/MixinApplicatorInterface.java @@ -24,12 +24,10 @@ */ package org.spongepowered.asm.mixin.transformer; -import java.lang.reflect.Modifier; import java.util.Map.Entry; import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.MethodNode; -import org.spongepowered.asm.mixin.MixinEnvironment; import org.spongepowered.asm.mixin.MixinEnvironment.Feature; import org.spongepowered.asm.mixin.injection.struct.InjectionInfo; import org.spongepowered.asm.mixin.injection.throwables.InvalidInjectionException; @@ -37,7 +35,6 @@ import org.spongepowered.asm.mixin.transformer.throwables.InvalidInterfaceMixinException; import org.spongepowered.asm.util.Annotations; import org.spongepowered.asm.util.Constants; -import org.spongepowered.asm.util.LanguageFeatures; /** * Applicator for interface mixins, mainly just disables things which aren't @@ -166,17 +163,4 @@ protected void applyInjections(MixinTargetContext mixin, int injectorOrder) { return; } } - - @Override - protected void checkMethodVisibility(MixinTargetContext mixin, MethodNode mixinMethod) { - //Allow injecting into static interface methods where it isn't possible to control the access of the injection method - if (Modifier.isStatic(mixinMethod.access) && !MixinEnvironment.getCompatibilityLevel().supports(LanguageFeatures.PRIVATE_METHODS_IN_INTERFACES)) { - InjectionInfo injectInfo = InjectionInfo.parse(mixin, mixinMethod); - if (injectInfo != null) { - return; - } - } - - super.checkMethodVisibility(mixin, mixinMethod); - } } diff --git a/src/main/java/org/spongepowered/asm/mixin/transformer/MixinInfo.java b/src/main/java/org/spongepowered/asm/mixin/transformer/MixinInfo.java index 980bcd26..41701876 100644 --- a/src/main/java/org/spongepowered/asm/mixin/transformer/MixinInfo.java +++ b/src/main/java/org/spongepowered/asm/mixin/transformer/MixinInfo.java @@ -1268,6 +1268,10 @@ List getTargets() { Set getInterfaces() { return this.getState().getInterfaces(); } + + int getClassVersion() { + return this.getState().getClassNode().version; + } /** * Get transformer extensions diff --git a/src/main/java/org/spongepowered/asm/mixin/transformer/MixinPreProcessorInterface.java b/src/main/java/org/spongepowered/asm/mixin/transformer/MixinPreProcessorInterface.java index a01aa57f..ae17ed22 100644 --- a/src/main/java/org/spongepowered/asm/mixin/transformer/MixinPreProcessorInterface.java +++ b/src/main/java/org/spongepowered/asm/mixin/transformer/MixinPreProcessorInterface.java @@ -108,10 +108,11 @@ protected void prepareMethod(MixinMethodNode mixinMethod, Method method) { method, this.mixin)); } - // Make injectors private synthetic if the current runtime supports it + CompatibilityLevel classLevel = CompatibilityLevel.forClassVersion(mixin.getClassVersion()); + // Make injectors private synthetic if the current class version supports it if (isPublic - && !currentLevel.supports(LanguageFeatures.PRIVATE_METHODS_IN_INTERFACES) - && currentLevel.supports(LanguageFeatures.PRIVATE_SYNTHETIC_METHODS_IN_INTERFACES)) { + && !classLevel.supports(LanguageFeatures.PRIVATE_METHODS_IN_INTERFACES) + && classLevel.supports(LanguageFeatures.PRIVATE_SYNTHETIC_METHODS_IN_INTERFACES)) { Bytecode.setVisibility(mixinMethod, Bytecode.Visibility.PRIVATE); mixinMethod.access |= Opcodes.ACC_SYNTHETIC; }