in jvm-agent/src/main/org/jetbrains/lincheck/jvm/agent/transformers/InlineMethodCallTransformer.kt [119:175]
override fun visitJumpInsn(opcode: Int, label: Label) {
// This is a jump inside the current inline call
if (!topOfStackEndsBeforeOrAtLabel(label)) {
super.visitJumpInsn(opcode, label)
return
}
// we must not pop the static analysis stack here, as an inline method is not ended here!
// So, only generate injection and don't alter the stack
when (opcode) {
GOTO -> adapter.invokeIfInAnalyzedCode(
original = {},
instrumented = {
// Stop when we jump inside the inline method, comparison is strict because
// "normal" exit code will be generated BEFORE this label (as method epilogue)
exitFromInlineMethods { methodInfo.labels.compare(it.endLabel, label) > 0 }
}
)
IFEQ,
IFNE,
IFLT,
IFGE,
IFGT,
IFLE,
IFNULL,
IFNONNULL -> {
// Duplicate one top category-1 value
adapter.dup()
adapter.invokeIfTrueAndInAnalyzedCode(opcode) {
// Stop when we jump inside the inline method, comparison is strict because
// "normal" exit code will be generated BEFORE this label (as method epilogue)
exitFromInlineMethods { methodInfo.labels.compare(it.endLabel, label) > 0 }
}
}
IF_ICMPEQ,
IF_ICMPNE,
IF_ICMPLT,
IF_ICMPGE,
IF_ICMPGT,
IF_ICMPLE,
IF_ACMPEQ,
IF_ACMPNE -> {
// Duplicate two top category-1 values
adapter.dup2()
adapter.invokeIfTrueAndInAnalyzedCode(opcode) {
// Stop when we jump inside the inline method, comparison is strict because
// "normal" exit code will be generated BEFORE this label (as method epilogue)
exitFromInlineMethods { methodInfo.labels.compare(it.endLabel, label) > 0 }
}
}
JSR -> {}
else -> error("Unknown conditional opcode $opcode")
}
super.visitJumpInsn(opcode, label)
}