8023551: Mirror functions can not be invoked using invokeMethod, invokeFunction
Reviewed-by: attila, jlaskey, lagergren
--- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Wed Aug 21 17:28:53 2013 +0530
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Thu Aug 22 18:46:26 2013 +0530
@@ -321,10 +321,11 @@
private ScriptObject getNashornGlobalFrom(final ScriptContext ctxt) {
final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE);
if (bindings instanceof ScriptObjectMirror) {
- ScriptObject sobj = ((ScriptObjectMirror)bindings).getScriptObject();
- if (sobj instanceof GlobalObject) {
- return sobj;
- }
+ final ScriptObjectMirror mirror = (ScriptObjectMirror)bindings;
+ ScriptObject sobj = ((ScriptObjectMirror)bindings).getScriptObject();
+ if (sobj instanceof GlobalObject && sobj.isOfContext(nashornContext)) {
+ return sobj;
+ }
}
// didn't find global object from context given - return the engine-wide global
@@ -402,8 +403,10 @@
args = ScriptRuntime.EMPTY_ARRAY;
}
// if no arguments passed, expose it
- args = ((GlobalObject)ctxtGlobal).wrapAsObject(args);
- ctxtGlobal.set("arguments", args, false);
+ if (! (args instanceof ScriptObject)) {
+ args = ((GlobalObject)ctxtGlobal).wrapAsObject(args);
+ ctxtGlobal.set("arguments", args, false);
+ }
}
private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
--- a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Wed Aug 21 17:28:53 2013 +0530
+++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Thu Aug 22 18:46:26 2013 +0530
@@ -99,12 +99,14 @@
}
final Object val = functionName == null? sobj : sobj.get(functionName);
- if (! (val instanceof ScriptFunction)) {
- throw new NoSuchMethodException("No such function " + ((functionName != null)? functionName : ""));
+ if (val instanceof ScriptFunction) {
+ final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
+ return wrap(ScriptRuntime.checkAndApply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global);
+ } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) {
+ return ((ScriptObjectMirror)val).call(null, args);
}
- final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
- return wrap(ScriptRuntime.checkAndApply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global);
+ throw new NoSuchMethodException("No such function " + ((functionName != null)? functionName : ""));
} catch (final RuntimeException | Error e) {
throw e;
} catch (final Throwable t) {
@@ -127,12 +129,14 @@
}
final Object val = functionName == null? sobj : sobj.get(functionName);
- if (! (val instanceof ScriptFunction)) {
- throw new RuntimeException("not a constructor " + ((functionName != null)? functionName : ""));
+ if (val instanceof ScriptFunction) {
+ final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
+ return wrap(ScriptRuntime.checkAndConstruct((ScriptFunction)val, unwrapArray(modArgs, global)), global);
+ } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) {
+ return ((ScriptObjectMirror)val).newObject(null, args);
}
- final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
- return wrap(ScriptRuntime.checkAndConstruct((ScriptFunction)val, unwrapArray(modArgs, global)), global);
+ throw new RuntimeException("not a constructor " + ((functionName != null)? functionName : ""));
} catch (final RuntimeException | Error e) {
throw e;
} catch (final Throwable t) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023551.js Thu Aug 22 18:46:26 2013 +0530
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8023551: Mirror functions can not be invoked using invokeMethod, invokeFunction
+ *
+ * @test
+ * @run
+ */
+
+var m = new javax.script.ScriptEngineManager();
+var e = m.getEngineByName("nashorn");
+
+function func(x) {
+ print("func: " + x);
+}
+
+e.put("func", func);
+e.invokeFunction("func", "hello");
+
+var obj = e.eval("({ foo: func })");
+e.invokeMethod(obj, "foo", "world");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023551.js.EXPECTED Thu Aug 22 18:46:26 2013 +0530
@@ -0,0 +1,2 @@
+func: hello
+func: world
--- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Wed Aug 21 17:28:53 2013 +0530
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Thu Aug 22 18:46:26 2013 +0530
@@ -1256,4 +1256,30 @@
// dos2unix - fix line endings if running on windows
assertEquals(sw.toString().replaceAll("\r", ""), "34 true hello\n");
}
+
+ @Test
+ public void mirrorNewObjectGlobalFunctionTest() throws ScriptException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final ScriptEngine e2 = m.getEngineByName("nashorn");
+
+ e.eval("function func() {}");
+ e2.put("foo", e.get("func"));
+ final Object e2global = e2.eval("this");
+ final Object newObj = ((ScriptObjectMirror)e2global).newObject("foo");
+ assertTrue(newObj instanceof ScriptObjectMirror);
+ }
+
+ @Test
+ public void mirrorNewObjectInstanceFunctionTest() throws ScriptException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final ScriptEngine e2 = m.getEngineByName("nashorn");
+
+ e.eval("function func() {}");
+ e2.put("func", e.get("func"));
+ final Object e2obj = e2.eval("({ foo: func })");
+ final Object newObj = ((ScriptObjectMirror)e2obj).newObject("foo");
+ assertTrue(newObj instanceof ScriptObjectMirror);
+ }
}