Skip to content

Commit

Permalink
Fix capturing the wrong MatrixStack
Browse files Browse the repository at this point in the history
Ensures when fuzzed lambdas change descriptor calls to them do also
  • Loading branch information
Chocohead committed Jun 19, 2021
1 parent 4f7d40a commit 7597971
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 38 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ loader_version=0.10.8
fabric_version=0.31.0+1.16
fabric_asm_version=v2.2

mod_version = 1.11.2
mod_version = 1.11.3
maven_group = me.modmuss50
archives_base_name = optifabric
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ private void renderScreenPre(float tickDelta, long startTime, boolean tick, Call

@Inject(method = "render(FJZ)V", locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true,
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;render(Lnet/minecraft/client/util/math/MatrixStack;IIF)V", ordinal = 0))
private void renderScreenPre(float tickDelta, long startTime, boolean tick, CallbackInfo call, int mouseX, int mouseY, Window window, Matrix4f projection, MatrixStack matrices) {
private void renderScreenPre(float tickDelta, long startTime, boolean tick, CallbackInfo call, int mouseX, int mouseY, Window window, Matrix4f projection, MatrixStack modelView, MatrixStack matrices) {
renderScreenPre(tickDelta, startTime, tick, call, mouseX, mouseY, matrices);
}

Expand All @@ -41,7 +41,7 @@ private void renderScreenPost(float tickDelta, long startTime, boolean tick, Cal

@Inject(method = "render(FJZ)V", locals = LocalCapture.CAPTURE_FAILHARD,
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;render(Lnet/minecraft/client/util/math/MatrixStack;IIF)V", shift = Shift.AFTER, ordinal = 0))
private void renderScreenPost(float tickDelta, long startTime, boolean tick, CallbackInfo call, int mouseX, int mouseY, Window window, Matrix4f projection, MatrixStack matrices) {
private void renderScreenPost(float tickDelta, long startTime, boolean tick, CallbackInfo call, int mouseX, int mouseY, Window window, Matrix4f projection, MatrixStack modelView, MatrixStack matrices) {
renderScreenPost(tickDelta, startTime, tick, call, mouseX, mouseY, matrices);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ private void onBeforeRenderScreen(float tickDelta, long startTime, boolean tick,
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;render(Lnet/minecraft/client/util/math/MatrixStack;IIF)V", ordinal = 0),
locals = LocalCapture.CAPTURE_FAILHARD,
cancellable = true)
private void onBeforeRenderScreen(float tickDelta, long startTime, boolean tick, CallbackInfo call, int mouseX, int mouseY, Window window, Matrix4f projection, MatrixStack matrices) {
private void onBeforeRenderScreen(float tickDelta, long startTime, boolean tick, CallbackInfo call, int mouseX, int mouseY, Window window, Matrix4f projection, MatrixStack modelView, MatrixStack matrices) {
onBeforeRenderScreen(tickDelta, startTime, tick, call, mouseX, mouseY, matrices);
}

Expand All @@ -44,7 +44,7 @@ private void onAfterRenderScreen(float tickDelta, long startTime, boolean tick,
@Inject(method = "render(FJZ)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;render(Lnet/minecraft/client/util/math/MatrixStack;IIF)V", shift = Shift.AFTER, ordinal = 0),
locals = LocalCapture.CAPTURE_FAILHARD)
private void onAfterRenderScreen(float tickDelta, long startTime, boolean tick, CallbackInfo call, int mouseX, int mouseY, Window window, Matrix4f projection, MatrixStack matrices) {
private void onAfterRenderScreen(float tickDelta, long startTime, boolean tick, CallbackInfo call, int mouseX, int mouseY, Window window, Matrix4f projection, MatrixStack modelView, MatrixStack matrices) {
onAfterRenderScreen(tickDelta, startTime, tick, call, mouseX, mouseY, matrices);
}
}
67 changes: 35 additions & 32 deletions src/main/java/me/modmuss50/optifabric/patcher/StaticFuzzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.Map.Entry;
Expand Down Expand Up @@ -150,7 +148,7 @@ private void fix(Map<String, String> toCheck, ClassNode minecraft, ClassNode opt
memberToAccess.put(key, method.access);
}

Set<String> staticFlip = new HashSet<>();
Map<String, String> staticFlip = new HashMap<>();
for (MethodNode method : optifine.methods) {
String key = method.name.concat(method.desc);

Expand All @@ -159,48 +157,49 @@ private void fix(Map<String, String> toCheck, ClassNode minecraft, ClassNode opt
int access = memberToAccess.getInt(remap);
if (access == -1) throw new IllegalStateException("Unable to find vanilla method " + minecraft.name + '#' + remap);

if (Modifier.isStatic(method.access) != Modifier.isStatic(access)) {
if (Modifier.isPrivate(method.access)) {//We'll just locally fix the difference
staticFlip.add(key);
} else {
if (Modifier.isStatic(method.access)) {//Become static, previously wasn't
if (Modifier.isStatic(method.access) != Modifier.isStatic(access)) {
if (Modifier.isStatic(method.access)) {//Become static, previously wasn't
if (Modifier.isPrivate(method.access)) {
Type[] args = Type.getArgumentTypes(method.desc);

if (args.length >= 1 && optifine.name.equals(args[0].getInternalName())) {//Could we fix it quickly?
staticFlip.add(method.name.concat(method.desc));
} else {//Not really
System.err.println("Method has become static: " + optifine.name + '#' + key);
}
} else {//No longer static, previously was
System.err.println("Method is no longer static: " + optifine.name + '#' + key);
staticFlip.put(method.name.concat(method.desc), Type.getMethodDescriptor(Type.getReturnType(method.desc), Arrays.copyOfRange(args, 1, args.length)));
continue;
}
}

throw new UnsupportedOperationException("Method has become static: " + optifine.name + '#' + key);
} else {//No longer static, previously was
if (Modifier.isPrivate(method.access)) {//We'll add this as a parameter as we can fix all the uses
staticFlip.put(key, "(L" + optifine.name + ';' + method.desc.substring(1));
continue;
}

//More consequential fixes will be needed
throw new UnsupportedOperationException("Method is no longer static: " + optifine.name + '#' + key);
}
}
}

if (!staticFlip.isEmpty()) {
for (MethodNode method : optifine.methods) {
if (staticFlip.contains(method.name.concat(method.desc))) {
if (Modifier.isStatic(method.access ^= Modifier.STATIC)) {//Method made static, need to add this as a parameter
method.desc = "(L" + optifine.name + ';' + method.desc.substring(1);
} else {//Method no longer static, need to add a this somehow
Type[] args = Type.getArgumentTypes(method.desc);

if (args.length >= 1 && optifine.name.equals(args[0].getInternalName())) {//Just remove the leading type argument
method.desc = Type.getMethodDescriptor(Type.getReturnType(method.desc), Arrays.copyOfRange(args, 1, args.length));
} else {//More of a nuisance, all the LVT indices will need bumping up by one
throw new UnsupportedOperationException("Removing static from " + optifine.name + '#' + method.name + method.desc + " is a bit more effort");
}
}
String newDesc = staticFlip.get(method.name.concat(method.desc));
if (newDesc != null) {
method.access ^= Modifier.STATIC;
method.desc = newDesc;
}

for (AbstractInsnNode insn : method.instructions) {
switch (insn.getType()) {
case AbstractInsnNode.METHOD_INSN: {
MethodInsnNode minsn = (MethodInsnNode) insn;

if (optifine.name.equals(minsn.owner) && staticFlip.contains(minsn.name.concat(minsn.desc))) {
minsn.setOpcode(minsn.getOpcode() == Opcodes.INVOKESTATIC ? Opcodes.INVOKEVIRTUAL : Opcodes.INVOKESTATIC);
if (optifine.name.equals(minsn.owner)) {
newDesc = staticFlip.get(minsn.name.concat(minsn.desc));
if (newDesc != null) {
minsn.setOpcode(minsn.getOpcode() == Opcodes.INVOKESTATIC ? Opcodes.INVOKEVIRTUAL : Opcodes.INVOKESTATIC);
minsn.desc = newDesc;
}
}
break;
}
Expand All @@ -210,9 +209,13 @@ private void fix(Map<String, String> toCheck, ClassNode minecraft, ClassNode opt

if (MethodComparison.isJavaLambdaMetafactory(dinsn.bsm)) {
Handle lambda = (Handle) dinsn.bsmArgs[1];
if (optifine.name.equals(lambda.getOwner()) && staticFlip.contains(lambda.getName().concat(lambda.getDesc()))) {
dinsn.bsmArgs[1] = new Handle(lambda.getTag() == Opcodes.H_INVOKESTATIC ? Opcodes.H_INVOKEVIRTUAL : Opcodes.H_INVOKESTATIC,
lambda.getOwner(), lambda.getName(), lambda.getDesc(), lambda.isInterface());

if (optifine.name.equals(lambda.getOwner())) {
newDesc = staticFlip.get(lambda.getName().concat(lambda.getDesc()));
if (newDesc != null) {
dinsn.bsmArgs[1] = new Handle(lambda.getTag() == Opcodes.H_INVOKESTATIC ? Opcodes.H_INVOKEVIRTUAL : Opcodes.H_INVOKESTATIC,
lambda.getOwner(), lambda.getName(), newDesc, lambda.isInterface());
}
}
}
break;
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"fabric-renderer-indigo:force_compatibility" : true
},
"depends": {
"fabricloader": ">=0.8.0",
"fabricloader": ">=0.8.0 <0.12",
"minecraft": ["1.16.1", "1.16.2", "1.16.3", "1.16.4", "1.16.5", "1.17-alpha.21.8.b", "1.17-beta.4", "1.17"],
"mm": ">=2.0"
},
Expand Down

0 comments on commit 7597971

Please sign in to comment.