|
|
|
@ -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<AbstractInsnNode>? { |
|
|
|
|
val expr = mutableListOf<AbstractInsnNode>() |
|
|
|
|
|
|
|
|
|
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<List<AbstractInsnNode>>? { |
|
|
|
|
val exprs = mutableListOf<List<AbstractInsnNode>>() |
|
|
|
|
|
|
|
|
|
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, |
|
|
|
|