--- old/src/jdk/nashorn/api/scripting/NashornScriptEngine.java 2013-08-22 18:25:26.354497122 +0530 +++ new/src/jdk/nashorn/api/scripting/NashornScriptEngine.java 2013-08-22 18:25:26.074495731 +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 { --- old/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java 2013-08-22 18:25:26.938500015 +0530 +++ new/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java 2013-08-22 18:25:26.818499425 +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) { --- old/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java 2013-08-22 18:25:27.358502106 +0530 +++ new/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java 2013-08-22 18:25:27.202501325 +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); + } } --- /dev/null 2013-08-22 15:55:38.691696070 +0530 +++ new/test/script/basic/JDK-8023551.js 2013-08-22 18:25:27.666503624 +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 2013-08-22 15:55:38.691696070 +0530 +++ new/test/script/basic/JDK-8023551.js.EXPECTED 2013-08-22 18:25:27.922504896 +0530 @@ -0,0 +1,2 @@ +func: hello +func: world