sofya.base
Class JVMStackReverser

java.lang.Object
  extended by sofya.base.JVMStackReverser
All Implemented Interfaces:
org.apache.bcel.Constants

public final class JVMStackReverser
extends java.lang.Object
implements org.apache.bcel.Constants

This class simulates the behavior of the Java stack for a sequence of instructions executed in reverse order. More precisely, it starts with the assumption that the stack contains one operand, and for each instruction that it is given it computes what the state of the stack would have been prior to execution of that instruction, in terms of the number of operands on the stack.

Starting from an instruction where the stack does contain at least one operand and assuming a legal Java bytecode sequence, when fed the sequence of preceding instructions this class should always eventually indicate which of those instructions placed that operand on the top of the stack. This is accomplished primarily by inverting the effect of instructions on the stack operand count (which may of course result in the inference of additional operands).

Note that this class knows no more than the number of operands on the stack at any given time. Any additional information would be very difficult (probably NP-hard) to determine. It also may not maintain a "true" count of the number of operands on the stack, as it will "discard" instructions that it determines cannot have any impact on determining which instruction produced the operand on the top of the stack (such as is the case with certain DUP instructions).

Version:
04/19/2004
Author:
Alex Kinneer

Field Summary
 
Fields inherited from interface org.apache.bcel.Constants
AALOAD, AASTORE, ACC_ABSTRACT, ACC_ANNOTATION, ACC_BRIDGE, ACC_ENUM, ACC_FINAL, ACC_INTERFACE, ACC_NATIVE, ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC, ACC_STATIC, ACC_STRICT, ACC_SUPER, ACC_SYNCHRONIZED, ACC_SYNTHETIC, ACC_TRANSIENT, ACC_VARARGS, ACC_VOLATILE, ACCESS_NAMES, ACONST_NULL, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ANEWARRAY_QUICK, ARETURN, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, ATHROW, ATTR_ANNOTATION_DEFAULT, ATTR_CODE, ATTR_CONSTANT_VALUE, ATTR_DEPRECATED, ATTR_EXCEPTIONS, ATTR_INNER_CLASSES, ATTR_LINE_NUMBER_TABLE, ATTR_LOCAL_VARIABLE_TABLE, ATTR_PMG, ATTR_RUNTIMEINVISIBLE_ANNOTATIONS, ATTR_RUNTIMEINVISIBLE_PARAMETER_ANNOTATIONS, ATTR_RUNTIMEVISIBLE_ANNOTATIONS, ATTR_RUNTIMEVISIBLE_PARAMETER_ANNOTATIONS, ATTR_SIGNATURE, ATTR_SOURCE_FILE, ATTR_STACK_MAP, ATTR_SYNTHETIC, ATTR_UNKNOWN, ATTRIBUTE_NAMES, BALOAD, BASTORE, BIPUSH, BREAKPOINT, CALOAD, CASTORE, CHECKCAST, CHECKCAST_QUICK, CLASS_TYPE_NAMES, CONSTANT_Class, CONSTANT_Double, CONSTANT_Fieldref, CONSTANT_Float, CONSTANT_Integer, CONSTANT_InterfaceMethodref, CONSTANT_Long, CONSTANT_Methodref, CONSTANT_NameAndType, CONSTANT_NAMES, CONSTANT_String, CONSTANT_Utf8, CONSTRUCTOR_NAME, CONSUME_STACK, D2F, D2I, D2L, DADD, DALOAD, DASTORE, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DNEG, DREM, DRETURN, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, F2D, F2I, F2L, FADD, FALOAD, FASTORE, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FNEG, FREM, FRETURN, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETFIELD_QUICK, GETFIELD_QUICK_W, GETFIELD2_QUICK, GETSTATIC, GETSTATIC_QUICK, GETSTATIC2_QUICK, GOTO, GOTO_W, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, IASTORE, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, IFEQ, IFGE, IFGT, IFLE, IFLT, IFNE, IFNONNULL, IFNULL, IINC, ILLEGAL_OPCODE, ILLEGAL_TYPE, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMPDEP1, IMPDEP2, IMUL, INEG, INSTANCEOF, INSTANCEOF_QUICK, INT2BYTE, INT2CHAR, INT2SHORT, INTERFACES_IMPLEMENTED_BY_ARRAYS, INVOKEINTERFACE, INVOKEINTERFACE_QUICK, INVOKENONVIRTUAL, INVOKENONVIRTUAL_QUICK, INVOKESPECIAL, INVOKESTATIC, INVOKESTATIC_QUICK, INVOKESUPER_QUICK, INVOKEVIRTUAL, INVOKEVIRTUAL_QUICK, INVOKEVIRTUAL_QUICK_W, INVOKEVIRTUALOBJECT_QUICK, IOR, IREM, IRETURN, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, ITEM_Bogus, ITEM_Double, ITEM_Float, ITEM_InitObject, ITEM_Integer, ITEM_Long, ITEM_NAMES, ITEM_NewObject, ITEM_Null, ITEM_Object, IUSHR, IXOR, JSR, JSR_W, KNOWN_ATTRIBUTES, L2D, L2F, L2I, LADD, LALOAD, LAND, LASTORE, LCMP, LCONST_0, LCONST_1, LDC, LDC_QUICK, LDC_W, LDC_W_QUICK, LDC2_W, LDC2_W_QUICK, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LNEG, LOOKUPSWITCH, LOR, LREM, LRETURN, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, MAJOR, MAJOR_1_1, MAJOR_1_2, MAJOR_1_3, MAJOR_1_4, MAJOR_1_5, MAX_ACC_FLAG, MAX_BYTE, MAX_CODE_SIZE, MAX_CP_ENTRIES, MAX_SHORT, MINOR, MINOR_1_1, MINOR_1_2, MINOR_1_3, MINOR_1_4, MINOR_1_5, MONITORENTER, MONITOREXIT, MULTIANEWARRAY, MULTIANEWARRAY_QUICK, NEW, NEW_QUICK, NEWARRAY, NO_OF_OPERANDS, NOP, OPCODE_NAMES, POP, POP2, PRODUCE_STACK, PUSH, PUTFIELD, PUTFIELD_QUICK, PUTFIELD_QUICK_W, PUTFIELD2_QUICK, PUTSTATIC, PUTSTATIC_QUICK, PUTSTATIC2_QUICK, RESERVED, RET, RETURN, SALOAD, SASTORE, SHORT_TYPE_NAMES, SIPUSH, STATIC_INITIALIZER_NAME, SWAP, SWITCH, T_ADDRESS, T_ARRAY, T_BOOLEAN, T_BYTE, T_CHAR, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_OBJECT, T_REFERENCE, T_SHORT, T_UNKNOWN, T_VOID, TABLESWITCH, TYPE_NAMES, TYPE_OF_OPERANDS, UNDEFINED, UNPREDICTABLE, WIDE
 
Constructor Summary
JVMStackReverser(org.apache.bcel.generic.ConstantPoolGen cpg)
          Creates a reverse stack simulator.
JVMStackReverser(org.apache.bcel.generic.ConstantPoolGen cpg, int operandDepth)
          Creates a reverse stack simulator.
 
Method Summary
 boolean atPossibleProducer()
          Reports whether the next instruction to be passed to the reverse stack simulator may potntially be identified as the producer of the stack operand of interest.
 JVMStackReverser copy()
          Creates a new reverse stack simulator which is in the same state as this one.
 boolean runInstruction(org.apache.bcel.generic.Instruction instr)
          Simulates execution of an instruction in reverse and reports whether the instruction produced the operand that was on top of the stack when the first instruction was simulated.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

JVMStackReverser

public JVMStackReverser(org.apache.bcel.generic.ConstantPoolGen cpg)
Creates a reverse stack simulator.

Parameters:
cpg - Constant pool of the class from which instructions are being "executed".

JVMStackReverser

public JVMStackReverser(org.apache.bcel.generic.ConstantPoolGen cpg,
                        int operandDepth)
Creates a reverse stack simulator.

Parameters:
cpg - Constant pool of the class from which instructions are being "executed".
operandDepth - How far the operand of interest is offset from the top of the stack.
Method Detail

runInstruction

public boolean runInstruction(org.apache.bcel.generic.Instruction instr)
Simulates execution of an instruction in reverse and reports whether the instruction produced the operand that was on top of the stack when the first instruction was simulated.

Parameters:
instr - Instruction (BCEL) to be simulated.
Returns:
true if the instruction produced the operand of interest, false otherwise.

atPossibleProducer

public boolean atPossibleProducer()
Reports whether the next instruction to be passed to the reverse stack simulator may potntially be identified as the producer of the stack operand of interest.

Returns:
true if the next instruction simulated by the stack reverser is an operand producing instruction and the simulator has determined that it produces the operand of interest.

copy

public JVMStackReverser copy()
Creates a new reverse stack simulator which is in the same state as this one.

This method should be used to prevent confusion when simulating instruction sequences that contain branches (technically joins following branches, in terms of proper forward execution). The user of this object is responsible for maintaining some notion of such control flow constructs, copying the stack for each "branch" and taking the union of the results in some manner.

Returns:
A new reverse java stack which is in the same state as the current stack; simulation of instructions on the new stack will not affect the original stack.