Skip to content

Commit

Permalink
Fix constant field name finding
Browse files Browse the repository at this point in the history
Follows asm commit [172221565c4347060d79285f183cdbca72344616](https://gitlab.ow2.org/asm/asm/-/commit/172221565c4347060d79285f183cdbca72344616) which changed behavior
  • Loading branch information
IotaBread committed Sep 29, 2024
1 parent e2977e4 commit 56b282b
Showing 1 changed file with 61 additions and 10 deletions.
71 changes: 61 additions & 10 deletions src/main/java/org/quiltmc/enigma_plugin/util/AsmUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,13 @@
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.ParameterNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import org.objectweb.asm.tree.analysis.Frame;
import org.objectweb.asm.tree.analysis.SourceValue;
import org.objectweb.asm.util.Textifier;
import org.objectweb.asm.util.TraceMethodVisitor;

import java.io.PrintWriter;
import java.util.Optional;
import java.util.function.Predicate;

Expand Down Expand Up @@ -185,30 +189,34 @@ public static AbstractInsnNode searchInsnInStack(InsnList insns, AbstractInsnNod
}
}

if (!shallow && lastStackInsn != null && lastStackInsn.getOpcode() == NEW && lastStackInsn.getNext() != null && lastStackInsn.getNext().getOpcode() == DUP) {
// Find the last frame containing the DUP instruction
var dup = lastStackInsn.getNext();
int searchFrameIndex = insns.indexOf(dup) + 1;
if (!shallow && lastStackInsn != null && lastStackInsn.getOpcode() == DUP && lastStackInsn.getPrevious() != null && lastStackInsn.getPrevious().getOpcode() == NEW) {
// Find the last frame containing two DUP instructions in the stack
// This used to search a single DUP following a NEW, but ASM commit 172221565c4347060d79285f183cdbca72344616
// changed the behavior for DUPS to replace the previous value
// Stack before: ..., NEW ..., DUP; after: ..., DUP, DUP
int searchFrameIndex = insns.indexOf(lastStackInsn) + 1;
var searchFrame = frames[searchFrameIndex];

while (searchFrame != null && searchFrameIndex <= frameIndex) {
boolean contains = false;
int count = 0;
for (int j = 0; j < searchFrame.getStackSize(); j++) {
if (frame.getStack(j).insns.contains(dup)) {
contains = true;
break;
if (frame.getStack(j).insns.contains(lastStackInsn)) {
count++;
if (count == 2) {
break;
}
}
}

if (contains) {
if (count == 2) {
searchFrameIndex++;
if (searchFrameIndex < frames.length) {
searchFrame = frames[searchFrameIndex];
} else {
searchFrame = null;
}
} else {
var insn = insns.get(searchFrameIndex - 1); // This was the last instruction with a frame with a dup
var insn = insns.get(searchFrameIndex - 1); // This was the last instruction with a frame with two dups
if (insn != frameInsn) {
return searchInsnInStack(insns, insn, frames, insnPredicate, false);
}
Expand Down Expand Up @@ -264,4 +272,47 @@ public static FieldInsnNode searchStaticFieldReferenceInStack(InsnList insns, Ab

return null;
}

public static void printFrames(MethodNode method, Frame<SourceValue>[] frames, PrintWriter printWriter) {
Textifier textifier = new Textifier();
TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(textifier);

printWriter.println(method.name + method.desc);
for (int i = 0; i < method.instructions.size(); ++i) {
StringBuilder stringBuilder = new StringBuilder();
Frame<SourceValue> frame = frames[i];
if (frame == null) {
stringBuilder.append('?');
} else {
for (int j = 0; j < frame.getLocals(); ++j) {
stringBuilder.append('[')
.append(frame.getLocal(j).insns.stream().map(insn -> method.instructions.indexOf(insn) + 100000)
.map(k -> String.valueOf(k).substring(1))
.reduce((a, b) -> a + ", " + b).orElse("?"))
.append("] ");
}
stringBuilder.append(" : ");
for (int j = 0; j < frame.getStackSize(); ++j) {
stringBuilder.append('[')
.append(frame.getStack(j).insns.stream().map(insn -> method.instructions.indexOf(insn) + 100000)
.map(k -> String.valueOf(k).substring(1))
.reduce((a, b) -> a + ", " + b).orElse("?"))
.append("] ");
}
}
while (stringBuilder.length() < method.maxStack + method.maxLocals + 1) {
stringBuilder.append(' ');
}
printWriter.print(Integer.toString(i + 100000).substring(1));

method.instructions.get(i).accept(traceMethodVisitor);
printWriter.print(
" " + stringBuilder + " : " + textifier.text.get(textifier.text.size() - 1));
}
for (TryCatchBlockNode tryCatchBlock : method.tryCatchBlocks) {
tryCatchBlock.accept(traceMethodVisitor);
printWriter.print(" " + textifier.text.get(textifier.text.size() - 1));
}
printWriter.println();
}
}

0 comments on commit 56b282b

Please sign in to comment.