77import static com .datadog .debugger .instrumentation .ASMHelper .invokeVirtual ;
88import static com .datadog .debugger .instrumentation .ASMHelper .isFinalField ;
99import static com .datadog .debugger .instrumentation .ASMHelper .isStaticField ;
10+ import static com .datadog .debugger .instrumentation .ASMHelper .isStore ;
1011import static com .datadog .debugger .instrumentation .ASMHelper .ldc ;
1112import static com .datadog .debugger .instrumentation .ASMHelper .newInstance ;
1213import static com .datadog .debugger .instrumentation .Types .CAPTURED_CONTEXT_TYPE ;
6869import org .slf4j .LoggerFactory ;
6970
7071public class CapturedContextInstrumentor extends Instrumentor {
71- private static final Logger log = LoggerFactory .getLogger (CapturedContextInstrumentor .class );
72+ private static final Logger LOGGER = LoggerFactory .getLogger (CapturedContextInstrumentor .class );
7273 private final boolean captureSnapshot ;
7374 private final Limits limits ;
7475 private final LabelNode contextInitLabel = new LabelNode ();
@@ -639,8 +640,8 @@ private void rewriteLocalVarInsn(LocalVariableNode localVar, int oldSlot, int ne
639640 // 10: astore_1
640641 // 11: aload_1
641642 // range for slot 1 starts at 11
642- // javac always starts the range right after the init of the local var, so we can just look for
643- // the previous instruction
643+ // javac often starts the range right after the init of the local var, so we can just look for
644+ // the previous instruction. But not always, and we put an arbitrary limit to 10 instructions
644645 // for kotlinc, many instructions can separate the init and the range start
645646 // ex:
646647 // LocalVariableTable:
@@ -656,18 +657,26 @@ private void rewriteLocalVarInsn(LocalVariableNode localVar, int oldSlot, int ne
656657 private static void rewritePreviousStoreInsn (
657658 LocalVariableNode localVar , int oldSlot , int newSlot ) {
658659 AbstractInsnNode previous = localVar .start .getPrevious ();
659- while (previous != null
660- && (!(previous instanceof VarInsnNode ) || ((VarInsnNode ) previous ).var != oldSlot )) {
660+ int processed = 0 ;
661+ // arbitrary fixing limit to 10 previous instructions to look at
662+ while (previous != null && !isVarStoreForSlot (previous , oldSlot ) && processed < 10 ) {
661663 previous = previous .getPrevious ();
664+ processed ++;
662665 }
663- if (previous != null ) {
666+ if (isVarStoreForSlot ( previous , oldSlot ) ) {
664667 VarInsnNode varInsnNode = (VarInsnNode ) previous ;
665668 if (varInsnNode .var == oldSlot ) {
666669 varInsnNode .var = newSlot ;
667670 }
668671 }
669672 }
670673
674+ private static boolean isVarStoreForSlot (AbstractInsnNode node , int slotIdx ) {
675+ return node instanceof VarInsnNode
676+ && isStore (node .getOpcode ())
677+ && ((VarInsnNode ) node ).var == slotIdx ;
678+ }
679+
671680 private void createInProbeFinallyHandler (LabelNode inProbeStartLabel , LabelNode inProbeEndLabel ) {
672681 LabelNode handlerLabel = new LabelNode ();
673682 InsnList handler = new InsnList ();
@@ -1234,7 +1243,7 @@ private static void addInheritedStaticFields(
12341243 FieldNode fieldNode =
12351244 new FieldNode (field .getModifiers (), field .getName (), desc , null , field );
12361245 results .add (fieldNode );
1237- log .debug ("Adding static inherited field {}" , fieldNode .name );
1246+ LOGGER .debug ("Adding static inherited field {}" , fieldNode .name );
12381247 fieldCount ++;
12391248 if (fieldCount > limits .maxFieldCount ) {
12401249 return ;
0 commit comments