下面列出了org.objectweb.asm.tree.analysis.Frame#getStackSize ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
static void printAnalyzerResult(
final MethodNode method, final Analyzer<BasicValue> analyzer, final PrintWriter printWriter) {
Textifier textifier = new Textifier();
TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(textifier);
printWriter.println(method.name + method.desc);
for (int i = 0; i < method.instructions.size(); ++i) {
method.instructions.get(i).accept(traceMethodVisitor);
StringBuilder stringBuilder = new StringBuilder();
Frame<BasicValue> frame = analyzer.getFrames()[i];
if (frame == null) {
stringBuilder.append('?');
} else {
for (int j = 0; j < frame.getLocals(); ++j) {
stringBuilder.append(getUnqualifiedName(frame.getLocal(j).toString())).append(' ');
}
stringBuilder.append(" : ");
for (int j = 0; j < frame.getStackSize(); ++j) {
stringBuilder.append(getUnqualifiedName(frame.getStack(j).toString())).append(' ');
}
}
while (stringBuilder.length() < method.maxStack + method.maxLocals + 1) {
stringBuilder.append(' ');
}
printWriter.print(Integer.toString(i + 100000).substring(1));
printWriter.print(
" " + stringBuilder + " : " + textifier.text.get(textifier.text.size() - 1));
}
for (TryCatchBlockNode tryCatchBlock : method.tryCatchBlocks) {
tryCatchBlock.accept(traceMethodVisitor);
printWriter.print(" " + textifier.text.get(textifier.text.size() - 1));
}
printWriter.println();
}
public boolean isThisTargetOfGet(int index) {
Frame<ConstructorThisInterpreter.ThisValue> frame = this.frames[index];
// Note that we will treat this as safe, even on invalid bytecode (we handle the stack underflow).
int size = frame.getStackSize();
return (size > 0)
? frame.getStack(size - 1).isThis
: false;
}
public boolean isThisTargetOfPut(int index) {
Frame<ConstructorThisInterpreter.ThisValue> frame = this.frames[index];
// Note that we will treat this as safe, even on invalid bytecode (we handle the stack underflow).
int size = frame.getStackSize();
return (size > 1)
? frame.getStack(size - 2).isThis
: false;
}
static void printAnalyzerResult(MethodNode method, Analyzer<BasicValue> a, final PrintWriter pw) {
Frame<BasicValue>[] frames = a.getFrames();
Textifier t = new Textifier();
TraceMethodVisitor mv = new TraceMethodVisitor(t);
pw.println(method.name + method.desc);
for (int j = 0; j < method.instructions.size(); ++j) {
method.instructions.get(j).accept(mv);
StringBuilder sb = new StringBuilder();
Frame<BasicValue> f = frames[j];
if (f == null) {
sb.append('?');
} else {
for (int k = 0; k < f.getLocals(); ++k) {
sb.append(getShortName(f.getLocal(k).toString())).append(' ');
}
sb.append(" : ");
for (int k = 0; k < f.getStackSize(); ++k) {
sb.append(getShortName(f.getStack(k).toString())).append(' ');
}
}
while (sb.length() < method.maxStack + method.maxLocals + 1) {
sb.append(' ');
}
pw.print(Integer.toString(j + 100000).substring(1));
pw.print(" " + sb + " : " + t.text.get(t.text.size() - 1));
}
for (int j = 0; j < method.tryCatchBlocks.size(); ++j) {
method.tryCatchBlocks.get(j).accept(mv);
pw.print(" " + t.text.get(t.text.size() - 1));
}
pw.println();
}
static void printAnalyzerResult(
final MethodNode method, final Analyzer<BasicValue> analyzer, final PrintWriter printWriter) {
Textifier textifier = new Textifier();
TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(textifier);
printWriter.println(method.name + method.desc);
for (int i = 0; i < method.instructions.size(); ++i) {
method.instructions.get(i).accept(traceMethodVisitor);
StringBuilder stringBuilder = new StringBuilder();
Frame<BasicValue> frame = analyzer.getFrames()[i];
if (frame == null) {
stringBuilder.append('?');
} else {
for (int j = 0; j < frame.getLocals(); ++j) {
stringBuilder.append(getUnqualifiedName(frame.getLocal(j).toString())).append(' ');
}
stringBuilder.append(" : ");
for (int j = 0; j < frame.getStackSize(); ++j) {
stringBuilder.append(getUnqualifiedName(frame.getStack(j).toString())).append(' ');
}
}
while (stringBuilder.length() < method.maxStack + method.maxLocals + 1) {
stringBuilder.append(' ');
}
printWriter.print(Integer.toString(i + 100000).substring(1));
printWriter.print(
" " + stringBuilder + " : " + textifier.text.get(textifier.text.size() - 1));
}
for (TryCatchBlockNode tryCatchBlock : method.tryCatchBlocks) {
tryCatchBlock.accept(traceMethodVisitor);
printWriter.print(" " + textifier.text.get(textifier.text.size() - 1));
}
printWriter.println();
}
static void printAnalyzerResult(
final MethodNode method, final Analyzer<BasicValue> analyzer, final PrintWriter printWriter) {
Textifier textifier = new Textifier();
TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(textifier);
printWriter.println(method.name + method.desc);
for (int i = 0; i < method.instructions.size(); ++i) {
method.instructions.get(i).accept(traceMethodVisitor);
StringBuilder stringBuilder = new StringBuilder();
Frame<BasicValue> frame = analyzer.getFrames()[i];
if (frame == null) {
stringBuilder.append('?');
} else {
for (int j = 0; j < frame.getLocals(); ++j) {
stringBuilder.append(getUnqualifiedName(frame.getLocal(j).toString())).append(' ');
}
stringBuilder.append(" : ");
for (int j = 0; j < frame.getStackSize(); ++j) {
stringBuilder.append(getUnqualifiedName(frame.getStack(j).toString())).append(' ');
}
}
while (stringBuilder.length() < method.maxStack + method.maxLocals + 1) {
stringBuilder.append(' ');
}
printWriter.print(Integer.toString(i + 100000).substring(1));
printWriter.print(
" " + stringBuilder + " : " + textifier.text.get(textifier.text.size() - 1));
}
for (TryCatchBlockNode tryCatchBlock : method.tryCatchBlocks) {
tryCatchBlock.accept(traceMethodVisitor);
printWriter.print(" " + textifier.text.get(textifier.text.size() - 1));
}
printWriter.println();
}
@Test
public void examineTestConstructor() throws Exception {
MethodNode node = buildTestConstructor();
Analyzer<ConstructorThisInterpreter.ThisValue> analyzer = new Analyzer<>(new ConstructorThisInterpreter());
Frame<ConstructorThisInterpreter.ThisValue>[] frames = analyzer.analyze(ConstructorThisInterpreterTest.class.getName(), node);
// Below are the totals derived from manually inspecting the bytecode below and how we interact with it.
int bytecodeCount = 17;
int explicitFrameCount = 2;
int labelCount = 2;
Assert.assertEquals(bytecodeCount + explicitFrameCount + labelCount, frames.length);
// To make this clear (since this is not obvious), we write the frame stacks.
for (Frame<ConstructorThisInterpreter.ThisValue> frame : frames) {
int size = frame.getStackSize();
report(size + ": ");
for (int i = size; i > 0; --i) {
ConstructorThisInterpreter.ThisValue val = frame.getStack(i-1);
String value = (null != val)
? (val.isThis ? "T" : "F")
: "_";
report(value);
}
reportLine();
}
// Now, verify the top of the stack at each bytecode.
int index = 0;
Assert.assertEquals(null, peekStackTop(frames[index++]));
// ALOAD
Assert.assertEquals(true, peekStackTop(frames[index++]).isThis);
// INVOKESPECIAL
Assert.assertEquals(null, peekStackTop(frames[index++]));
// ICONST_5
Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
// ILOAD
Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
// IF_ICMPNE
Assert.assertEquals(null, peekStackTop(frames[index++]));
// ALOAD
Assert.assertEquals(true, peekStackTop(frames[index++]).isThis);
// GOTO
Assert.assertEquals(null, peekStackTop(frames[index++]));
// (label)
Assert.assertEquals(null, peekStackTop(frames[index++]));
// (frame)
Assert.assertEquals(null, peekStackTop(frames[index++]));
// ALOAD
Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
// (label)
Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
// (frame)
Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
// ILOAD
Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
// PUTFIELD
Assert.assertEquals(null, peekStackTop(frames[index++]));
// ALOAD
Assert.assertEquals(true, peekStackTop(frames[index++]).isThis);
// ICONST_1
Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
// PUTFIELD
Assert.assertEquals(null, peekStackTop(frames[index++]));
// ALOAD
Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
// ICONST_2
Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
// PUTFIELD
Assert.assertEquals(null, peekStackTop(frames[index++]));
// RETURN
Assert.assertEquals(frames.length, index);
}
@Test
public void examineSecondConstructor() throws Exception {
MethodNode node = buildSecondConstructor();
Analyzer<ConstructorThisInterpreter.ThisValue> analyzer = new Analyzer<>(new ConstructorThisInterpreter());
Frame<ConstructorThisInterpreter.ThisValue>[] frames = analyzer.analyze(ConstructorThisInterpreterTest.class.getName(), node);
// Below are the totals derived from manually inspecting the bytecode below and how we interact with it.
int bytecodeCount = 6;
int explicitFrameCount = 0;
int labelCount = 0;
Assert.assertEquals(bytecodeCount + explicitFrameCount + labelCount, frames.length);
// To make this clear (since this is not obvious), we write the frame stacks.
for (Frame<ConstructorThisInterpreter.ThisValue> frame : frames) {
int size = frame.getStackSize();
report(size + ": ");
for (int i = size; i > 0; --i) {
ConstructorThisInterpreter.ThisValue val = frame.getStack(i-1);
String value = (null != val)
? (val.isThis ? "T" : "F")
: "_";
report(value);
}
reportLine();
}
// Now, verify the top of the stack at each bytecode.
int index = 0;
Assert.assertEquals(null, peekStackTop(frames[index++]));
// ALOAD
Assert.assertEquals(true, peekStackTop(frames[index++]).isThis);
// ALOAD
Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
// PUTFIELD
Assert.assertEquals(null, peekStackTop(frames[index++]));
// ALOAD
Assert.assertEquals(true, peekStackTop(frames[index++]).isThis);
// INVOKESPECIAL
Assert.assertEquals(null, peekStackTop(frames[index++]));
// RETURN
Assert.assertEquals(frames.length, index);
}
private ConstructorThisInterpreter.ThisValue peekStackTop(Frame<ConstructorThisInterpreter.ThisValue> frame) {
int size = frame.getStackSize();
return (size > 0)
? frame.getStack(size - 1)
: null;
}