Stack map error when iterating over int array with enhanced for-loop

Issue #302 resolved
Jesper Öqvist created an issue

ExtendJ 8.1.1-25-gf6b42914 Java SE 8

ExtendJ generates bad stack map frames for this program:

public class F1 {                  
  public static void main(String[] args) {                            
    int[] x = { 1, 2, 3, };        
    long last = 0;                 
    for (long i : x) {             
      int pow = 3;                 
      last = i;                    
    }                              
    System.out.println(last);      
  }                                
}

Compiling and running the program results in this error:

Exception in thread "main" java.lang.VerifyError: Bad local variable type                                                                    
Exception Details:                 
  Location:                        
    F1.main([Ljava/lang/String;)V @44: lload                          
  Reason:                          
    Type top (current frame, locals[6]) is not assignable to long     
  Current Frame:                   
    bci: @44                       
    flags: { }                     
    locals: { '[Ljava/lang/String;', '[I', long, long_2nd, '[I', integer, top, integer }                                                     
    stack: { } 

Comments (5)

  1. Jesper Öqvist reporter

    This error is caused by the pow variable getting an incorrect local variable index, computed by VariableDeclarator.localNum(). The problem is probably that the enhanced-for statement does not correctly increase the local number count when the loop variable has type long/double.

  2. Jesper Öqvist reporter

    Here is a modified test that is not as likely to be fixed by dead code elimination:

    public class Test {                
      public static void main(String[] args) {                             
        int[] x = { 12321 };           
        long last = 0;                 
        for (long i : x) {             
          int pow = (int)i;            
          System.out.println(i);       
        }                              
      }                                
    }
    
  3. Jesper Öqvist reporter

    The fault is at line 42 in java5/backend/EnhancedForCodegen.jrag:

      eq EnhancedForStmt.getStmt().localNum() =
          getVariableDecl().localNum() + getTypeAccess().type().size();
    

    The variableSize() method should be called, not size().

  4. Jesper Öqvist reporter

    Fix incorrect local index inside for-each

    The SimpleSet.size() attribute was incorrectly used instead of VariableDeclarator.size(), causing incorrect local variable indices inside a for-each loop with a long or double loop variable.

    fixes #302 (bitbucket

    → <<cset ba7e55fd12ab>>

  5. Log in to comment