diff --git a/asm/src/main/kotlin/org/openrs2/asm/InsnListUtils.kt b/asm/src/main/kotlin/org/openrs2/asm/InsnListUtils.kt index 6cd8eacb..88bdec6c 100644 --- a/asm/src/main/kotlin/org/openrs2/asm/InsnListUtils.kt +++ b/asm/src/main/kotlin/org/openrs2/asm/InsnListUtils.kt @@ -1,23 +1,26 @@ package org.openrs2.asm +import org.objectweb.asm.Type import org.objectweb.asm.tree.AbstractInsnNode import org.objectweb.asm.tree.InsnList import org.objectweb.asm.tree.LabelNode +import org.objectweb.asm.tree.MethodInsnNode private val ANY_INSN = { _: AbstractInsnNode -> true } public fun getExpression( last: AbstractInsnNode, - filter: (AbstractInsnNode) -> Boolean = ANY_INSN + filter: (AbstractInsnNode) -> Boolean = ANY_INSN, + initialHeight: Int = 0 ): List? { val expr = mutableListOf() - var height = 0 + var height = initialHeight var insn: AbstractInsnNode? = last do { val (pops, pushes) = insn!!.stackMetadata expr.add(insn) - if (insn !== last) { + if (insn !== last || initialHeight != 0) { height -= pushes } height += pops @@ -32,6 +35,24 @@ public fun getExpression( return null } +public fun getArgumentExpressions( + invoke: MethodInsnNode, + filter: (AbstractInsnNode) -> Boolean = ANY_INSN +): List>? { + val exprs = mutableListOf>() + + var insn: AbstractInsnNode = invoke.previous ?: return null + + for (type in Type.getArgumentTypes(invoke.desc)) { + val expr = getExpression(insn, filter, type.size) ?: return null + exprs += expr + + insn = expr.first().previous ?: return null + } + + return exprs.asReversed() +} + public fun InsnList.replaceExpression( last: AbstractInsnNode, replacement: AbstractInsnNode,