From 71413256da2cbfa11c42c15cefd0f3cf32a7c5ba Mon Sep 17 00:00:00 2001 From: Graham Date: Sat, 30 May 2020 21:25:47 +0100 Subject: [PATCH] Check that methods have a single tail RETURN The code for splicing an initializer into the method relies on this assumption. Signed-off-by: Graham --- .../java/dev/openrs2/asm/classpath/LibraryRemapper.kt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/asm/src/main/java/dev/openrs2/asm/classpath/LibraryRemapper.kt b/asm/src/main/java/dev/openrs2/asm/classpath/LibraryRemapper.kt index e3bf8284..504371c4 100644 --- a/asm/src/main/java/dev/openrs2/asm/classpath/LibraryRemapper.kt +++ b/asm/src/main/java/dev/openrs2/asm/classpath/LibraryRemapper.kt @@ -2,6 +2,7 @@ package dev.openrs2.asm.classpath import dev.openrs2.asm.ClassVersionUtils import dev.openrs2.asm.MemberRef +import dev.openrs2.asm.nextReal import dev.openrs2.asm.remap import org.objectweb.asm.Opcodes import org.objectweb.asm.tree.ClassNode @@ -160,7 +161,10 @@ class LibraryRemapper( } val clinit = clazz.methods.find { it.name == "" } ?: createClinitMethod(clazz) - // TODO(gpe): check the method only has a single RETURN and that it is the last instruction + check(hasSingleTailExit(clinit.instructions)) { + "${clazz.name}'s method does not have a single RETURN at the end of the InsnList" + } + clinit.maxStack = max(clinit.maxStack, field.initializer.maxStack) clinit.instructions.insertBefore(clinit.instructions.last, field.initializer.instructions) } @@ -169,6 +173,11 @@ class LibraryRemapper( clazz.fields.add(field.node) } + private fun hasSingleTailExit(instructions: InsnList): Boolean { + val insn = instructions.singleOrNull { it.opcode == Opcodes.RETURN } + return insn != null && insn.nextReal == null + } + private fun spliceMethods() { for (method in methods) { val clazz = classes.computeIfAbsent(method.owner, ::createClass)