答えは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により取得することができ、これが唯一のスタック項目の型情報を返しますが、それは与えるものではありません変数名。
各命令が使用する値については、命令の仕様に従って異なる方法で扱う必要があります。
この仕様では「オペランド」とは言わず、「オペランドスタック」と言います。 JVMは仕様レベルでスタックベースのアーキテクチャを持ち、 "オペランド"はスタックからポップされます。 –
@ErwinBolwidtご清聴ありがとうございました。 「命令によって使用されるオペランドスタックから値を取得する」と言うのは正しいですか? – Qoros
私は仕事のためにASMを使用することを好むでしょうが、とにかく質問は不明です。スタックにはオペランドと値の両方がありますが、どちらの場合でも、各命令にどのオペランドとパラメータがあるかがわかります。それはあなたがリンクしている仕様書に書かれています... – Holger