2015-11-24 1 views
0

Я хочу извлечь возвращаемое значение, это тип org.apache.commons.dbcp.BasicDataSource Как я могу достичь этого в asm?Как получить возвращаемое значение в asm?

Мне нужно получить экземпляр класса org.apache.commons.dbcp.BasicDataSource сразу после его создания в createDataSource(). Поэтому я перейду к этому методу и поставлю байт-код для получения возвращаемого значения.

ответ

0

Для получения фактического значения вам необходимо выполнить или интерпретировать байт-код. Для того, чтобы изменить то, что метод возвращает, последние две команды в методе должны быть:

xload_# 
xreturn 

где х типа

examples:  
//returning an object 
aload 
areturn 

//returning an int 
iload 
ireturn 

и # является индекс переменной в текущем кадре

методы, которые вы можете захотеть взглянуть на это visitBasicVarInstruction/visitVarInstruction (для команды загрузки) visitBasicInstruction (для возвращенной инструкции)

Если вы ш ant, чтобы идти по маршруту выполнения. В ASM вы можете создать класс заглушки, который содержит только метод, который вы хотите выполнить, и поля локального класса, которые ссылаются на метод. Затем, используя ClassWriter, зайдите в созданный вами класс заглушки и напишите его в файл, в который будут загружены байты.
Затем используйте URLClassLoader для загрузки этого файла в jvm, создайте экземпляр этого объекта и вызовите метод через отражение (если вы хотите создать класс во время выполнения); или запишите файл и включите в свой путь сборки, чтобы использовать его во время программирования.

Вариант исполнения ОСОБЕННО упрощен, но это выполнимо (программное обеспечение, которое я пишу, пишет сейчас). Надеюсь, я смогу открыть его или, по крайней мере, выпустить двоичные файлы публично.

0

Я использовал Advice Adapter для получения возвращаемого значения из метода. Метод возвращает значение или исключение throw.Hope ниже кода помогает вам.

import org.objectweb.asm.Label; 
import org.objectweb.asm.MethodVisitor; 
import org.objectweb.asm.Opcodes; 
import org.objectweb.asm.commons.AdviceAdapter; 

public class MyMethodVisitor extends AdviceAdapter{ 

Label startFinally = new Label(); 

public MyMethodVisitor(int access , MethodVisitor mv , String methodName, String description, String className) { 
    super(Opcodes.ASM5 , mv, access, methodName, description); 
} 

public void visitCode() { 
    super.visitCode(); 
    mv.visitLabel(startFinally); 
} 

public void visitMaxs(int maxStack, int maxLocals) { 
    Label endFinally = new Label(); 
    mv.visitTryCatchBlock(startFinally, endFinally, endFinally, null); 
    mv.visitLabel(endFinally); 
    onFinally(Opcodes.ATHROW); 
    mv.visitInsn(Opcodes.ATHROW); 
    super.visitMaxs(maxStack, maxLocals); 
} 

protected void onMethodEnter(){ 
    // If required, add some code when a method begin 
} 

protected void onMethodExit(int opcode){ 
    if(opcode!=ATHROW) { 
     onFinally(opcode); 
    } 
} 

private void onFinally(int opcode) { 
    if(opcode == Opcodes.ATHROW){ 
     mv.visitInsn(Opcodes.DUP); // Exception thrown by the method 
     mv.visitMethodInsn(Opcodes.INVOKESTATIC, "abc/xyz/CatchError", "recordException", "(Ljava/lang/Object)V", false); 
    } 
    else{ 
     mv.visitInsn(Opcodes.DUP); // Return object 
     mv.visitMethodInsn(Opcodes.INVOKESTATIC, "abc/xyz/CatchError", "getReturnObject", "(Ljava/lang/Object)V", false); 
    } 
} 

}

линия на самом деле дает возвращаемый тип - mv.visitInsn (Opcodes.DUP); // Обратный объект

Смежные вопросы