JDK-8134490 : Dead var statement evacuation incorrectly descends into nested functions
  • Type: Bug
  • Component: core-libs
  • Sub-Component: jdk.nashorn
  • Affected Version: 8u60,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_8
  • CPU: x86
  • Submitted: 2015-08-25
  • Updated: 2016-02-02
  • Resolved: 2015-09-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u72Fixed 9 b84Fixed
Description
FULL PRODUCT VERSION :
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) Client VM (build 25.60-b23, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.3.9600]

A DESCRIPTION OF THE PROBLEM :
While executing a JavaScript code with nashorn executable (jjs.exe), an exception is thrown.

Probably it caused by a dead code elimination while pre-processing the JavaScript file.

This bug might be related to previously reported bug (reported by me few days ago, JI-9023716).

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
save the attaches source code as program.js and run in windows command:
jjs.exe program.js

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
in
out
ACTUAL -
in
Exception in thread "main" java.lang.ClassCastException: Cannot cast jdk.nashorn.internal.runtime.Undefined to jdk.nashorn.internal.runtime.ScriptFunction
        at java.lang.invoke.MethodHandleImpl.newClassCastException(Unknown Source)
        at java.lang.invoke.MethodHandleImpl.castReference(Unknown Source)
        at jdk.nashorn.internal.scripts.Script$code.:program(code.js:11)
        at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:640)
        at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:228)
        at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
        at jdk.nashorn.tools.Shell.apply(Shell.java:397)
        at jdk.nashorn.tools.Shell.runScripts(Shell.java:326)
        at jdk.nashorn.tools.Shell.run(Shell.java:172)
        at jdk.nashorn.tools.Shell.main(Shell.java:136)
        at jdk.nashorn.tools.Shell.main(Shell.java:112)

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.ClassCastException: Cannot cast jdk.nashorn.internal.runtime.Undefined to jdk.nashorn.internal.runtime.ScriptFunction
        at java.lang.invoke.MethodHandleImpl.newClassCastException(Unknown Source)
        at java.lang.invoke.MethodHandleImpl.castReference(Unknown Source)
        at jdk.nashorn.internal.scripts.Script$code.:program(code.js:11)
        at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:640)
        at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:228)
        at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
        at jdk.nashorn.tools.Shell.apply(Shell.java:397)
        at jdk.nashorn.tools.Shell.runScripts(Shell.java:326)
        at jdk.nashorn.tools.Shell.run(Shell.java:172)
        at jdk.nashorn.tools.Shell.main(Shell.java:136)
        at jdk.nashorn.tools.Shell.main(Shell.java:112)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
print("in");
var v1;

function f1()
{
	v1 = 1;
	return true;
	(function () { var v1; })();
}

f1();
print("out");
---------- END SOURCE ----------


Comments
The culprit was in Lower. We have code that evacuates VarNodes from the part of the function identified as dead code, as they still need to be effected as declarations, as they are scoped to the whole function. E.g. this: function f() { x = 1; return x; var x = 2; } is effectively transformed into: function f() { x = 1; return x; var x; } so that "x" is recognized as a local and not global variable. The problem was that the visitor looking for var declarations in dead code was also descending into nested functions, so "var v1" in the anonymous nested function got evacuated into f1.
24-09-2015

I can reproduce this issue with jdk8u-dev tip and jdk9-dev tip.
01-09-2015

Attached test case ran from Command line as: jjs.exe program.js JDK 8u60 - fail JDK 9eab78 - fail On commenting the dead code, it does work as expected. Moving to dev-team for confirming if this is due to dead code elimination and taking further action.
26-08-2015