如何使用ASM创建局部变量

如何使用ASM创建局部变量

本文介绍了如何使用ASM创建局部变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用ASM修补类.我需要在函数中添加一些逻辑.此逻辑需要一个新的局部变量.这是我所做的:

I'm trying to patch a class with ASM. I need to add some logic in a function. This logic needs a new local variable. Here is what I've done:

class CreateHashTableMethodAdapter extends MethodAdapter {
    @Override
    public void visitMethodInsn(int opcode, String owner,String name, String desc){
        System.out.println(opcode + "/" + owner + "/" + name + "/" + desc);

        if(opcode == Opcodes.INVOKESPECIAL &&
                "javax/naming/InitialContext".equals(owner) &&
                "<init>".equals(name) &&
                "()V".equals(desc)){

            System.out.println("In mod");
            //  83: new #436; //class javax/naming/InitialContext
            //  86: dup


            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "javax/naming/InitialContext", "<init>", "()V");
            mv.visitVarInsn(Opcodes.ASTORE, 1);

            Label start_patch = new Label();
            Label end_patch = new Label();

            mv.visitLabel(start_patch);



            mv.visitTypeInsn(Opcodes.NEW,"java/util/Hashtable");
            mv.visitInsn(Opcodes.DUP);
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/Hashtable", "<init>", "()V");
            mv.visitVarInsn(Opcodes.ASTORE,9);

            // ........ sNip ..........

            mv.visitLabel(end_patch);
            mv.visitLocalVariable("env","Ljava/util/Hashtable;",null,start_patch,end_patch,9);

            //    127:  astore_1

        }
        else {
            mv.visitMethodInsn(opcode, owner, name, desc);
        }
    }
}

当我针对CheckClassAdapter运行此方法适配器时,状态为:

When I run this method adapter against CheckClassAdapter it states:

org.objectweb.asm.tree.analysis.AnalyzerException: Error at instruction 51: Trying to access an inexistant local variable 9
.... sNiP ....
00050 R R . . .  : R R  :     INVOKESPECIAL java/util/Hashtable.<init> ()V
00051 R R . . .  : R  :     ASTORE 9

我认为我滥用了visitLocalVariable,但是我找不到应该在哪里调用它.

I think I misuse the visitLocalVariable, but I can not find out where I'm supposed to call it.

当我javap生成字节码(不检查)时,我得到以下本地变量表:

When I javap generated bytecode (without checking), I get the following local variables table:

LocalVariableTable:
Start  Length  Slot  Name   Signature
91      40      9    env       Ljava/util/Hashtable;
0      343      0    this       Lpmu/jms/ServerJMS;
132      146      1    initialContext       Ljavax/naming/InitialContext;
153      125      2    topicConnectionFactory       Ljavax/jms/TopicConnectionFactory;
223      55      3    topic       Ljavax/jms/Topic;
249      29      4    topicSubscriber       Ljavax/jms/TopicSubscriber;
279      55      1    ex       Ljava/lang/Exception;
281      53      2    codeMessage       I
289      45      3    params       Lpmu/data/Parameters;
325      9      4    messageError       Ljava/lang/String;

您可能会注意到,我的变量在这里,但是最顶部?!有什么主意吗?

As you may notice, my variable is here but topmost ?!Any idea ?

推荐答案

创建新局部变量的一种便捷方法是扩展LocalVariablesSorter而不是MethodAdapter.然后,您可以使用newLocal()根据需要分配局部变量,而不会干扰现有变量.请参阅 ASM主页上的 ASM 4.0 A Java字节码工程库的3.3.3节. >了解详情.

One convenient way to create new local variables is to extend LocalVariablesSorter instead of MethodAdapter. Then you can allocate local variables as needed using newLocal() without interfering with existing variables. See section 3.3.3 of the ASM 4.0 A Java bytecode engineering library on the ASM homepage for details.

这篇关于如何使用ASM创建局部变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 17:32