cit*_*ity 4 java java-bytecode-asm
我使用ASM为while()语句生成字节代码.但是eclipse报道:
Exception in thread "main" java.lang.VerifyError: (class: show_cise_image, method: main signature: ([Ljava/lang/String;)V) Inconsistent stack height 2 != 1
at java.lang.Class.getDeclaredMethods0(Native Method)
..................
Run Code Online (Sandbox Code Playgroud)
我的字节码源代码:
show_cise_image {
boolean flag;
flag = true;
while(flag){
flag = false;
}
}
Run Code Online (Sandbox Code Playgroud)
生成上述代码的字节代码:
/ class version 51.0 (51)
// access flags 0x21
public class show_cise_image {
// access flags 0x8
static int v = 0
// access flags 0x8
static boolean flag = 0
// access flags 0x9
public static main(String[]) : void
L0
LINENUMBER 6 L0
GETSTATIC show_cise_image.flag : boolean
LDC 1
PUTSTATIC show_cise_image.flag : boolean
GOTO L1
L2
GETSTATIC show_cise_image.flag : boolean
LDC 0
PUTSTATIC show_cise_image.flag : boolean
L1
GETSTATIC show_cise_image.flag : boolean
IFNE L2
RETURN
L3
LOCALVARIABLE args String[] L0 L3 2
LOCALVARIABLE x int L0 L3 0
LOCALVARIABLE y int L0 L3 1
MAXSTACK = 3
MAXLOCALS = 3
}
Run Code Online (Sandbox Code Playgroud)
我的java代码生成字节码(我认为这个错误是由while()语句引起的,所以我只发布这部分):
/* while(Expr){ stmt*} */
@Override
public Object visitIterationStmt(IterationStmt iterationStmt, Object arg)
throws Exception {
MethodVisitor mv = (MethodVisitor)arg;
Label guardLabel = new Label();
Label bodyLabel = new Label();
mv.visitJumpInsn(GOTO, guardLabel);
mv.visitLabel(bodyLabel);
for(Stmt t : iterationStmt.stmtList)
t.visit(this, mv); // execute statements in body
mv.visitLabel(guardLabel);
iterationStmt.expr.visit(this, mv); // put the result of expr on stack
mv.visitJumpInsn(IFNE, bodyLabel);
return null;
}
Run Code Online (Sandbox Code Playgroud)
让我们手动分析你的字节码:
L0 ; on entry stack is empty
LINENUMBER 6 L0
GETSTATIC show_cise_image.flag : boolean ; pushes a value, stack height is 1
LDC 1 ; pushes a value, stack heighe is 2
PUTSTATIC show_cise_image.flag : boolean ; pop 1 value, stack height is 1
GOTO L1 ; stack height 1 on going to L1...
L1 ; stack height 1 from previous goto
GETSTATIC show_cise_image.flag : boolean ; pushes a value, stack height is 2
IFNE L2 ; pops 1 value for test, stack height 1 on branch
L2 ; stack height 1 from previous branch
GETSTATIC show_cise_image.flag : boolean ; pushes a value, stack height is 2
LDC 0 ; pushes a value, stack height is 3
PUTSTATIC show_cise_image.flag : boolean ; pops a value, stack height is 2
; fall through to L1 with stack height 2
Run Code Online (Sandbox Code Playgroud)
因此,您在两条路径上的堆栈深度不一致L1,从而导致您看到的验证错误.
在我看来,你的错误是块中的无用'GETSTATIC'字节码L0和L2- 你正在推动flag堆栈的值,但从不对它做任何事情.
| 归档时间: |
|
| 查看次数: |
4196 次 |
| 最近记录: |