2017-09-14 11 views
0

Javassistコード属性を編集するためのCodeIteratorを提供します。この属性は、メソッド内のすべての命令を横断するために使用できます。 JVM命令のJVM命令がJavassistで操作するオペランドスタックの値を取得する方法は?

、それは常にspecificationを次の バイナリアセンブリは異なり mnemonic operand1 operand2 ... 、スタックベースのJVMの命令は、オペランドスタック上の値をとります。例としてifgeを取る。命令は次の形式を持ちます if<cond> branchbyte1 branchbyte2 がスタック0以上の場合にのみ、branchbyte1およびbranchbyte2がジャンプのターゲットになります。

私の質問は、Javassistを使用してオペランドスタックにvalueを得ることができますか?

+1

この仕様では「オペランド」とは言わず、「オペランドスタック」と言います。 JVMは仕様レベルでスタックベースのアーキテクチャを持ち、 "オペランド"はスタックからポップされます。 –

+0

@ErwinBolwidtご清聴ありがとうございました。 「命令によって使用されるオペランドスタックから値を取得する」と言うのは正しいですか? – Qoros

+0

私は仕事のためにASMを使用することを好むでしょうが、とにかく質問は不明です。スタックにはオペランドと値の両方がありますが、どちらの場合でも、各命令にどのオペランドとパラメータがあるかがわかります。それはあなたがリンクしている仕様書に書かれています... – Holger

答えて

0

答えはjavassist.bytecode.analysisモジュールです。 JVM仕様によると、frameは、データと部分的な結果を格納するために使用されます。各フレームには、独自のローカル変数の配列、独自のオペランドスタック、および実行時constプールへの参照があります。

javassist.bytecode.analysis.FramePrinterには、各命令でフレームごとに印刷する方法が表示されています(print)。このコードから

/** 
* Prints the instructions and the frame states of the given method. 
*/ 
public void print(CtMethod method) { 
    stream.println("\n" + getMethodString(method)); 
    MethodInfo info = method.getMethodInfo2(); 
    ConstPool pool = info.getConstPool(); 
    CodeAttribute code = info.getCodeAttribute(); 
    if (code == null) 
     return; 

    Frame[] frames; 
    try { 
     frames = (new Analyzer()).analyze(method.getDeclaringClass(), info); 
    } catch (BadBytecode e) { 
     throw new RuntimeException(e); 
    } 

    int spacing = String.valueOf(code.getCodeLength()).length(); 

    CodeIterator iterator = code.iterator(); 
    while (iterator.hasNext()) { 
     int pos; 
     try { 
      pos = iterator.next(); 
     } catch (BadBytecode e) { 
      throw new RuntimeException(e); 
     } 

     stream.println(pos + ": " + InstructionPrinter.instructionString(iterator, pos, pool)); 

     addSpacing(spacing + 3); 
     Frame frame = frames[pos]; 
     if (frame == null) { 
      stream.println("--DEAD CODE--"); 
      continue; 
     } 
     printStack(frame); 

     addSpacing(spacing + 3); 
     printLocals(frame); 
    } 

} 

我々が見ることができ、:

をフレームがframes = (new Analyzer()).analyze(method.getDeclaringClass(), info);

NOTEにより取得することができ、これが唯一のスタック項目の型情報を返しますが、それは与えるものではありません変数名。

各命令が使用する値については、命令の仕様に従って異なる方法で扱う必要があります。

関連する問題