JDK-8044750 : megamorphic getter for scope objects does not call __noSuchProperty__ hook
  • Type: Bug
  • Component: core-libs
  • Sub-Component: jdk.nashorn
  • Affected Version: 8u20,9
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2014-06-04
  • Updated: 2014-08-05
  • Resolved: 2014-06-04
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
8u20Fixed 9 b17Fixed
Description
The following code works on jdk8 and jdk8u5 - but fails on jdk8u20 and jdk9. So, it is a regression due to recent jdk8u and jdk9 changes:

---- File: Main.java ----

import javax.script.*;

public class Main {
  public static void main(String[] args) throws Exception {
    ScriptEngineManager m = new ScriptEngineManager();
    ScriptEngine engine = m.getEngineByName("nashorn");
    for (int index = 0; index < 20; index++) {
        final Bindings bindings = new SimpleBindings();
        bindings.put("foo", index);
        String script = "print(foo)";
        engine.eval(script, bindings);
    }
  }
}

--- Main.java ends ----

jdk9 failure stack trace looks as follows:

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Exception in thread "main" javax.script.ScriptException: ReferenceError: "foo" is not defined in <eval> at line number 1
	at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:586)
	at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:570)
	at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:525)
	at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:521)
	at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:192)
	at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:233)
	at Main.main(Main.java:11)
Caused by: <eval>:1 ReferenceError: "foo" is not defined
	at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:58)
	at jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:320)
	at jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:292)
	at jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:279)
	at jdk.nashorn.internal.runtime.ScriptObject.megamorphicGet(ScriptObject.java:2000)
	at jdk.nashorn.internal.scripts.Script$1$\^eval\_.:program(<eval>:1)
	at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:565)
	at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:221)
	at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:374)
	at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:568)
	... 5 more


Another test that is independent of javax.script API is as follows:

----- File:  x.js -------

__noSuchProperty__ = function(name) {
    return 1;
}

function func(obj) {
    with(obj) {
        foo;
    }
}

for (var i = 0; i < 20; i++) {
    var obj = {};
    obj.foo = i;
    obj[i] = i;
    func(obj);
}

func({});

---- x.js ends ----------

In jdk8 and jdk8u5, no error with that script. But with jdk9 and jdk8u20, we get:

x.js:7 ReferenceError: "foo" is not defined

Comments
verified on 9b25
05-08-2014

ScriptObject.java has the following code: @SuppressWarnings("unused") private Object megamorphicGet(final String key, final boolean isMethod, final boolean isScope) { final FindProperty find = findProperty(key, true); if (find != null) { return find.getObjectValue(); } // * assumes __noSuchProperty__ can be skipped for scope object+scope access * if (isScope) { throw referenceError("not.defined", key); } return isMethod ? getNoSuchMethod(key, INVALID_PROGRAM_POINT) : invokeNoSuchProperty(key, INVALID_PROGRAM_POINT); } The "if (isScope)" block assumes that for scope objects + scope access __noSuchProperty__ hook can be skipped - which is wrong as shown by the test cases in this issue.
04-06-2014