forked from openrs2/openrs2
parent
c02fe030fa
commit
e68fed7a9e
@ -1,353 +0,0 @@ |
|||||||
package dev.openrs2.asm; |
|
||||||
|
|
||||||
import org.objectweb.asm.Opcodes; |
|
||||||
import org.objectweb.asm.Type; |
|
||||||
import org.objectweb.asm.tree.AbstractInsnNode; |
|
||||||
import org.objectweb.asm.tree.FieldInsnNode; |
|
||||||
import org.objectweb.asm.tree.LdcInsnNode; |
|
||||||
import org.objectweb.asm.tree.MethodInsnNode; |
|
||||||
import org.objectweb.asm.tree.MultiANewArrayInsnNode; |
|
||||||
|
|
||||||
public final class StackMetadata { |
|
||||||
private static final StackMetadata NONE = new StackMetadata(0, 0); |
|
||||||
private static final StackMetadata POP1 = new StackMetadata(1, 0); |
|
||||||
private static final StackMetadata POP1_PUSH1 = new StackMetadata(1, 1); |
|
||||||
private static final StackMetadata POP1_PUSH2 = new StackMetadata(1, 2); |
|
||||||
private static final StackMetadata POP2 = new StackMetadata(2, 0); |
|
||||||
private static final StackMetadata POP2_PUSH1 = new StackMetadata(2, 1); |
|
||||||
private static final StackMetadata POP2_PUSH2 = new StackMetadata(2, 2); |
|
||||||
private static final StackMetadata POP2_PUSH3 = new StackMetadata(2, 3); |
|
||||||
private static final StackMetadata POP2_PUSH4 = new StackMetadata(2, 4); |
|
||||||
private static final StackMetadata POP3 = new StackMetadata(3, 0); |
|
||||||
private static final StackMetadata POP3_PUSH2 = new StackMetadata(3, 2); |
|
||||||
private static final StackMetadata POP3_PUSH4 = new StackMetadata(3, 4); |
|
||||||
private static final StackMetadata POP3_PUSH5 = new StackMetadata(3, 5); |
|
||||||
private static final StackMetadata POP4 = new StackMetadata(4, 0); |
|
||||||
private static final StackMetadata POP4_PUSH1 = new StackMetadata(4, 1); |
|
||||||
private static final StackMetadata POP4_PUSH2 = new StackMetadata(4, 2); |
|
||||||
private static final StackMetadata POP4_PUSH6 = new StackMetadata(4, 6); |
|
||||||
private static final StackMetadata PUSH1 = new StackMetadata(0, 1); |
|
||||||
private static final StackMetadata PUSH2 = new StackMetadata(0, 2); |
|
||||||
|
|
||||||
public static StackMetadata get(AbstractInsnNode insn) { |
|
||||||
var opcode = insn.getOpcode(); |
|
||||||
switch (opcode) { |
|
||||||
case -1: |
|
||||||
case Opcodes.NOP: |
|
||||||
return NONE; |
|
||||||
case Opcodes.ACONST_NULL: |
|
||||||
case Opcodes.ICONST_M1: |
|
||||||
case Opcodes.ICONST_0: |
|
||||||
case Opcodes.ICONST_1: |
|
||||||
case Opcodes.ICONST_2: |
|
||||||
case Opcodes.ICONST_3: |
|
||||||
case Opcodes.ICONST_4: |
|
||||||
case Opcodes.ICONST_5: |
|
||||||
return PUSH1; |
|
||||||
case Opcodes.LCONST_0: |
|
||||||
case Opcodes.LCONST_1: |
|
||||||
return PUSH2; |
|
||||||
case Opcodes.FCONST_0: |
|
||||||
case Opcodes.FCONST_1: |
|
||||||
case Opcodes.FCONST_2: |
|
||||||
return PUSH1; |
|
||||||
case Opcodes.DCONST_0: |
|
||||||
case Opcodes.DCONST_1: |
|
||||||
return PUSH2; |
|
||||||
case Opcodes.BIPUSH: |
|
||||||
case Opcodes.SIPUSH: |
|
||||||
return PUSH1; |
|
||||||
case Opcodes.LDC: |
|
||||||
var cst = ((LdcInsnNode) insn).cst; |
|
||||||
if (cst instanceof Double || cst instanceof Long) { |
|
||||||
return PUSH2; |
|
||||||
} else { |
|
||||||
return PUSH1; |
|
||||||
} |
|
||||||
case Opcodes.ILOAD: |
|
||||||
return PUSH1; |
|
||||||
case Opcodes.LLOAD: |
|
||||||
return PUSH2; |
|
||||||
case Opcodes.FLOAD: |
|
||||||
return PUSH1; |
|
||||||
case Opcodes.DLOAD: |
|
||||||
return PUSH2; |
|
||||||
case Opcodes.ALOAD: |
|
||||||
return PUSH1; |
|
||||||
case Opcodes.IALOAD: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.LALOAD: |
|
||||||
return POP2_PUSH2; |
|
||||||
case Opcodes.FALOAD: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.DALOAD: |
|
||||||
return POP2_PUSH2; |
|
||||||
case Opcodes.AALOAD: |
|
||||||
case Opcodes.BALOAD: |
|
||||||
case Opcodes.CALOAD: |
|
||||||
case Opcodes.SALOAD: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.ISTORE: |
|
||||||
return POP1; |
|
||||||
case Opcodes.LSTORE: |
|
||||||
return POP2; |
|
||||||
case Opcodes.FSTORE: |
|
||||||
return POP1; |
|
||||||
case Opcodes.DSTORE: |
|
||||||
return POP2; |
|
||||||
case Opcodes.ASTORE: |
|
||||||
return POP1; |
|
||||||
case Opcodes.IASTORE: |
|
||||||
return POP3; |
|
||||||
case Opcodes.LASTORE: |
|
||||||
return POP4; |
|
||||||
case Opcodes.FASTORE: |
|
||||||
return POP3; |
|
||||||
case Opcodes.DASTORE: |
|
||||||
return POP4; |
|
||||||
case Opcodes.AASTORE: |
|
||||||
case Opcodes.BASTORE: |
|
||||||
case Opcodes.CASTORE: |
|
||||||
case Opcodes.SASTORE: |
|
||||||
return POP3; |
|
||||||
case Opcodes.POP: |
|
||||||
return POP1; |
|
||||||
case Opcodes.POP2: |
|
||||||
return POP2; |
|
||||||
case Opcodes.DUP: |
|
||||||
return POP1_PUSH2; |
|
||||||
case Opcodes.DUP_X1: |
|
||||||
return POP2_PUSH3; |
|
||||||
case Opcodes.DUP_X2: |
|
||||||
return POP3_PUSH4; |
|
||||||
case Opcodes.DUP2: |
|
||||||
return POP2_PUSH4; |
|
||||||
case Opcodes.DUP2_X1: |
|
||||||
return POP3_PUSH5; |
|
||||||
case Opcodes.DUP2_X2: |
|
||||||
return POP4_PUSH6; |
|
||||||
case Opcodes.SWAP: |
|
||||||
return POP2_PUSH2; |
|
||||||
case Opcodes.IADD: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.LADD: |
|
||||||
return POP4_PUSH2; |
|
||||||
case Opcodes.FADD: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.DADD: |
|
||||||
return POP4_PUSH2; |
|
||||||
case Opcodes.ISUB: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.LSUB: |
|
||||||
return POP4_PUSH2; |
|
||||||
case Opcodes.FSUB: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.DSUB: |
|
||||||
return POP4_PUSH2; |
|
||||||
case Opcodes.IMUL: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.LMUL: |
|
||||||
return POP4_PUSH2; |
|
||||||
case Opcodes.FMUL: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.DMUL: |
|
||||||
return POP4_PUSH2; |
|
||||||
case Opcodes.IDIV: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.LDIV: |
|
||||||
return POP4_PUSH2; |
|
||||||
case Opcodes.FDIV: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.DDIV: |
|
||||||
return POP4_PUSH2; |
|
||||||
case Opcodes.IREM: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.LREM: |
|
||||||
return POP4_PUSH2; |
|
||||||
case Opcodes.FREM: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.DREM: |
|
||||||
return POP4_PUSH2; |
|
||||||
case Opcodes.INEG: |
|
||||||
return POP1_PUSH1; |
|
||||||
case Opcodes.LNEG: |
|
||||||
return POP2_PUSH2; |
|
||||||
case Opcodes.FNEG: |
|
||||||
return POP1_PUSH1; |
|
||||||
case Opcodes.DNEG: |
|
||||||
return POP2_PUSH2; |
|
||||||
case Opcodes.ISHL: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.LSHL: |
|
||||||
return POP3_PUSH2; |
|
||||||
case Opcodes.ISHR: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.LSHR: |
|
||||||
return POP3_PUSH2; |
|
||||||
case Opcodes.IUSHR: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.LUSHR: |
|
||||||
return POP3_PUSH2; |
|
||||||
case Opcodes.IAND: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.LAND: |
|
||||||
return POP4_PUSH2; |
|
||||||
case Opcodes.IOR: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.LOR: |
|
||||||
return POP4_PUSH2; |
|
||||||
case Opcodes.IXOR: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.LXOR: |
|
||||||
return POP4_PUSH2; |
|
||||||
case Opcodes.IINC: |
|
||||||
return NONE; |
|
||||||
case Opcodes.I2L: |
|
||||||
return POP1_PUSH2; |
|
||||||
case Opcodes.I2F: |
|
||||||
return POP1_PUSH1; |
|
||||||
case Opcodes.I2D: |
|
||||||
return POP1_PUSH2; |
|
||||||
case Opcodes.L2I: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.L2F: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.L2D: |
|
||||||
return POP2_PUSH2; |
|
||||||
case Opcodes.F2I: |
|
||||||
return POP1_PUSH1; |
|
||||||
case Opcodes.F2L: |
|
||||||
return POP1_PUSH2; |
|
||||||
case Opcodes.F2D: |
|
||||||
return POP1_PUSH2; |
|
||||||
case Opcodes.D2I: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.D2L: |
|
||||||
return POP2_PUSH2; |
|
||||||
case Opcodes.D2F: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.I2B: |
|
||||||
case Opcodes.I2C: |
|
||||||
case Opcodes.I2S: |
|
||||||
return POP1_PUSH1; |
|
||||||
case Opcodes.LCMP: |
|
||||||
return POP4_PUSH1; |
|
||||||
case Opcodes.FCMPL: |
|
||||||
case Opcodes.FCMPG: |
|
||||||
return POP2_PUSH1; |
|
||||||
case Opcodes.DCMPL: |
|
||||||
case Opcodes.DCMPG: |
|
||||||
return POP4_PUSH1; |
|
||||||
case Opcodes.IFEQ: |
|
||||||
case Opcodes.IFNE: |
|
||||||
case Opcodes.IFLT: |
|
||||||
case Opcodes.IFGE: |
|
||||||
case Opcodes.IFGT: |
|
||||||
case Opcodes.IFLE: |
|
||||||
return POP1; |
|
||||||
case Opcodes.IF_ICMPEQ: |
|
||||||
case Opcodes.IF_ICMPNE: |
|
||||||
case Opcodes.IF_ICMPLT: |
|
||||||
case Opcodes.IF_ICMPGE: |
|
||||||
case Opcodes.IF_ICMPGT: |
|
||||||
case Opcodes.IF_ICMPLE: |
|
||||||
case Opcodes.IF_ACMPEQ: |
|
||||||
case Opcodes.IF_ACMPNE: |
|
||||||
return POP2; |
|
||||||
case Opcodes.GOTO: |
|
||||||
return NONE; |
|
||||||
case Opcodes.JSR: |
|
||||||
return PUSH1; |
|
||||||
case Opcodes.RET: |
|
||||||
return NONE; |
|
||||||
case Opcodes.TABLESWITCH: |
|
||||||
case Opcodes.LOOKUPSWITCH: |
|
||||||
return POP1; |
|
||||||
case Opcodes.IRETURN: |
|
||||||
return POP1; |
|
||||||
case Opcodes.LRETURN: |
|
||||||
return POP2; |
|
||||||
case Opcodes.FRETURN: |
|
||||||
return POP1; |
|
||||||
case Opcodes.DRETURN: |
|
||||||
return POP2; |
|
||||||
case Opcodes.ARETURN: |
|
||||||
return POP1; |
|
||||||
case Opcodes.RETURN: |
|
||||||
return NONE; |
|
||||||
case Opcodes.GETSTATIC: |
|
||||||
case Opcodes.PUTSTATIC: |
|
||||||
case Opcodes.GETFIELD: |
|
||||||
case Opcodes.PUTFIELD: |
|
||||||
var fieldInsn = (FieldInsnNode) insn; |
|
||||||
var fieldSize = Type.getType(fieldInsn.desc).getSize(); |
|
||||||
|
|
||||||
int pushes = 0, pops = 0; |
|
||||||
|
|
||||||
if (opcode == Opcodes.GETFIELD || opcode == Opcodes.PUTFIELD) { |
|
||||||
pops++; |
|
||||||
} |
|
||||||
|
|
||||||
if (opcode == Opcodes.PUTFIELD || opcode == Opcodes.PUTSTATIC) { |
|
||||||
pushes += fieldSize; |
|
||||||
} else { |
|
||||||
pops += fieldSize; |
|
||||||
} |
|
||||||
|
|
||||||
return new StackMetadata(pops, pushes); |
|
||||||
case Opcodes.INVOKEVIRTUAL: |
|
||||||
case Opcodes.INVOKESPECIAL: |
|
||||||
case Opcodes.INVOKESTATIC: |
|
||||||
case Opcodes.INVOKEINTERFACE: |
|
||||||
var methodInsn = (MethodInsnNode) insn; |
|
||||||
var argumentsAndReturnSizes = Type.getArgumentsAndReturnSizes(methodInsn.desc); |
|
||||||
|
|
||||||
pushes = argumentsAndReturnSizes >> 2; |
|
||||||
pops = argumentsAndReturnSizes & 0x3; |
|
||||||
|
|
||||||
if (opcode != Opcodes.INVOKESTATIC) { |
|
||||||
pops++; |
|
||||||
} |
|
||||||
|
|
||||||
return new StackMetadata(pops, pushes); |
|
||||||
case Opcodes.INVOKEDYNAMIC: |
|
||||||
throw new UnsupportedOperationException(); |
|
||||||
case Opcodes.NEW: |
|
||||||
return POP1; |
|
||||||
case Opcodes.NEWARRAY: |
|
||||||
case Opcodes.ANEWARRAY: |
|
||||||
case Opcodes.ARRAYLENGTH: |
|
||||||
return POP1_PUSH1; |
|
||||||
case Opcodes.ATHROW: |
|
||||||
return POP1; |
|
||||||
case Opcodes.CHECKCAST: |
|
||||||
case Opcodes.INSTANCEOF: |
|
||||||
return POP1_PUSH1; |
|
||||||
case Opcodes.MONITORENTER: |
|
||||||
case Opcodes.MONITOREXIT: |
|
||||||
return POP1; |
|
||||||
case Opcodes.MULTIANEWARRAY: |
|
||||||
return new StackMetadata(((MultiANewArrayInsnNode) insn).dims, 1); |
|
||||||
case Opcodes.IFNULL: |
|
||||||
case Opcodes.IFNONNULL: |
|
||||||
return POP1; |
|
||||||
} |
|
||||||
|
|
||||||
throw new IllegalArgumentException(); |
|
||||||
} |
|
||||||
|
|
||||||
private final int pops, pushes; |
|
||||||
|
|
||||||
private StackMetadata(int pops, int pushes) { |
|
||||||
this.pops = pops; |
|
||||||
this.pushes = pushes; |
|
||||||
} |
|
||||||
|
|
||||||
public int getPops() { |
|
||||||
return pops; |
|
||||||
} |
|
||||||
|
|
||||||
public int getPushes() { |
|
||||||
return pushes; |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,211 @@ |
|||||||
|
package dev.openrs2.asm |
||||||
|
|
||||||
|
import org.objectweb.asm.Opcodes |
||||||
|
import org.objectweb.asm.Type |
||||||
|
import org.objectweb.asm.tree.* |
||||||
|
|
||||||
|
data class StackMetadata(val pops: Int, val pushes: Int) |
||||||
|
|
||||||
|
private val NONE = StackMetadata(0, 0) |
||||||
|
private val POP1 = StackMetadata(1, 0) |
||||||
|
private val POP1_PUSH1 = StackMetadata(1, 1) |
||||||
|
private val POP1_PUSH2 = StackMetadata(1, 2) |
||||||
|
private val POP2 = StackMetadata(2, 0) |
||||||
|
private val POP2_PUSH1 = StackMetadata(2, 1) |
||||||
|
private val POP2_PUSH2 = StackMetadata(2, 2) |
||||||
|
private val POP2_PUSH3 = StackMetadata(2, 3) |
||||||
|
private val POP2_PUSH4 = StackMetadata(2, 4) |
||||||
|
private val POP3 = StackMetadata(3, 0) |
||||||
|
private val POP3_PUSH2 = StackMetadata(3, 2) |
||||||
|
private val POP3_PUSH4 = StackMetadata(3, 4) |
||||||
|
private val POP3_PUSH5 = StackMetadata(3, 5) |
||||||
|
private val POP4 = StackMetadata(4, 0) |
||||||
|
private val POP4_PUSH1 = StackMetadata(4, 1) |
||||||
|
private val POP4_PUSH2 = StackMetadata(4, 2) |
||||||
|
private val POP4_PUSH6 = StackMetadata(4, 6) |
||||||
|
private val PUSH1 = StackMetadata(0, 1) |
||||||
|
private val PUSH2 = StackMetadata(0, 2) |
||||||
|
|
||||||
|
private val SIMPLE_OPCODES = mapOf( |
||||||
|
-1 to NONE, |
||||||
|
Opcodes.NOP to NONE, |
||||||
|
Opcodes.ACONST_NULL to PUSH1, |
||||||
|
Opcodes.ICONST_M1 to PUSH1, |
||||||
|
Opcodes.ICONST_0 to PUSH1, |
||||||
|
Opcodes.ICONST_1 to PUSH1, |
||||||
|
Opcodes.ICONST_2 to PUSH1, |
||||||
|
Opcodes.ICONST_3 to PUSH1, |
||||||
|
Opcodes.ICONST_4 to PUSH1, |
||||||
|
Opcodes.ICONST_5 to PUSH1, |
||||||
|
Opcodes.LCONST_0 to PUSH2, |
||||||
|
Opcodes.LCONST_1 to PUSH2, |
||||||
|
Opcodes.FCONST_0 to PUSH1, |
||||||
|
Opcodes.FCONST_1 to PUSH1, |
||||||
|
Opcodes.FCONST_2 to PUSH1, |
||||||
|
Opcodes.DCONST_0 to PUSH2, |
||||||
|
Opcodes.DCONST_1 to PUSH2, |
||||||
|
Opcodes.BIPUSH to PUSH1, |
||||||
|
Opcodes.SIPUSH to PUSH1, |
||||||
|
Opcodes.ILOAD to PUSH1, |
||||||
|
Opcodes.LLOAD to PUSH2, |
||||||
|
Opcodes.FLOAD to PUSH1, |
||||||
|
Opcodes.DLOAD to PUSH2, |
||||||
|
Opcodes.ALOAD to PUSH1, |
||||||
|
Opcodes.IALOAD to POP2_PUSH1, |
||||||
|
Opcodes.LALOAD to POP2_PUSH2, |
||||||
|
Opcodes.FALOAD to POP2_PUSH1, |
||||||
|
Opcodes.DALOAD to POP2_PUSH2, |
||||||
|
Opcodes.AALOAD to POP2_PUSH1, |
||||||
|
Opcodes.BALOAD to POP2_PUSH1, |
||||||
|
Opcodes.CALOAD to POP2_PUSH1, |
||||||
|
Opcodes.SALOAD to POP2_PUSH1, |
||||||
|
Opcodes.ISTORE to POP1, |
||||||
|
Opcodes.LSTORE to POP2, |
||||||
|
Opcodes.FSTORE to POP1, |
||||||
|
Opcodes.DSTORE to POP2, |
||||||
|
Opcodes.ASTORE to POP1, |
||||||
|
Opcodes.IASTORE to POP3, |
||||||
|
Opcodes.LASTORE to POP4, |
||||||
|
Opcodes.FASTORE to POP3, |
||||||
|
Opcodes.DASTORE to POP4, |
||||||
|
Opcodes.AASTORE to POP3, |
||||||
|
Opcodes.BASTORE to POP3, |
||||||
|
Opcodes.CASTORE to POP3, |
||||||
|
Opcodes.SASTORE to POP3, |
||||||
|
Opcodes.POP to POP1, |
||||||
|
Opcodes.POP2 to POP2, |
||||||
|
Opcodes.DUP to POP1_PUSH2, |
||||||
|
Opcodes.DUP_X1 to POP2_PUSH3, |
||||||
|
Opcodes.DUP_X2 to POP3_PUSH4, |
||||||
|
Opcodes.DUP2 to POP2_PUSH4, |
||||||
|
Opcodes.DUP2_X1 to POP3_PUSH5, |
||||||
|
Opcodes.DUP2_X2 to POP4_PUSH6, |
||||||
|
Opcodes.SWAP to POP2_PUSH2, |
||||||
|
Opcodes.IADD to POP2_PUSH1, |
||||||
|
Opcodes.LADD to POP4_PUSH2, |
||||||
|
Opcodes.FADD to POP2_PUSH1, |
||||||
|
Opcodes.DADD to POP4_PUSH2, |
||||||
|
Opcodes.ISUB to POP2_PUSH1, |
||||||
|
Opcodes.LSUB to POP4_PUSH2, |
||||||
|
Opcodes.FSUB to POP2_PUSH1, |
||||||
|
Opcodes.DSUB to POP4_PUSH2, |
||||||
|
Opcodes.IMUL to POP2_PUSH1, |
||||||
|
Opcodes.LMUL to POP4_PUSH2, |
||||||
|
Opcodes.FMUL to POP2_PUSH1, |
||||||
|
Opcodes.DMUL to POP4_PUSH2, |
||||||
|
Opcodes.IDIV to POP2_PUSH1, |
||||||
|
Opcodes.LDIV to POP4_PUSH2, |
||||||
|
Opcodes.FDIV to POP2_PUSH1, |
||||||
|
Opcodes.DDIV to POP4_PUSH2, |
||||||
|
Opcodes.IREM to POP2_PUSH1, |
||||||
|
Opcodes.LREM to POP4_PUSH2, |
||||||
|
Opcodes.FREM to POP2_PUSH1, |
||||||
|
Opcodes.DREM to POP4_PUSH2, |
||||||
|
Opcodes.INEG to POP1_PUSH1, |
||||||
|
Opcodes.LNEG to POP2_PUSH2, |
||||||
|
Opcodes.FNEG to POP1_PUSH1, |
||||||
|
Opcodes.DNEG to POP2_PUSH2, |
||||||
|
Opcodes.ISHL to POP2_PUSH1, |
||||||
|
Opcodes.LSHL to POP3_PUSH2, |
||||||
|
Opcodes.ISHR to POP2_PUSH1, |
||||||
|
Opcodes.LSHR to POP3_PUSH2, |
||||||
|
Opcodes.IUSHR to POP2_PUSH1, |
||||||
|
Opcodes.LUSHR to POP3_PUSH2, |
||||||
|
Opcodes.IAND to POP2_PUSH1, |
||||||
|
Opcodes.LAND to POP4_PUSH2, |
||||||
|
Opcodes.IOR to POP2_PUSH1, |
||||||
|
Opcodes.LOR to POP4_PUSH2, |
||||||
|
Opcodes.IXOR to POP2_PUSH1, |
||||||
|
Opcodes.LXOR to POP4_PUSH2, |
||||||
|
Opcodes.IINC to NONE, |
||||||
|
Opcodes.I2L to POP1_PUSH2, |
||||||
|
Opcodes.I2F to POP1_PUSH1, |
||||||
|
Opcodes.I2D to POP1_PUSH2, |
||||||
|
Opcodes.L2I to POP2_PUSH1, |
||||||
|
Opcodes.L2F to POP2_PUSH1, |
||||||
|
Opcodes.L2D to POP2_PUSH2, |
||||||
|
Opcodes.F2I to POP1_PUSH1, |
||||||
|
Opcodes.F2L to POP1_PUSH2, |
||||||
|
Opcodes.F2D to POP1_PUSH2, |
||||||
|
Opcodes.D2I to POP2_PUSH1, |
||||||
|
Opcodes.D2L to POP2_PUSH2, |
||||||
|
Opcodes.D2F to POP2_PUSH1, |
||||||
|
Opcodes.I2B to POP1_PUSH1, |
||||||
|
Opcodes.I2C to POP1_PUSH1, |
||||||
|
Opcodes.I2S to POP1_PUSH1, |
||||||
|
Opcodes.LCMP to POP4_PUSH1, |
||||||
|
Opcodes.FCMPL to POP2_PUSH1, |
||||||
|
Opcodes.FCMPG to POP2_PUSH1, |
||||||
|
Opcodes.DCMPL to POP4_PUSH1, |
||||||
|
Opcodes.DCMPG to POP4_PUSH1, |
||||||
|
Opcodes.IFEQ to POP1, |
||||||
|
Opcodes.IFNE to POP1, |
||||||
|
Opcodes.IFLT to POP1, |
||||||
|
Opcodes.IFGE to POP1, |
||||||
|
Opcodes.IFGT to POP1, |
||||||
|
Opcodes.IFLE to POP1, |
||||||
|
Opcodes.IF_ICMPEQ to POP2, |
||||||
|
Opcodes.IF_ICMPNE to POP2, |
||||||
|
Opcodes.IF_ICMPLT to POP2, |
||||||
|
Opcodes.IF_ICMPGE to POP2, |
||||||
|
Opcodes.IF_ICMPGT to POP2, |
||||||
|
Opcodes.IF_ICMPLE to POP2, |
||||||
|
Opcodes.IF_ACMPEQ to POP2, |
||||||
|
Opcodes.IF_ACMPNE to POP2, |
||||||
|
Opcodes.GOTO to NONE, |
||||||
|
Opcodes.JSR to PUSH1, |
||||||
|
Opcodes.RET to NONE, |
||||||
|
Opcodes.TABLESWITCH to POP1, |
||||||
|
Opcodes.LOOKUPSWITCH to POP1, |
||||||
|
Opcodes.IRETURN to POP1, |
||||||
|
Opcodes.LRETURN to POP2, |
||||||
|
Opcodes.FRETURN to POP1, |
||||||
|
Opcodes.DRETURN to POP2, |
||||||
|
Opcodes.ARETURN to POP1, |
||||||
|
Opcodes.RETURN to NONE, |
||||||
|
Opcodes.NEW to POP1, |
||||||
|
Opcodes.NEWARRAY to POP1_PUSH1, |
||||||
|
Opcodes.ANEWARRAY to POP1_PUSH1, |
||||||
|
Opcodes.ARRAYLENGTH to POP1_PUSH1, |
||||||
|
Opcodes.ATHROW to POP1, |
||||||
|
Opcodes.CHECKCAST to POP1_PUSH1, |
||||||
|
Opcodes.INSTANCEOF to POP1_PUSH1, |
||||||
|
Opcodes.MONITORENTER to POP1, |
||||||
|
Opcodes.MONITOREXIT to POP1, |
||||||
|
Opcodes.IFNULL to POP1, |
||||||
|
Opcodes.IFNONNULL to POP1 |
||||||
|
) |
||||||
|
|
||||||
|
fun AbstractInsnNode.stackMetadata(): StackMetadata = when (this) { |
||||||
|
is LdcInsnNode -> if (cst is Double || cst is Long) { |
||||||
|
PUSH2 |
||||||
|
} else { |
||||||
|
PUSH1 |
||||||
|
} |
||||||
|
is FieldInsnNode -> { |
||||||
|
val fieldSize = Type.getType(desc).size |
||||||
|
var pushes = 0 |
||||||
|
var pops = 0 |
||||||
|
if (opcode == Opcodes.GETFIELD || opcode == Opcodes.PUTFIELD) { |
||||||
|
pops++ |
||||||
|
} |
||||||
|
if (opcode == Opcodes.PUTFIELD || opcode == Opcodes.PUTSTATIC) { |
||||||
|
pushes += fieldSize |
||||||
|
} else { |
||||||
|
pops += fieldSize |
||||||
|
} |
||||||
|
StackMetadata(pops, pushes) |
||||||
|
} |
||||||
|
is MethodInsnNode -> { |
||||||
|
val argumentsAndReturnSizes = Type.getArgumentsAndReturnSizes(desc) |
||||||
|
val pushes = argumentsAndReturnSizes shr 2 |
||||||
|
var pops = argumentsAndReturnSizes and 0x3 |
||||||
|
if (opcode != Opcodes.INVOKESTATIC) { |
||||||
|
pops++ |
||||||
|
} |
||||||
|
StackMetadata(pops, pushes) |
||||||
|
} |
||||||
|
is InvokeDynamicInsnNode -> throw UnsupportedOperationException() |
||||||
|
is MultiANewArrayInsnNode -> StackMetadata(dims, 1) |
||||||
|
else -> SIMPLE_OPCODES[opcode] ?: throw IllegalArgumentException() |
||||||
|
} |
Loading…
Reference in new issue