Class Instruction

java.lang.Object
com.ibm.wala.shrike.shrikeBT.Instruction
All Implemented Interfaces:
Constants, IInstruction, Cloneable
Direct Known Subclasses:
ArrayLengthInstruction, ArrayLoadInstruction, ArrayStoreInstruction, BinaryOpInstruction, CheckCastInstruction, ComparisonInstruction, ConditionalBranchInstruction, ConstantInstruction, ConversionInstruction, DupInstruction, GetInstruction, GotoInstruction, InstanceofInstruction, InvokeDynamicInstruction, InvokeInstruction, LoadInstruction, MonitorInstruction, NewInstruction, PopInstruction, PutInstruction, ReturnInstruction, ShiftInstruction, StoreInstruction, SwapInstruction, SwitchInstruction, ThrowInstruction, UnaryOpInstruction

public abstract class Instruction extends Object implements Constants, Cloneable, IInstruction
Instructions are immutable objects. It is always legal to take a reference to an instruction and use it in any other context. You never need to copy instructions. It is often a good idea to keep references to frequently used instructions cached in static fields.

To generate an Instruction, locate the class for the instruction you want to generate, and invoke the appropriate "make" static method on that class. The Util class has convenience methods for creating some of the more complex instructions using reflection to fill in some of the needed information (e.g., makeGet, makePut, makeInvoke).

We simplify the bytecode instruction set a bit using some preprocessing and postprocessing:

There is no 'iinc' instruction. 'iinc' instructions are expanded to 'iload; bipush; iadd; istore' during decoding and reassembled during compilation.

There are no 'jsr' or 'ret' instructions. Bytecode subroutines are expanded inline during decoding.

There are no 'ifeq', 'ifne', 'ifgt', 'ifge', 'iflt', 'ifle' instructions. These instructions are expanded to 'bipush 0; if_icmp' during decoding and reassembled during compilation.

There are no 'ifnull' or 'ifnonnull' instructions. These instructions are expanded to 'aconst_null; if_acmp' during decoding and reassembled during compilation.

All Java values, including longs and doubles, occupy just one word on the stack. Places where the JVM assumes differently are fixed up during compilation. However, longs and double still take up two local variable slots (this usually doesn't matter to instrumentation).

Control transfer instructions refer to target instructions using integers. These integers are usually indices into an array of instructions.

  • Field Details

    • noInstructions

      public static final int[] noInstructions
  • Method Details

    • isFallThrough

      public boolean isFallThrough()
      Specified by:
      isFallThrough in interface IInstruction
      Returns:
      true if the instruction can "fall through" to the following instruction
    • getBranchTargets

      public int[] getBranchTargets()
      Specified by:
      getBranchTargets in interface IInstruction
      Returns:
      an array containing the labels this instruction can branch to (not including the following instruction if this instruction 'falls through')
    • redirectTargets

      public IInstruction redirectTargets(int[] targetMap)
      Specified by:
      redirectTargets in interface IInstruction
      Returns:
      an Instruction equivalent to this one but with any branch labels updated by looking them up in the targetMap array
    • getPoppedCount

      public int getPoppedCount()
      Specified by:
      getPoppedCount in interface IInstruction
      Returns:
      the number of values this instruction pops off the working stack
    • getOpcode

      public final short getOpcode()
      Returns:
      the opcode selected for this instruction, or -1 if we don't know it yet
    • getPushedType

      public String getPushedType(String[] poppedTypesToCheck)
      Computes the type of data pushed onto the stack, or null if none is pushed.
      Specified by:
      getPushedType in interface IInstruction
      Parameters:
      poppedTypesToCheck - the types of the data popped off the stack by this instruction; if poppedTypes is null, then we don't know the incoming stack types and the result of this method may be less accurate
    • getPushedWordSize

      public byte getPushedWordSize()
      Specified by:
      getPushedWordSize in interface IInstruction
      Returns:
      the JVM word size of the value this instruction pushes onto the stack, or 0 if this instruction doesn't push anything onto the stack.
    • visit

      public abstract void visit(IInstruction.Visitor v)
      Apply a Visitor to this instruction. We invoke the appropriate Visitor method according to the type of this instruction.
      Specified by:
      visit in interface IInstruction
    • toString

      public abstract String toString()
      Subclasses must implement toString.
      Specified by:
      toString in interface IInstruction
      Overrides:
      toString in class Object
    • clone

      public final Object clone()
      We're immutable so there's no need to clone any Instruction object.
      Overrides:
      clone in class Object