VerifyError when compiling

ASSIGNED
Assigned to

Status

Rhino
Compiler
--
major
ASSIGNED
10 years ago
10 years ago

People

(Reporter: Nathan Clement, Assigned: Norris Boyd)

Tracking

Details

Attachments

(4 attachments)

(Reporter)

Description

10 years ago
User-Agent:       Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648)
Build Identifier: 1.7R1

The code below produces a VerifyError for some scripts.

    context.setGeneratingDebug( true ); 
    context.setOptimizationLevel( 0 ); 
    this.script = context.compileReader( reader, fileName, 1, null ); 

The error details are as follows:

java.lang.VerifyError: (class: org/mozilla/javascript/gen/c3, method: _c1 signature: (Lorg/mozilla/javascript/gen/c3;Lorg/mozilla/javascript/Context;Lorg/mozilla/javascript/Scriptable;Lorg/mozilla/javascript/Scriptable;[Ljava/lang/Object;)Ljava/lang/Object;) Accessing value from uninitialized register 9 
  at java.lang.Class.getDeclaredConstructors0(Native Method) 
  at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389) 
  at java.lang.Class.getConstructor0(Class.java:2699) 
  at java.lang.Class.newInstance0(Class.java:326) 
  at java.lang.Class.newInstance(Class.java:308) 
  at org.mozilla.javascript.optimizer.Codegen.createScriptObject(Codegen.java:106) 
  at org.mozilla.javascript.Context.compileImpl(Context.java:2293) 
  at org.mozilla.javascript.Context.compileReader(Context.java:1202) 
  at org.mozilla.javascript.Context.compileReader(Context.java:1174) 


Reproducible: Always

Steps to Reproduce:
1. Execute the following code with the attached source code.

    context.setGeneratingDebug( true ); 
    context.setOptimizationLevel( 0 ); 
    this.script = context.compileReader( reader, fileName, 1, null ); 

Actual Results:  
java.lang.VerifyError: (class: org/mozilla/javascript/gen/c3, method: _c1 signature: (Lorg/mozilla/javascript/gen/c3;Lorg/mozilla/javascript/Context;Lorg/mozilla/javascript/Scriptable;Lorg/mozilla/javascript/Scriptable;[Ljava/lang/Object;)Ljava/lang/Object;) Accessing value from uninitialized register 9 
  at java.lang.Class.getDeclaredConstructors0(Native Method) 
  at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389) 
  at java.lang.Class.getConstructor0(Class.java:2699) 
  at java.lang.Class.newInstance0(Class.java:326) 
  at java.lang.Class.newInstance(Class.java:308) 
  at org.mozilla.javascript.optimizer.Codegen.createScriptObject(Codegen.java:106) 
  at org.mozilla.javascript.Context.compileImpl(Context.java:2293) 
  at org.mozilla.javascript.Context.compileReader(Context.java:1202) 
  at org.mozilla.javascript.Context.compileReader(Context.java:1174) 


Expected Results:  
A Script object is returned from compileReader
(Reporter)

Comment 1

10 years ago
Created attachment 335448 [details]
The script file that produces the VerifyError
(Assignee)

Updated

10 years ago
Assignee: nobody → norrisboyd
(Assignee)

Updated

10 years ago
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
Created attachment 354476 [details]
Smaller test case that results in a VerifyError
Created attachment 354678 [details]
Disassembly of the offending method

This is the output from javap on the class file the jsc creates for my reduced test case.  I've added instruction numbers in square brackets in front of each instruction.
Created attachment 354685 [details]
Debugging output from the OpenJDK verifier

This is the debugging output of the dataflow analysis stage of the verifier.  The format is pretty much a series of:

  Instruction x: (stack){locals}<...>  (stack'){locals'}<...> [i j ...]
    i:(stack){locals}<...>  (stack){locals}<...>
    j:(stack){locals}<...>  (stack){locals}<...>
    ...

Each of these entries shows, for the instruction numbered x, what the known types of the stack operands and local registers are before and after the instruction would be executed.  In square brackets is the list of instructions that can possibly follow this one (asterisked ones are jumps due to exceptions), which are then listed below on indented lines, showing their known stack/locals type information before and after merging knowledge of stack/locals types after instruction x is looked at.  "xx" means that type information is not known at that point.

The debugging output shows that it cannot prove that register 8 actually has an object reference in it when reaching instruction 40 (which is the 'aload 8' at offset 76).  This is because the verifier does not distinguish between the 'jsr 104' instructions (at offsets 26, 98 and 186) that the 'ret 7' at offset 176 could possibly return to.  You can see this in lines 212-215 of the debugging output.  All possible states of the types in the stack/locals are merged for these different jsrs.

So even though there's actually no way (as far as I've been able to trace through the bytecode) for the 'astore 8' at offset 24 not to be run (i.e., an exception occurs before it) and for the 'ret 7' later on to return to offset 16 (at which point another exception would have to occur, jumping to offset 74, after which the 'aload 8' instruction would run), the verifier cannot prove it.
You need to log in before you can comment on or make changes to this bug.