繁体   English   中英

导致此错误的原因是:java.lang.VerifyError:堆栈高度不一致2!= 1?

[英]What causes this error : java.lang.VerifyError: Inconsistent stack height 2 != 1?

我使用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)
          ..................

我的字节码源代码:

show_cise_image {
    boolean flag;
    flag =  true;
    while(flag){
        flag = false;   
    }    
}

生成上述代码的字节代码:

/ 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
}

我的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;
    }

让我们手动分析你的字节码:

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

因此,在L1两条路径上存在不一致的堆栈深度,导致您看到的验证错误。

在我看来,你的错误是在L0L2的块中无用的'GETSTATIC'字节码 - 你正在推动堆栈上的flag值,但从不对它做任何事情。

这是因为内置的tomcat编译器。

Eclipse JDT中的Java编译器作为默认编译器包含在内。 它是一个高级Java编译器,它将从Tomcat类加载器加载所有依赖项,这将在编译具有数十个JAR的大型安装时提供极大的帮助。 在快速服务器上,这将允许甚至大型JSP页面的亚秒级重新编译循环。

如果出现任何此类问题,请遵循以下解决方法

只需删除lib / ecj - * .jar文件,并从最新的Ant发行版中放置ant.jar和ant-launcher.jar文件,就可以使用以前的Tomcat版本中使用的Apache Ant代替新编译器。在lib文件夹中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM