Chcę napisać MethodVisitor, który przekształca instrukcje LDC, które są dla mnożenia.ASM: Stateful Transformation
Przykład bajtowy:
ldC#26
imul
Zasadniczo popycha stały i następnie mnoży się.
Musi to być transformacja stanowa, ponieważ najpierw muszę sprawdzić, czy jest ona dla mnożenia, a jeśli tak jest, muszę wrócić do instrukcji ldc i zmodyfikować stałą. Nie jestem do końca pewny, jak to zrobić, i nie wiem, jak modyfikować stałą (kiedy próbowałem przekazać inną wartość, stara wartość nadal pozostawała w puli stałej).
Edit:
public class AdditionTransformer extends MethodAdapter {
boolean replace = false;
int operand = 0;
AdditionTransformer(MethodVisitor mv) {
super(mv);
}
@Override
public void visitInsn(int opcode) {
if (opcode == IMUL && replace) {
operand *= 2;
visitLdcInsn(operand);
replace = false;
}
mv.visitInsn(opcode);
}
@Override
public void visitLdcInsn(Object cst) {
if (cst instanceof Integer && !replace) {
operand = (Integer) cst;
replace = true;
} else {
mv.visitLdcInsn(cst);
}
}
}
To co mam, ale nie usunąć starą wartość w stałej puli i może zawierać błędy.
Bardzo chciałem znaleźć rozwiązanie za pomocą interfejsu API odwiedzającego, ponieważ ASM stwierdziło, że jest to zalecane. Jednakże, jeśli API drzewa jest lepszym wyborem w tym przypadku, zajrzę do niego. Dzięki. – someguy
Korzystając z interfejsu API gościa, jakim jesteś teraz, nie możesz po prostu zastąpić stałej w miejscu; musisz dodać do strumienia dodatkowy kod, aby wypchnąć starą wartość i wcisnąć nową. Być może jednak powinieneś zajrzeć do podklasy ClassWriter; istnieje kilka wirtualnych metod, które można przesłonić, mając do czynienia ze stałą zapisu, chociaż może być trochę skomplikowane, aby sprawdzić, czy modyfikujesz tylko stałą, którą chcesz. – oldrinb