Package edu.umd.cs.findbugs
Class OpcodeStack
- java.lang.Object
-
- edu.umd.cs.findbugs.OpcodeStack
-
public class OpcodeStack extends java.lang.Object
tracks the types and numbers of objects that are currently on the operand stack throughout the execution of method. To use, a detector should instantiate one for each method, and callstack.sawOpcode(this,seen);
at the bottom of their sawOpcode method. at any point you can then inspect the stack and see what the types of objects are on the stack, including constant values if they were pushed. The types described are of course, only the static types. There are some outstanding opcodes that have yet to be implemented, I couldn't find any code that actually generated these, so i didn't put them in because I couldn't test them:- dup2_x2
- jsr_w
- wide
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interface
OpcodeStack.CustomUserValue
You can put this annotation on a OpcodeStack detector to indicate that it usesOpcodeStack.Item.userValue
, and thus should not reuse generic OpcodeStack information from an iterative evaluation of the opcode stack.(package private) static class
OpcodeStack.HttpParameterInjection
static class
OpcodeStack.Item
static class
OpcodeStack.JumpInfo
static class
OpcodeStack.JumpInfoFactory
-
Field Summary
Fields Modifier and Type Field Description (package private) boolean
backwardsBranch
(package private) static java.util.HashMap<java.lang.String,java.lang.String>
boxedTypes
(package private) int
convertJumpToOneZeroState
(package private) int
convertJumpToZeroOneState
private static boolean
DEBUG
private static boolean
DEBUG2
(package private) boolean
encountedTop
(package private) java.util.BitSet
exceptionHandlers
private static java.util.Map<org.apache.commons.lang3.tuple.Pair<java.lang.String,java.lang.String>,java.lang.String>
IMMUTABLE_RETURNER_MAP
private static java.lang.String
JAVA_UTIL_ARRAYS_ARRAY_LIST
private static java.lang.String
JAVA_UTIL_COLLECTIONS
private java.util.Map<java.lang.Integer,java.util.List<OpcodeStack.Item>>
jumpEntries
private java.util.BitSet
jumpEntryLocations
private boolean
jumpInfoChangedByBackwardsBranch
private boolean
jumpInfoChangedByNewTarget
private java.util.Map<java.lang.Integer,java.util.List<OpcodeStack.Item>>
jumpStackEntries
private java.util.List<java.lang.Integer>
lastUpdate
private java.util.List<OpcodeStack.Item>
lvValues
private java.lang.String
methodName
(package private) boolean
needToMerge
(package private) boolean
oneMeansNull
private boolean
reachOnlyByBranch
(package private) int
registerTestedFoundToBeNonnegative
private boolean
seenTransferOfControl
private java.util.List<OpcodeStack.Item>
stack
private boolean
top
private boolean
useIterativeAnalysis
(package private) DismantleBytecode
v
(package private) int
zeroOneComing
-
Constructor Summary
Constructors Constructor Description OpcodeStack()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description private static void
addBoxedType(java.lang.Class<?>... clss)
private void
addJumpValue(int from, int target)
void
clear()
(package private) void
clearJumpInfoChangedByBackwardsBranch()
(package private) void
clearJumpInfoChangedByNewTarget()
private static void
clearRegisterLoad(java.util.List<OpcodeStack.Item> list, int register)
private double
constantToDouble(OpcodeStack.Item it)
private float
constantToFloat(OpcodeStack.Item it)
private int
constantToInt(OpcodeStack.Item it)
private long
constantToLong(OpcodeStack.Item it)
private void
eraseKnowledgeOf(XField fieldOperand)
private org.apache.bcel.classfile.BootstrapMethod
getBootstrapMethod(org.apache.bcel.classfile.Attribute[] attribs, org.apache.bcel.classfile.Constant index)
static java.lang.String
getExceptionSig(DismantleBytecode dbc, org.apache.bcel.classfile.CodeException e)
OpcodeStack.Item
getItemMethodInvokedOn(DismantleBytecode dbc)
private OpcodeStack.JumpInfo
getJumpInfo()
private StackMapAnalyzer.JumpInfoFromStackMap
getJumpInfoFromStackMap()
int
getLastUpdate(int reg)
OpcodeStack.Item
getLVValue(int index)
int
getNumLastUpdates()
int
getNumLocalValues()
int
getStackDepth()
OpcodeStack.Item
getStackItem(int stackOffset)
private java.lang.String
getStringFromIndex(DismantleBytecode dbc, int i)
private void
handleDcmp(int opcode)
private void
handleDup()
private void
handleDup2()
private void
handleDup2X1()
private void
handleDup2X2()
private void
handleDupX1()
private void
handleDupX2()
private void
handleFcmp(int opcode)
private void
handleLcmp()
private void
handleSwap()
boolean
hasIncomingBranches(int pc)
void
initialize()
(package private) boolean
isJumpInfoChangedByBackwardsBranch()
protected boolean
isJumpInfoChangedByNewTarget()
boolean
isJumpTarget(int pc)
private boolean
isMethodThatReturnsGivenReference(java.lang.String clsName, java.lang.String methodName)
(package private) boolean
isReachOnlyByBranch()
boolean
isTop()
void
learnFrom(OpcodeStack.JumpInfo info)
private void
markConstantValueUnknown(OpcodeStack.Item item)
void
mergeJumps(DismantleBytecode dbc)
private boolean
mergeLists(java.util.List<OpcodeStack.Item> mergeInto, java.util.List<OpcodeStack.Item> mergeFrom, boolean errorIfSizesDoNotMatch)
(package private) int
nullSafeSize(java.util.Collection<?> c)
private OpcodeStack.Item
pop()
private void
pop(int count)
void
precomputation(DismantleBytecode dbc)
void
printJumpEntries()
private void
processInvokeDynamic(DismantleBytecode dbc)
private void
processMethodCall(DismantleBytecode dbc, int seen)
private void
push(OpcodeStack.Item i)
private void
pushByConstant(DismantleBytecode dbc, org.apache.bcel.classfile.Constant c)
private void
pushByDoubleMath(int seen, OpcodeStack.Item it, OpcodeStack.Item it2)
private void
pushByFloatMath(int seen, OpcodeStack.Item it, OpcodeStack.Item it2)
private void
pushByIntMath(DismantleBytecode dbc, int seen, OpcodeStack.Item lhs, OpcodeStack.Item rhs)
private void
pushByInvoke(DismantleBytecode dbc, boolean popThis)
private void
pushByLocalLoad(java.lang.String signature, int register)
private void
pushByLocalObjectLoad(DismantleBytecode dbc, int register)
private void
pushByLocalStore(int register)
private void
pushByLongMath(int seen, OpcodeStack.Item lhs, OpcodeStack.Item rhs)
private void
pushBySignature(java.lang.String s, DismantleBytecode dbc)
void
replace(int stackOffset, OpcodeStack.Item value)
void
replaceTop(OpcodeStack.Item newTop)
int
resetForMethodEntry(DismantleBytecode visitor)
private int
resetForMethodEntry0(PreorderVisitor visitor)
(package private) int
resetForMethodEntry0(java.lang.String className, org.apache.bcel.classfile.Method m)
void
sawOpcode(DismantleBytecode dbc, int seen)
void
setJumpInfoChangedByBackwardBranch(java.lang.String kind, int from, int to)
(package private) void
setJumpInfoChangedByBackwardsBranch(int from, int to)
protected void
setJumpInfoChangedByNewTarget()
private void
setLastUpdate(int reg, int pc)
private void
setLVValue(int index, OpcodeStack.Item value)
(package private) void
setReachOnlyByBranch(boolean reachOnlyByBranch)
private void
setTop(boolean top)
private OpcodeStack.Item
top()
java.lang.String
toString()
-
-
-
Field Detail
-
JAVA_UTIL_ARRAYS_ARRAY_LIST
private static final java.lang.String JAVA_UTIL_ARRAYS_ARRAY_LIST
- See Also:
- Constant Field Values
-
JAVA_UTIL_COLLECTIONS
private static final java.lang.String JAVA_UTIL_COLLECTIONS
- See Also:
- Constant Field Values
-
DEBUG
private static final boolean DEBUG
-
DEBUG2
private static final boolean DEBUG2
-
IMMUTABLE_RETURNER_MAP
private static final java.util.Map<org.apache.commons.lang3.tuple.Pair<java.lang.String,java.lang.String>,java.lang.String> IMMUTABLE_RETURNER_MAP
-
boxedTypes
@StaticConstant static final java.util.HashMap<java.lang.String,java.lang.String> boxedTypes
-
stack
private java.util.List<OpcodeStack.Item> stack
-
lvValues
private java.util.List<OpcodeStack.Item> lvValues
-
lastUpdate
private final java.util.List<java.lang.Integer> lastUpdate
-
top
private boolean top
-
seenTransferOfControl
private boolean seenTransferOfControl
-
useIterativeAnalysis
private final boolean useIterativeAnalysis
-
encountedTop
boolean encountedTop
-
backwardsBranch
boolean backwardsBranch
-
exceptionHandlers
java.util.BitSet exceptionHandlers
-
jumpInfoChangedByBackwardsBranch
private boolean jumpInfoChangedByBackwardsBranch
-
jumpInfoChangedByNewTarget
private boolean jumpInfoChangedByNewTarget
-
jumpEntries
private java.util.Map<java.lang.Integer,java.util.List<OpcodeStack.Item>> jumpEntries
-
jumpStackEntries
private java.util.Map<java.lang.Integer,java.util.List<OpcodeStack.Item>> jumpStackEntries
-
jumpEntryLocations
private java.util.BitSet jumpEntryLocations
-
convertJumpToOneZeroState
int convertJumpToOneZeroState
-
convertJumpToZeroOneState
int convertJumpToZeroOneState
-
registerTestedFoundToBeNonnegative
int registerTestedFoundToBeNonnegative
-
zeroOneComing
int zeroOneComing
-
oneMeansNull
boolean oneMeansNull
-
needToMerge
boolean needToMerge
-
reachOnlyByBranch
private boolean reachOnlyByBranch
-
methodName
private java.lang.String methodName
-
-
Method Detail
-
toString
public java.lang.String toString()
- Overrides:
toString
in classjava.lang.Object
-
hasIncomingBranches
public boolean hasIncomingBranches(int pc)
-
getExceptionSig
public static java.lang.String getExceptionSig(DismantleBytecode dbc, org.apache.bcel.classfile.CodeException e)
-
mergeJumps
public void mergeJumps(DismantleBytecode dbc)
-
setLastUpdate
private void setLastUpdate(int reg, int pc)
-
getLastUpdate
public int getLastUpdate(int reg)
-
getNumLastUpdates
public int getNumLastUpdates()
-
sawOpcode
public void sawOpcode(DismantleBytecode dbc, int seen)
-
eraseKnowledgeOf
private void eraseKnowledgeOf(XField fieldOperand)
-
precomputation
public void precomputation(DismantleBytecode dbc)
-
constantToInt
private int constantToInt(OpcodeStack.Item it)
-
constantToFloat
private float constantToFloat(OpcodeStack.Item it)
-
constantToDouble
private double constantToDouble(OpcodeStack.Item it)
-
constantToLong
private long constantToLong(OpcodeStack.Item it)
-
handleDcmp
private void handleDcmp(int opcode)
-
handleFcmp
private void handleFcmp(int opcode)
-
handleLcmp
private void handleLcmp()
-
handleSwap
private void handleSwap()
-
handleDup
private void handleDup()
-
handleDupX1
private void handleDupX1()
-
handleDup2
private void handleDup2()
-
handleDup2X1
private void handleDup2X1()
-
handleDup2X2
private void handleDup2X2()
-
handleDupX2
private void handleDupX2()
-
addBoxedType
private static void addBoxedType(java.lang.Class<?>... clss)
-
markConstantValueUnknown
private void markConstantValueUnknown(OpcodeStack.Item item)
-
processMethodCall
private void processMethodCall(DismantleBytecode dbc, int seen)
-
isMethodThatReturnsGivenReference
private boolean isMethodThatReturnsGivenReference(java.lang.String clsName, java.lang.String methodName)
-
processInvokeDynamic
private void processInvokeDynamic(DismantleBytecode dbc)
-
getBootstrapMethod
private org.apache.bcel.classfile.BootstrapMethod getBootstrapMethod(org.apache.bcel.classfile.Attribute[] attribs, org.apache.bcel.classfile.Constant index)
-
mergeLists
private boolean mergeLists(java.util.List<OpcodeStack.Item> mergeInto, java.util.List<OpcodeStack.Item> mergeFrom, boolean errorIfSizesDoNotMatch)
-
clear
public void clear()
-
printJumpEntries
public void printJumpEntries()
-
isJumpTarget
public boolean isJumpTarget(int pc)
-
addJumpValue
private void addJumpValue(int from, int target)
-
learnFrom
public void learnFrom(OpcodeStack.JumpInfo info)
-
initialize
public void initialize()
-
resetForMethodEntry
public int resetForMethodEntry(DismantleBytecode visitor)
-
nullSafeSize
int nullSafeSize(@CheckForNull java.util.Collection<?> c)
-
getJumpInfo
private OpcodeStack.JumpInfo getJumpInfo()
-
getJumpInfoFromStackMap
private StackMapAnalyzer.JumpInfoFromStackMap getJumpInfoFromStackMap()
-
setJumpInfoChangedByBackwardBranch
public void setJumpInfoChangedByBackwardBranch(java.lang.String kind, int from, int to)
-
resetForMethodEntry0
private int resetForMethodEntry0(PreorderVisitor visitor)
-
resetForMethodEntry0
int resetForMethodEntry0(@SlashedClassName java.lang.String className, org.apache.bcel.classfile.Method m)
-
getStackDepth
public int getStackDepth()
-
getStackItem
public OpcodeStack.Item getStackItem(int stackOffset)
-
pop
private OpcodeStack.Item pop()
-
top
private OpcodeStack.Item top()
-
replace
public void replace(int stackOffset, OpcodeStack.Item value)
-
replaceTop
public void replaceTop(OpcodeStack.Item newTop)
-
pop
private void pop(int count)
-
push
private void push(OpcodeStack.Item i)
-
pushByConstant
private void pushByConstant(DismantleBytecode dbc, org.apache.bcel.classfile.Constant c)
-
pushByLocalObjectLoad
private void pushByLocalObjectLoad(DismantleBytecode dbc, int register)
-
pushByIntMath
private void pushByIntMath(DismantleBytecode dbc, int seen, OpcodeStack.Item lhs, OpcodeStack.Item rhs)
-
pushByLongMath
private void pushByLongMath(int seen, OpcodeStack.Item lhs, OpcodeStack.Item rhs)
-
pushByFloatMath
private void pushByFloatMath(int seen, OpcodeStack.Item it, OpcodeStack.Item it2)
-
pushByDoubleMath
private void pushByDoubleMath(int seen, OpcodeStack.Item it, OpcodeStack.Item it2)
-
pushByInvoke
private void pushByInvoke(DismantleBytecode dbc, boolean popThis)
-
getItemMethodInvokedOn
public OpcodeStack.Item getItemMethodInvokedOn(DismantleBytecode dbc)
-
getStringFromIndex
private java.lang.String getStringFromIndex(DismantleBytecode dbc, int i)
-
pushBySignature
private void pushBySignature(java.lang.String s, DismantleBytecode dbc)
-
pushByLocalStore
private void pushByLocalStore(int register)
-
clearRegisterLoad
private static void clearRegisterLoad(java.util.List<OpcodeStack.Item> list, int register)
-
pushByLocalLoad
private void pushByLocalLoad(java.lang.String signature, int register)
-
setLVValue
private void setLVValue(int index, OpcodeStack.Item value)
-
getLVValue
@Nonnull public OpcodeStack.Item getLVValue(int index)
-
getNumLocalValues
public int getNumLocalValues()
-
setTop
private void setTop(boolean top)
-
isTop
public boolean isTop()
-
setReachOnlyByBranch
void setReachOnlyByBranch(boolean reachOnlyByBranch)
-
isReachOnlyByBranch
boolean isReachOnlyByBranch()
-
isJumpInfoChangedByBackwardsBranch
boolean isJumpInfoChangedByBackwardsBranch()
-
clearJumpInfoChangedByBackwardsBranch
void clearJumpInfoChangedByBackwardsBranch()
-
setJumpInfoChangedByBackwardsBranch
void setJumpInfoChangedByBackwardsBranch(int from, int to)
-
isJumpInfoChangedByNewTarget
protected boolean isJumpInfoChangedByNewTarget()
- Returns:
- Returns the jumpInfoChangedByNewTarget.
-
clearJumpInfoChangedByNewTarget
void clearJumpInfoChangedByNewTarget()
-
setJumpInfoChangedByNewTarget
protected void setJumpInfoChangedByNewTarget()
-
-