Tôi muốn viết một MethodVisitor biến đổi các lệnh LDC dành cho phép nhân.ASM: Chuyển đổi trạng thái
Ví dụ bytecode:
ldC#26
imul
này về cơ bản đẩy một hằng số và sau đó sẽ nhân nó.
Nó phải là một sự chuyển đổi trạng thái vì trước tiên tôi phải kiểm tra xem nó có nhân và, nếu có, tôi cần quay trở lại lệnh ldc và sửa đổi hằng số. Tôi không hoàn toàn chắc chắn làm thế nào tôi sẽ đi về điều này, và tôi không biết làm thế nào để sửa đổi các hằng số (khi tôi đã cố gắng để vượt qua một giá trị khác nhau, giá trị cũ vẫn còn trong hồ bơi liên tục).
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);
}
}
}
Đây là những gì tôi có, nhưng nó không loại bỏ các giá trị cũ trong hồ bơi thường xuyên, và nó có thể có lỗi.
Tôi đã quan tâm tìm kiếm một giải pháp bằng cách sử dụng API khách truy cập, vì ASM đã làm cho nó khá rõ ràng rằng nó được khuyến khích. Tuy nhiên, nếu API cây là lựa chọn tốt hơn trong trường hợp này, tôi sẽ xem xét nó. Cảm ơn. – someguy
Sử dụng API khách truy cập như bạn hiện tại, bạn không thể thay thế hằng số tại chỗ; bạn phải thêm mã bổ sung vào luồng để bật giá trị cũ và đẩy một giá trị mới. Có lẽ bạn nên, tuy nhiên, nhìn vào subclassing ClassWriter; có một vài phương pháp ảo bạn có thể ghi đè thỏa thuận đó bằng cách viết hằng số, mặc dù nó có thể hơi phức tạp để xác minh bạn chỉ đang sửa đổi hằng số bạn dự định. – oldrinb