Skip to content

Commit 8652ceb

Browse files
authored
fix: commodore class remap on latest spigot versions (#1535)
### Motivation Spigot made a change to Commodore a few days ago (merged into paper yesterday) that made the `Commodore#convert` non-static. Therefore our current transformer for the class fails as it tries to return the slot 0 (which, when the method is static, is the first argument) which now is the Commodore instance. ### Modification Check if the method being transformed is static and return slot 0 in that case, if the method is not static return slot 1. In both constellations the first argument of the convert method, the raw input class bytes, is returned. ### Result Latest Spigot/Paper Services no longer crash due to a bad stack frame.
1 parent 4370add commit 8652ceb

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

wrapper-jvm/src/main/java/eu/cloudnetservice/wrapper/transform/bukkit/BukkitCommodoreTransformer.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
import java.lang.classfile.ClassTransform;
2121
import java.lang.classfile.CodeBuilder;
2222
import java.lang.classfile.CodeElement;
23+
import java.lang.classfile.CodeModel;
2324
import java.lang.classfile.CodeTransform;
25+
import java.lang.reflect.AccessFlag;
2426
import java.util.ArrayDeque;
2527
import java.util.Deque;
2628
import lombok.NonNull;
@@ -94,6 +96,15 @@ public void accept(@NonNull CodeBuilder builder, @NonNull CodeElement element) {
9496
*/
9597
@Override
9698
public void atEnd(@NonNull CodeBuilder builder) {
99+
// get if the method we're transforming is static or not, this changed in 1.21.1
100+
// if the method is non-static we need to load a different slot to get the raw bytecode
101+
// argument that was supplied to the method
102+
// see https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/commits/0a7bd6c81a33cfaaa2f4d2456c6b237792f38fe6
103+
var methodModel = builder.original()
104+
.flatMap(CodeModel::parent)
105+
.orElseThrow(() -> new IllegalStateException("original method not preset on remap"));
106+
var transformMethodIsStatic = methodModel.flags().has(AccessFlag.STATIC);
107+
97108
// inserts a try block using the captured instructions that are in the original method
98109
// inserts a no-op catch block & a return instruction after the catch block to return the raw input data
99110
// this is needed as sometimes there are labels generated after the last return instruction in the
@@ -106,7 +117,8 @@ public void atEnd(@NonNull CodeBuilder builder) {
106117
this.methodElements::forEach,
107118
catchBuilder -> catchBuilder.catchingAll(_ -> {
108119
}))
109-
.aload(0).areturn();
120+
.aload(transformMethodIsStatic ? 0 : 1)
121+
.areturn();
110122
}
111123
}
112124
}

0 commit comments

Comments
 (0)