0

BCIにasmを使用しようとしましたが、「if条件」を挿入する必要があるため、以下のようなものを使用してみました

 Below is the code snippet..if i comment the jump instruction things work fine..with jump instruction i see verifyerror

@Override
protected void onMethodEnter() {
    try{            
    visitor.visitVarInsn(ALOAD, 0);
    visitor.visitFieldInsn(GETFIELD, "com/vish/MyWrapper", "isCached", "Z");
    Label jump = new Label();
    visitor.visitJumpInsn(IFEQ,jump);
    visitor.visitMethodInsn(Opcodes.INVOKESTATIC, MyConstants.TO_HELPER_CLASS, "sayHello","(Z)V");
    visitor.visitVarInsn(ALOAD, 0);
    visitor.visitInsn(ICONST_1);
    visitFieldInsn(PUTFIELD, "com/vish/MyWrapper", "isCached", "Z");
    visitor.visitLabel(jump);
    visitor.visitVarInsn(ALOAD, 0);
    visitor.visitFieldInsn(GETFIELD, "com/vish/MyWrapper", "isCached", "Z");
    visitor.visitMethodInsn(Opcodes.INVOKESTATIC, MyConstants.TO_HELPER_CLASS, "sayHello",
            "()V");
    }catch(Exception e){
        e.printStackTrace();
    }
}

しかし、実行しようとすると、以下の例外が発生します

java.lang.VerifyError: JVMVRFY036 stack underflow; class=com/vish/MyWrapper, method=service()V, pc=10
       at java.lang.J9VMInternals.verifyImpl(Native Method)
       at java.lang.J9VMInternals.verify(J9VMInternals.java:72)
       at java.lang.J9VMInternals.verify(J9VMInternals.java:70)
       at java.lang.J9VMInternals.initialize(J9VMInternals.java:134)

ジャンプ命令にコメントすると、問題なく動作します。

私はいくつかの読書を行い、JumpInstructions の使用のためにスタック マップ フレームが混乱する可能性があることを知りました。

"public static final int COMPUTE_FRAMES メソッドのスタック マップ フレームをゼロから自動的に計算するフラグ。このフラグが設定されている場合、MethodVisitor.visitFrame(int, int, java.lang.Object[], int, java. lang.Object[]) メソッドは無視され、スタック マップ フレームはメソッドのバイトコードから再計算されます。visitMaxs メソッドの引数も無視され、バイトコードから再計算されます。つまり、computeFrames は computeMaxs を意味します。"

誰が私が何を間違っているのかを明らかにすることができます..ジャンプ命令の場合、スタックマップフレームを計算する必要がありますか?その場合、スタックマップフレームを計算する方法のどこかでサンプルを取得できますか??

ありがとう

4

2 に答える 2

1

ここで導入された命令:

visitor.visitMethodInsn(Opcodes.INVOKESTATIC, MyConstants.TO_HELPER_CLASS, "sayHello","(Z)V");

...スタックにブール (整数) パラメーターが必要です。が存在する場合IFEQ、スタックは空です。をコメントアウトするIFEQと、スタックにパラメータが含まれます。スタック アンダーフローは、スタックに必要なパラメーターを指定せずにメソッドを呼び出すことによって発生します。これは、スタック フレーム マップとは関係ありません。

于 2013-10-30T17:49:59.227 に答える
1

問題は、最初の引数が欠落していることですsayHello。結果を渡したい場合は、その前にgetCached別のものを追加する必要があります。visitor.visitFieldInsn(GETFIELD, "com/vish/MyWrapper", "isCached", "Z");

これが意図されたものであると仮定すると、コードは次のようになります。

visitor.visitVarInsn(ALOAD, 0);
visitor.visitFieldInsn(GETFIELD, "com/vish/MyWrapper", "isCached", "Z");
Label jump = new Label();
visitor.visitJumpInsn(IFEQ,jump);
visitor.visitFieldInsn(GETFIELD, "com/vish/MyWrapper", "isCached", "Z");
visitor.visitMethodInsn(Opcodes.INVOKESTATIC, MyConstants.TO_HELPER_CLASS, "sayHello","(Z)V");
visitor.visitVarInsn(ALOAD, 0);
visitor.visitInsn(ICONST_1);
visitFieldInsn(PUTFIELD, "com/vish/MyWrapper", "isCached", "Z");
visitor.visitLabel(jump);
visitor.visitVarInsn(ALOAD, 0);
visitor.visitFieldInsn(GETFIELD, "com/vish/MyWrapper", "isCached", "Z");
visitor.visitMethodInsn(Opcodes.INVOKESTATIC, MyConstants.TO_HELPER_CLASS, "sayHello",
        "()V");
于 2013-10-30T17:50:09.253 に答える