aboutsummaryrefslogtreecommitdiff
path: root/agent/src/main/java/moe/nea
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2024-06-20 02:48:38 +0200
committerLinnea Gräf <nea@nea.moe>2024-06-20 02:48:38 +0200
commit5593488744dc5aa994b5ab2806ed56d7bc627368 (patch)
tree9d8701474adbd0ce3d51c3f2b92e7ed5724b02a7 /agent/src/main/java/moe/nea
parentcb08a83e7a0f82f2459da7cb93b8c327b29d9838 (diff)
downloadModernJavaLauncher-master.tar.gz
ModernJavaLauncher-master.tar.bz2
ModernJavaLauncher-master.zip
Modernize some stuff idkHEADmaster
Diffstat (limited to 'agent/src/main/java/moe/nea')
-rw-r--r--agent/src/main/java/moe/nea/modernjava/agent/LenientType.java34
-rw-r--r--agent/src/main/java/moe/nea/modernjava/agent/Pack200Retransformer.java90
2 files changed, 95 insertions, 29 deletions
diff --git a/agent/src/main/java/moe/nea/modernjava/agent/LenientType.java b/agent/src/main/java/moe/nea/modernjava/agent/LenientType.java
new file mode 100644
index 0000000..88462f3
--- /dev/null
+++ b/agent/src/main/java/moe/nea/modernjava/agent/LenientType.java
@@ -0,0 +1,34 @@
+package moe.nea.modernjava.agent;
+
+import org.objectweb.asm.Type;
+
+public class LenientType {
+ /**
+ * {@link Type#getType(String)}, but implementing the old lenient behaviour.
+ * This deviates from the old behaviour in that it defaults to creating an object,
+ * instead of a method, but this is generally the desired behaviour.
+ */
+ public static Type getType(String typeDescriptor) {
+ char c = 0;
+ if (!typeDescriptor.isEmpty()) {
+ c = typeDescriptor.charAt(0);
+ }
+ switch (c) {
+ case 'V':
+ case 'Z':
+ case 'C':
+ case 'B':
+ case 'S':
+ case 'I':
+ case 'F':
+ case 'J':
+ case 'D':
+ case '[':
+ case 'L':
+ case '(':
+ return Type.getType(typeDescriptor);
+ default:
+ return Type.getObjectType(typeDescriptor);
+ }
+ }
+}
diff --git a/agent/src/main/java/moe/nea/modernjava/agent/Pack200Retransformer.java b/agent/src/main/java/moe/nea/modernjava/agent/Pack200Retransformer.java
index 67480bf..4d31329 100644
--- a/agent/src/main/java/moe/nea/modernjava/agent/Pack200Retransformer.java
+++ b/agent/src/main/java/moe/nea/modernjava/agent/Pack200Retransformer.java
@@ -3,6 +3,9 @@ package moe.nea.modernjava.agent;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
import org.objectweb.asm.commons.ClassRemapper;
import org.objectweb.asm.commons.Remapper;
@@ -20,33 +23,62 @@ import java.util.List;
* but the java agent is far more reliable.
*/
public class Pack200Retransformer implements ClassFileTransformer {
- // relocate("dev.architectury.pack200.java", "java.util.jar")
- List<String> classes = Arrays.asList("AdaptiveCoding", "Attribute", "BandStructure", "ClassReader", "ClassWriter", "Code", "Coding", "CodingChooser", "CodingMethod", "ConstantPool", "Constants", "Driver", "DriverResource", "DriverResource_ja", "DriverResource_zh_CN", "FixedList", "Fixups", "Histogram", "Instruction", "NativeUnpack", "Pack200", "Pack200Adapter", "Pack200Plugin", "Package", "PackageReader", "PackageWriter", "PackerImpl", "PopulationCoding", "PropMap", "TLGlobals", "UnpackerImpl", "Utils");
- String architecturyPackage = "dev/architectury/pack200/java/";
- String javaPackage = "java/util/jar/";
-
- public static void premain(String agentArgs, Instrumentation inst) {
- inst.addTransformer(new Pack200Retransformer());
- }
-
- @Override
- public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
- ClassReader reader = new ClassReader(classfileBuffer);
- ClassWriter writer = new ClassWriter(reader, 0);
- Remapper remapper = new Remapper() {
- @Override
- public String map(String internalName) {
- if (internalName.startsWith(javaPackage)) {
- for (String aClass : classes) {
- if (internalName.equals(javaPackage + aClass) || (internalName.startsWith(javaPackage + aClass + "$")))
- return internalName.replace(javaPackage, architecturyPackage);
- }
- }
- return internalName;
- }
- };
- ClassVisitor visitor = new ClassRemapper(writer, remapper);
- reader.accept(visitor, 0);
- return writer.toByteArray();
- }
+ // relocate("dev.architectury.pack200.java", "java.util.jar")
+ List<String> classes = Arrays.asList("AdaptiveCoding", "Attribute", "BandStructure", "ClassReader", "ClassWriter", "Code", "Coding", "CodingChooser", "CodingMethod", "ConstantPool", "Constants", "Driver", "DriverResource", "DriverResource_ja", "DriverResource_zh_CN", "FixedList", "Fixups", "Histogram", "Instruction", "NativeUnpack", "Pack200", "Pack200Adapter", "Pack200Plugin", "Package", "PackageReader", "PackageWriter", "PackerImpl", "PopulationCoding", "PropMap", "TLGlobals", "UnpackerImpl", "Utils");
+ String architecturyPackage = "dev/architectury/pack200/java/";
+ String javaPackage = "java/util/jar/";
+
+ public static void premain(String agentArgs, Instrumentation inst) {
+ inst.addTransformer(new Pack200Retransformer());
+ }
+
+ @Override
+ public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) {
+ if (className.startsWith("moe/nea/modernjava/agent")) return classfileBuffer;
+ ClassReader reader = new ClassReader(classfileBuffer);
+ ClassWriter writer = new ClassWriter(reader, 0);
+ ClassVisitor visitor = writer;
+ visitor = getRemapVisitor(visitor);
+ visitor = getTypeVisitor(className, visitor);
+ reader.accept(visitor, 0);
+ return writer.toByteArray();
+ }
+
+ private ClassVisitor getRemapVisitor(ClassVisitor parent) {
+ Remapper remapper = new Remapper() {
+ @Override
+ public String map(String internalName) {
+ if (internalName.startsWith(javaPackage)) {
+ for (String aClass : classes) {
+ if (internalName.equals(javaPackage + aClass) || (internalName.startsWith(javaPackage + aClass + "$")))
+ return internalName.replace(javaPackage, architecturyPackage);
+ }
+ }
+ return internalName;
+ }
+ };
+ return new ClassRemapper(parent, remapper);
+ }
+
+ private ClassVisitor getTypeVisitor(String className, ClassVisitor parent) {
+ if (className.startsWith("org/objectweb/asm/")) return parent;
+ return new ClassVisitor(Opcodes.ASM9, parent) {
+ @Override
+ public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
+ return new MethodVisitor(Opcodes.ASM9, super.visitMethod(access, name, descriptor, signature, exceptions)) {
+ @Override
+ public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
+ boolean isType = owner.equals("org/objectweb$/asm/Type".replace("$",""));
+ boolean isName = "getType".equals(name);
+ boolean isDesc = "(Ljava/lang/String;)Lorg/objectweb/asm/Type;".equals(descriptor);
+ if (isType && isName && isDesc) {
+ owner = Type.getInternalName(LenientType.class);
+ }
+ super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+
+ }
+ };
+ }
+ };
+ }
}