diff --git a/asm/src/main/java/dev/openrs2/asm/ClassNodeRemapper.kt b/asm/src/main/java/dev/openrs2/asm/ClassNodeRemapper.kt new file mode 100644 index 00000000..99195ef9 --- /dev/null +++ b/asm/src/main/java/dev/openrs2/asm/ClassNodeRemapper.kt @@ -0,0 +1,86 @@ +package dev.openrs2.asm + +import org.objectweb.asm.commons.Remapper +import org.objectweb.asm.tree.AbstractInsnNode +import org.objectweb.asm.tree.ClassNode +import org.objectweb.asm.tree.FieldInsnNode +import org.objectweb.asm.tree.FrameNode +import org.objectweb.asm.tree.InvokeDynamicInsnNode +import org.objectweb.asm.tree.LdcInsnNode +import org.objectweb.asm.tree.MethodInsnNode +import org.objectweb.asm.tree.MultiANewArrayInsnNode +import org.objectweb.asm.tree.TypeInsnNode + +fun ClassNode.remap(remapper: Remapper) { + val originalName = name + name = remapper.mapType(originalName) + signature = remapper.mapSignature(signature, false) + superName = remapper.mapType(superName) + + if (interfaces != null) { + interfaces = interfaces.map(remapper::mapType) + } + + for (field in fields) { + field.name = remapper.mapFieldName(originalName, field.name, field.desc) + field.desc = remapper.mapDesc(field.desc) + field.signature = remapper.mapSignature(field.signature, true) + + if (field.value != null) { + field.value = remapper.mapValue(field.value) + } + } + + for (method in methods) { + method.name = remapper.mapMethodName(originalName, method.name, method.desc) + method.desc = remapper.mapMethodDesc(method.desc) + method.signature = remapper.mapSignature(method.signature, false) + + method.exceptions = method.exceptions.map(remapper::mapType) + + if (method.hasCode()) { + ClassForNameUtils.remap(remapper, method) + + for (insn in method.instructions) { + insn.remap(remapper) + } + + for (tryCatch in method.tryCatchBlocks) { + tryCatch.type = remapper.mapType(tryCatch.type) + } + } + } +} + +private fun Remapper.mapFrameType(type: Any): Any { + return if (type is String) { + mapType(type) + } else { + type + } +} + +private fun AbstractInsnNode.remap(remapper: Remapper) { + when (this) { + is FrameNode -> { + local = local.map(remapper::mapFrameType) + stack = stack.map(remapper::mapFrameType) + } + is FieldInsnNode -> { + val originalOwner = owner + owner = remapper.mapType(originalOwner) + name = remapper.mapFieldName(originalOwner, name, desc) + desc = remapper.mapDesc(desc) + } + is MethodInsnNode -> { + val originalOwner = owner + owner = remapper.mapType(originalOwner) + name = remapper.mapMethodName(originalOwner, name, desc) + desc = remapper.mapDesc(desc) + } + is InvokeDynamicInsnNode -> throw UnsupportedOperationException() + is TypeInsnNode -> desc = remapper.mapType(desc) + is LdcInsnNode -> cst = remapper.mapValue(cst) + is MultiANewArrayInsnNode -> desc = remapper.mapType(desc) + } +} diff --git a/asm/src/main/java/dev/openrs2/asm/classpath/Library.kt b/asm/src/main/java/dev/openrs2/asm/classpath/Library.kt index 204adf12..36e7eff6 100644 --- a/asm/src/main/java/dev/openrs2/asm/classpath/Library.kt +++ b/asm/src/main/java/dev/openrs2/asm/classpath/Library.kt @@ -1,14 +1,12 @@ package dev.openrs2.asm.classpath import com.github.michaelbull.logging.InlineLogger -import dev.openrs2.asm.ClassForNameUtils -import dev.openrs2.asm.hasCode +import dev.openrs2.asm.remap import dev.openrs2.common.crypto.Pkcs12KeyStore import dev.openrs2.common.io.DeterministicJarOutputStream import dev.openrs2.common.io.SkipOutputStream import org.objectweb.asm.ClassReader import org.objectweb.asm.ClassWriter -import org.objectweb.asm.commons.ClassRemapper import org.objectweb.asm.commons.Remapper import org.objectweb.asm.tree.ClassNode import org.objectweb.asm.util.CheckClassAdapter @@ -17,7 +15,6 @@ import java.io.OutputStream import java.io.SequenceInputStream import java.nio.file.Files import java.nio.file.Path -import java.util.HashSet import java.util.TreeMap import java.util.jar.JarEntry import java.util.jar.JarInputStream @@ -28,7 +25,7 @@ import java.util.zip.GZIPInputStream import java.util.zip.GZIPOutputStream class Library constructor() : Iterable { - private val classes = TreeMap() + private var classes = TreeMap() constructor(library: Library) : this() { for (clazz in library.classes.values) { @@ -59,26 +56,11 @@ class Library constructor() : Iterable { } fun remap(remapper: Remapper) { - val classNames = HashSet() - for (clazz in classes.values) { - for (method in clazz.methods) { - if (method.hasCode()) { - ClassForNameUtils.remap(remapper, method) - } - } - - classNames.add(clazz.name) + clazz.remap(remapper) } - for (name in classNames) { - val `in` = classes.remove(name) - - val out = ClassNode() - `in`!!.accept(ClassRemapper(out, remapper)) - - classes[out.name] = out - } + classes = classes.mapKeysTo(TreeMap()) { (_, clazz) -> clazz.name } } fun writeJar(path: Path, manifest: Manifest? = null) {