8023551: Mirror functions can not be invoked using invokeMethod, invokeFunction
authorsundar
Thu, 22 Aug 2013 18:46:26 +0530
changeset 19620 3f0c79b63846
parent 19619 4085b74056ee
child 19621 1b2a79d8924c
8023551: Mirror functions can not be invoked using invokeMethod, invokeFunction Reviewed-by: attila, jlaskey, lagergren
nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java
nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
nashorn/test/script/basic/JDK-8023551.js
nashorn/test/script/basic/JDK-8023551.js.EXPECTED
nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
--- 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);
+    }
 }