Closed Bug 203841 Opened 21 years ago Closed 21 years ago

Bad code generation to merge "if" and boolean expressions

Categories

(Rhino Graveyard :: Compiler, defect)

x86
Windows 2000
defect
Not set
normal

Tracking

(Not tracked)

VERIFIED FIXED

People

(Reporter: briang, Assigned: norrisboyd)

Details

Attachments

(1 file)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.0.2) Gecko/20021216
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.0.2) Gecko/20021216

When using a comma operator inside an if statement in non-interpreted mode, as
in the following example,

if (a = 5, b == 6) { c = 1; }

Rhino throws this exception:

Exception in thread "main" java.lang.IllegalStateException: Stack underflow: -1
        at org.mozilla.classfile.ClassFileWriter.badStack(ClassFileWriter.java:1154)
        at org.mozilla.classfile.ClassFileWriter.add(ClassFileWriter.java:401)
        at org.mozilla.javascript.optimizer.Codegen.addByteCode(Codegen.java:3568)
        at org.mozilla.javascript.optimizer.Codegen.visitGOTO(Codegen.java:1574)
        at
org.mozilla.javascript.optimizer.Codegen.generateCodeFromNode(Codegen.java:1172)
        at
org.mozilla.javascript.optimizer.Codegen.generateCodeFromNode(Codegen.java:1044)
        at
org.mozilla.javascript.optimizer.Codegen.generateCodeFromNode(Codegen.java:1044)
        at org.mozilla.javascript.optimizer.Codegen.generateCode(Codegen.java:409)
        at org.mozilla.javascript.optimizer.Codegen.compile(Codegen.java:137)
        at org.mozilla.javascript.Context.compile(Context.java:1916)
        at org.mozilla.javascript.Context.compileReader(Context.java:886)
        at org.mozilla.javascript.Context.evaluateReader(Context.java:803)
        at org.mozilla.javascript.tools.shell.Main.evaluateReader(Main.java:363)
        at org.mozilla.javascript.tools.shell.Main.processSource(Main.java:260)
        at org.mozilla.javascript.tools.shell.Main.exec(Main.java:103)
        at org.mozilla.javascript.tools.shell.Main.main(Main.java:76)

Reproducible: Always

Steps to Reproduce:
1. use the js> shell
2. Enter the following:

js> Packages.org.mozilla.javascript.Context.enter().setOptimizationLevel(1);
js> if (a = 5, b==6} { return false; }

Actual Results:  
Got this exception:

org.mozilla.javascript.optimizer.Codegen.generateCode(Codegen.java:409)
        at org.mozilla.javascript.optimizer.Codegen.compile(Codegen.java:137)
        at org.mozilla.javascript.Context.compile(Context.java:1916)
        at org.mozilla.javascript.Context.compileReader(Context.java:886)
        at org.mozilla.javascript.Context.evaluateReader(Context.java:803)
        at org.mozilla.javascript.tools.shell.Main.evaluateReader(Main.java:363)
        at org.mozilla.javascript.tools.shell.Main.processSource(Main.java:260)
        at org.mozilla.javascript.tools.shell.Main.exec(Main.java:103)
        at org.mozilla.javascript.tools.shell.Main.main(Main.java:76)

Expected Results:  
No exception

This isn't a problem in interpreted mode.
Confirming bug; cc'ing Igor -
Testcase added to JS testsuite:

      mozilla/js/tests/js1_5/Regress/regress-203841.js


Currently passing in SpiderMonkey and Rhino interpreted mode.
But crashing in any optimized Rhino mode, with the above stack.
I changed the subject since the same problem persists not only with comma
operator cases like:

if (1, 1 == 6) ;

but also with the following cases"

// get elem case
x=[];
if (x[1==2]) ;

// set elem case
if (x[1==2]=1) ;

// delete elem case
if (delete x[1==2]) ;


All these cases caused by incorrect code generation optimization to merger
evaluation of boolean expressions like x == y, a && b etc. with generation code
for conditional jumps like code for if statements, ? operator etc.

In fact these test cases are produced by looking for the code of
generateCodeFromNode in  omj/optimizer/Codegen.java.
Summary: If statement containing embedded comma operator generates Stack underflow: -1 exception → Bad code generation to merge "if" and boolean expressions
To fix the issue I moved away from generateCodeFromNode code to merge boolean
checks and conditional jumps into separated generateIfJump method that tries to
apply this optimization and if it is not possible, it calls
generateCodeFromNode and adds a generic jump.
Attachment #122121 - Attachment description: Fix for Codegen.java: for conditional jumps are processed in new generateIfJump method → Fix for Codegen.java: conditional jumps are processed in new generateIfJump method
I've added Igor's new examples from Comment #3 to the testcase.
Once again, passing in SpiderMonkey and in Rhino interpreted mode,
but failing in Rhino compiled modes.
I committed the fix. By "if and boolean checks merger" I mean special code in
the optimizer not to generate Boolean object just to convert them to boolean on
JVM stack later when generating bytecode for conditional jumps but rather use
IFLE etc. bytecode to compare and jump skipping intermediate steps. 

Hopefully the fix closed all the problems with the optimization.

Status: NEW → RESOLVED
Closed: 21 years ago
Resolution: --- → FIXED
Verified FIXED.

The above testcase now passes not only in Rhino interpreted mode,
but in optimized modes as well.
Status: RESOLVED → VERIFIED
Targeting as resolved against 1.5R5
Target Milestone: --- → 1.5R5
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: