Я хочу написать MethodVisitor, который преобразует команды LDC, которые предназначены для умножения.ASM: Stateful Transformation
Пример байткод:
ldC#26
imul
В основном это толкает постоянное, а затем умножает его.
Это должно быть преобразование с состоянием, потому что я сначала должен проверить, что он предназначен для умножения, и, если это так, мне нужно вернуться к инструкции ldc и изменить константу. Я не совсем уверен, как это сделать, и я не знаю, как изменить константу (когда я попытался передать другое значение, старое значение все еще оставалось в постоянном пуле).
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);
}
}
}
Это то, что у меня есть, но это не снимает старое значение в постоянном пуле, и это может иметь ошибки.
Я был заинтересован в поиске решения с использованием API-интерфейса посетителя, так как ASM довольно ясно дала понять, что это рекомендуется. Однако, если API дерева является лучшим выбором в этом случае, я рассмотрю его. Благодарю. – someguy
Используя API-интерфейс посетителя, как вы сейчас, вы не можете просто заменить константу на месте; вам придется добавить дополнительный код к потоку, чтобы поместить старое значение и нажать новый. Возможно, вам следует, однако, изучить подклассификацию ClassWriter; существует несколько виртуальных методов, которые вы можете переопределить, имея дело с константами записи, хотя может быть немного сложно проверить, что вы изменяете только константу, которую вы собираетесь использовать. – oldrinb