Class ActualValueInference.InferenceMethodVisitor
- Enclosing class:
ActualValueInference
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final com.google.common.collect.ImmutableSetMultimap.Builder<Integer, ActualValueInference.StackEntry> The output of this process: a mapping from line number to the root actual values with assertions on that line.private final com.google.common.collect.ImmutableSetMultimap.Builder<com.google.common.collect.ImmutableList<org.objectweb.asm.Label>, ActualValueInference.StackEntry> The mapping that indexes every root actual value by the full list of labels we'd visited before we visited it.private final com.google.common.collect.ImmutableList.Builder<org.objectweb.asm.Label> The ASM labels that we've seen so far, which we use to look up the closest line number for each assertion.private final com.google.common.collect.ImmutableSetMultimap.Builder<org.objectweb.asm.Label, Integer> The mapping from label to line number.private final ArrayList<ActualValueInference.StackEntry> private final StringFor debugging purpose.private final ArrayList<ActualValueInference.StackEntry> private ActualValueInference.FrameInfoprivate booleanSet totruewhenever a method permits multiple execution paths.private booleanFields inherited from class org.objectweb.asm.MethodVisitor
api, mv -
Constructor Summary
ConstructorsConstructorDescriptionInferenceMethodVisitor(int access, String owner, String name, String methodDescriptor, com.google.common.collect.ImmutableSetMultimap.Builder<Integer, ActualValueInference.StackEntry> actualValueAtLine) -
Method Summary
Modifier and TypeMethodDescriptionprivate com.google.common.collect.ImmutableList<ActualValueInference.StackEntry> appendArrayToList(com.google.common.collect.ImmutableList<ActualValueInference.StackEntry> list, int size, Object[] array) private static StringconvertToDescriptor(String type) convertTypeInStackMapFrame(Object typeInStackMapFrame) Convert the type in stack map frame to inference type.private com.google.common.collect.ImmutableList<ActualValueInference.StackEntry> convertTypesInStackMapFrame(int size, Object[] array) private static ArrayList<ActualValueInference.StackEntry> createInitialLocalVariableSlots(int access, String ownerClass, String methodName, String methodDescriptor) Create the slots for local variables at the very beginning of the method with the information of the declaring class and the method descriptor.private ActualValueInference.StackEntrygetLocalVariable(int index) private ActualValueInference.StackEntrygetOperandFromTop(int offsetFromTop) Returns the entry for the operand at the specified offset.private static com.google.common.collect.ImmutableSet<Integer> lineNumbers(com.google.common.collect.ImmutableList<org.objectweb.asm.Label> labels, com.google.common.collect.ImmutableSetMultimap<org.objectweb.asm.Label, Integer> lineNumbersAtLabel) private ActualValueInference.StackEntrypop()private ActualValueInference.StackEntrypop(int count) Pop elements from the end of the operand stack, and return the last popped element.private voidpopDescriptor(String desc) private voidprivate voidprivate voidpushDescriptor(String desc) private voidpushDescriptorAndMaybeProcessMethodCall(String desc, ActualValueInference.Invocation invocation) Pushes entries onto the stack for the given arguments, and, if the descriptor is for a method call, records the assertion made by that call (if any).private voidpushMaybeDescribed(ActualValueInference.InferredType type, ActualValueInference.Invocation invocation, boolean hasParams) private static com.google.common.collect.ImmutableList<ActualValueInference.StackEntry> removeBackFromList(com.google.common.collect.ImmutableList<ActualValueInference.StackEntry> list, int countToRemove) private voidreplaceUninitializedTypeInStack(ActualValueInference.InferredType oldType, ActualValueInference.InferredType newType) private voidsetLocalVariable(int index, ActualValueInference.StackEntry entry) private ActualValueInference.StackEntrytop()voidvoidvisitEnd()voidvisitFieldInsn(int opcode, String owner, String name, String desc) voidvisitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) voidvisitIincInsn(int var, int increment) voidvisitInsn(int opcode) voidvisitIntInsn(int opcode, int operand) voidvisitInvokeDynamicInsn(String name, String desc, org.objectweb.asm.Handle bsm, Object... bsmArgs) voidvisitJumpInsn(int opcode, org.objectweb.asm.Label label) voidvisitLabel(org.objectweb.asm.Label label) voidvisitLdcInsn(Object cst) voidvisitLineNumber(int line, org.objectweb.asm.Label start) voidvisitLookupSwitchInsn(org.objectweb.asm.Label dflt, int[] keys, org.objectweb.asm.Label[] labels) voidvisitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) voidvisitMultiANewArrayInsn(String desc, int dims) voidvisitTableSwitchInsn(int min, int max, org.objectweb.asm.Label dflt, org.objectweb.asm.Label... labels) voidvisitTryCatchBlock(org.objectweb.asm.Label start, org.objectweb.asm.Label end, org.objectweb.asm.Label handler, String type) voidvisitTypeInsn(int opcode, String type) voidvisitVarInsn(int opcode, int var) Methods inherited from class org.objectweb.asm.MethodVisitor
getDelegate, visitAnnotableParameterCount, visitAnnotation, visitAnnotationDefault, visitAttribute, visitInsnAnnotation, visitLocalVariable, visitLocalVariableAnnotation, visitMaxs, visitMethodInsn, visitParameter, visitParameterAnnotation, visitTryCatchAnnotation, visitTypeAnnotation
-
Field Details
-
used
private boolean used -
localVariableSlots
-
operandStack
-
previousFrame
-
methodSignature
For debugging purpose. -
labelsSeen
private final com.google.common.collect.ImmutableList.Builder<org.objectweb.asm.Label> labelsSeenThe ASM labels that we've seen so far, which we use to look up the closest line number for each assertion. -
lineNumbersAtLabel
private final com.google.common.collect.ImmutableSetMultimap.Builder<org.objectweb.asm.Label,Integer> lineNumbersAtLabelThe mapping from label to line number.I had hoped that we didn't need this: In the
.classfiles I looked at,visitLineNumbercalls were interleaved with the actual instructions. (I even have evidence that the current implementation visits labels and line numbers together: See Label.accept.) If that were guaranteed, then we could identify the line number for each assertion just by looking at whichvisitLineNumbercall we'd seen most recently. However, that doesn't appear to be guaranteed, so we store this mapping and then join it with the labels at the end.I would expect to be able to use a map here. But I'm seeing multiple line numbers for the same label in some Kotlin code.
-
actualValueAtLocation
private final com.google.common.collect.ImmutableSetMultimap.Builder<com.google.common.collect.ImmutableList<org.objectweb.asm.Label>,ActualValueInference.StackEntry> actualValueAtLocationThe mapping that indexes every root actual value by the full list of labels we'd visited before we visited it. -
seenJump
private boolean seenJumpSet totruewhenever a method permits multiple execution paths. -
actualValueAtLine
private final com.google.common.collect.ImmutableSetMultimap.Builder<Integer,ActualValueInference.StackEntry> actualValueAtLineThe output of this process: a mapping from line number to the root actual values with assertions on that line. This builder is potentially shared across multiple method visitors for the same class visitor.
-
-
Constructor Details
-
InferenceMethodVisitor
InferenceMethodVisitor(int access, String owner, String name, String methodDescriptor, com.google.common.collect.ImmutableSetMultimap.Builder<Integer, ActualValueInference.StackEntry> actualValueAtLine)
-
-
Method Details
-
visitCode
public void visitCode()- Overrides:
visitCodein classorg.objectweb.asm.MethodVisitor
-
visitEnd
public void visitEnd()- Overrides:
visitEndin classorg.objectweb.asm.MethodVisitor
-
lineNumbers
-
visitLineNumber
public void visitLineNumber(int line, org.objectweb.asm.Label start) - Overrides:
visitLineNumberin classorg.objectweb.asm.MethodVisitor
-
visitLabel
public void visitLabel(org.objectweb.asm.Label label) - Overrides:
visitLabelin classorg.objectweb.asm.MethodVisitor
-
getOperandFromTop
Returns the entry for the operand at the specified offset. 0 means the top of the stack. -
visitInsn
public void visitInsn(int opcode) - Overrides:
visitInsnin classorg.objectweb.asm.MethodVisitor
-
visitIntInsn
public void visitIntInsn(int opcode, int operand) - Overrides:
visitIntInsnin classorg.objectweb.asm.MethodVisitor
-
visitVarInsn
public void visitVarInsn(int opcode, int var) - Overrides:
visitVarInsnin classorg.objectweb.asm.MethodVisitor
-
visitTypeInsn
- Overrides:
visitTypeInsnin classorg.objectweb.asm.MethodVisitor
-
visitFieldInsn
- Overrides:
visitFieldInsnin classorg.objectweb.asm.MethodVisitor
-
visitMethodInsn
- Overrides:
visitMethodInsnin classorg.objectweb.asm.MethodVisitor
-
visitInvokeDynamicInsn
public void visitInvokeDynamicInsn(String name, String desc, org.objectweb.asm.Handle bsm, Object... bsmArgs) - Overrides:
visitInvokeDynamicInsnin classorg.objectweb.asm.MethodVisitor
-
visitJumpInsn
public void visitJumpInsn(int opcode, org.objectweb.asm.Label label) - Overrides:
visitJumpInsnin classorg.objectweb.asm.MethodVisitor
-
visitLdcInsn
- Overrides:
visitLdcInsnin classorg.objectweb.asm.MethodVisitor
-
visitIincInsn
public void visitIincInsn(int var, int increment) - Overrides:
visitIincInsnin classorg.objectweb.asm.MethodVisitor
-
visitTableSwitchInsn
public void visitTableSwitchInsn(int min, int max, org.objectweb.asm.Label dflt, org.objectweb.asm.Label... labels) - Overrides:
visitTableSwitchInsnin classorg.objectweb.asm.MethodVisitor
-
visitLookupSwitchInsn
public void visitLookupSwitchInsn(org.objectweb.asm.Label dflt, int[] keys, org.objectweb.asm.Label[] labels) - Overrides:
visitLookupSwitchInsnin classorg.objectweb.asm.MethodVisitor
-
visitTryCatchBlock
public void visitTryCatchBlock(org.objectweb.asm.Label start, org.objectweb.asm.Label end, org.objectweb.asm.Label handler, String type) - Overrides:
visitTryCatchBlockin classorg.objectweb.asm.MethodVisitor
-
visitMultiANewArrayInsn
- Overrides:
visitMultiANewArrayInsnin classorg.objectweb.asm.MethodVisitor
-
visitFrame
- Overrides:
visitFramein classorg.objectweb.asm.MethodVisitor
-
convertToDescriptor
-
push
-
push
-
replaceUninitializedTypeInStack
private void replaceUninitializedTypeInStack(ActualValueInference.InferredType oldType, ActualValueInference.InferredType newType) -
pushDescriptor
-
pushDescriptorAndMaybeProcessMethodCall
private void pushDescriptorAndMaybeProcessMethodCall(String desc, ActualValueInference.Invocation invocation) Pushes entries onto the stack for the given arguments, and, if the descriptor is for a method call, records the assertion made by that call (if any).If the descriptor is for a call, this method not only records the assertion made by it (if any) but also examines its parameters to generate more detailed stack entries.
- Parameters:
desc- the descriptor of the type to be added to the stack (or the descriptor of the method whose return value is to be added to the stack)invocation- the method invocation being visited, ornullif a non-method descriptor is being visited
-
pushMaybeDescribed
private void pushMaybeDescribed(ActualValueInference.InferredType type, ActualValueInference.Invocation invocation, boolean hasParams) -
pop
-
pop
Pop elements from the end of the operand stack, and return the last popped element. -
popDescriptor
-
getLocalVariable
-
setLocalVariable
-
top
-
createInitialLocalVariableSlots
private static ArrayList<ActualValueInference.StackEntry> createInitialLocalVariableSlots(int access, String ownerClass, String methodName, String methodDescriptor) Create the slots for local variables at the very beginning of the method with the information of the declaring class and the method descriptor. -
removeBackFromList
private static com.google.common.collect.ImmutableList<ActualValueInference.StackEntry> removeBackFromList(com.google.common.collect.ImmutableList<ActualValueInference.StackEntry> list, int countToRemove) -
appendArrayToList
private com.google.common.collect.ImmutableList<ActualValueInference.StackEntry> appendArrayToList(com.google.common.collect.ImmutableList<ActualValueInference.StackEntry> list, int size, Object[] array) -
convertTypeInStackMapFrame
Convert the type in stack map frame to inference type. -
convertTypesInStackMapFrame
private com.google.common.collect.ImmutableList<ActualValueInference.StackEntry> convertTypesInStackMapFrame(int size, Object[] array)
-