3

ASM を使用してクラスにパッチを適用しようとしています。関数にロジックを追加する必要があります。このロジックには新しいローカル変数が必要です。これが私がやったことです:

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ようになります。

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を誤用していると思いますが、どこで呼び出すべきかわかりません。

生成されたバイトコードを (チェックせずに) javap すると、次のローカル変数テーブルが得られます。

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;

お気づきかもしれませんが、私の変数はここにありますが、最上位ですか?! 何か案が ?

4

1 に答える 1

3

新しいローカル変数を作成する便利な方法の 1 つは、MethodAdapter の代わりに LocalVariablesSorter を拡張することです。newLocal()次に、既存の変数に干渉することなく、必要に応じて使用してローカル変数を割り当てることができます。詳細については、ASM ホームページのASM 4.0 A Java バイトコード エンジニアリング ライブラリのセクション 3.3.3 を参照してください。

于 2013-02-07T18:26:46.280 に答える