--- old/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionExpressionTreeImpl.java 2015-06-29 21:14:30.560472794 +0530 +++ new/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionExpressionTreeImpl.java 2015-06-29 21:14:30.348471739 +0530 @@ -40,7 +40,7 @@ final BlockTree body) { super(node); funcNode = node; - assert !funcNode.isDeclared() : "function expression expected"; + assert !funcNode.isDeclared() || funcNode.isAnonymous() : "function expression expected"; final FunctionNode.Kind kind = node.getKind(); if (node.isAnonymous() || kind == FunctionNode.Kind.GETTER || kind == FunctionNode.Kind.SETTER) { --- old/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IRTranslator.java 2015-06-29 21:14:31.408477003 +0530 +++ new/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IRTranslator.java 2015-06-29 21:14:31.236476143 +0530 @@ -224,7 +224,7 @@ @Override public boolean enterFunctionNode(final FunctionNode functionNode) { - assert !functionNode.isDeclared() : "should not reach here for function declaration"; + assert !functionNode.isDeclared() || functionNode.isAnonymous() : "should not reach here for function declaration"; final List paramTrees = translateExprs(functionNode.getParameters()); --- old/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java 2015-06-29 21:14:32.116480518 +0530 +++ new/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java 2015-06-29 21:14:31.936479621 +0530 @@ -551,9 +551,7 @@ private void defineVarIdent(final VarNode varNode) { final IdentNode ident = varNode.getName(); final int flags; - if (varNode.isAnonymousFunctionDeclaration()) { - flags = IS_INTERNAL; - } else if (!varNode.isBlockScoped() && lc.getCurrentFunction().isProgram()) { + if (!varNode.isBlockScoped() && lc.getCurrentFunction().isProgram()) { flags = IS_SCOPE; } else { flags = 0; --- old/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SplitIntoFunctions.java 2015-06-29 21:14:32.784483848 +0530 +++ new/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SplitIntoFunctions.java 2015-06-29 21:14:32.580482814 +0530 @@ -312,10 +312,6 @@ assert !varNode.isBlockScoped(); //TODO: we must handle these too, but we currently don't final Expression init = varNode.getInit(); - if (varNode.isAnonymousFunctionDeclaration()) { - // We ain't moving anonymous function declarations. - return super.enterVarNode(varNode); - } // Move a declaration-only var statement to the top of the outermost function. getCurrentFunctionState().varStatements.add(varNode.setInit(null)); --- old/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java 2015-06-29 21:14:33.516487457 +0530 +++ new/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java 2015-06-29 21:14:33.344486603 +0530 @@ -2765,6 +2765,11 @@ functionBody); if (isStatement) { + if (isAnonymous) { + appendStatement(new ExpressionStatement(functionLine, functionToken, finish, function)); + return function; + } + // mark ES6 block functions as lexically scoped final int varFlags = (topLevel || !useBlockScope()) ? 0 : VarNode.IS_LET; final VarNode varNode = new VarNode(functionLine, functionToken, finish, name, function, varFlags); --- old/test/script/basic/JDK-8075454.js 2015-06-29 21:14:34.352491593 +0530 +++ new/test/script/basic/JDK-8075454.js 2015-06-29 21:14:34.144490561 +0530 @@ -40,4 +40,4 @@ EOF, print); -Assert.assertNull(ast.sourceElements[0].name); +Assert.assertNull(ast.sourceElements[0].expression.name); --- /dev/null 2015-06-29 20:14:30.008954322 +0530 +++ new/samples/javabind.js 2015-06-29 21:14:34.796493799 +0530 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// bind on a Java method + +// #javascript "bind" function +var bind = Function.prototype.bind; + +// Java console object +var console = java.lang.System.console(); + +// arguments "this" and prompt string of Console.readLine method are bound +var readName = bind.call(console.readLine, console, "Your name: "); + +// Now call it like a function that takes no arguments! +print("Hello,", readName()); --- /dev/null 2015-06-29 20:14:30.008954322 +0530 +++ new/samples/javaconstructorbind.js 2015-06-29 21:14:35.328496436 +0530 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// bind on a Java constructor + +// See Function.prototype.bind: +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind +var bind = Function.prototype.bind; + +var URL = Java.type("java.net.URL"); + +// get the constructor that accepts URL, String parameters. +// constructor signatures are properties of type object. +var newURL = URL["(URL, String)"]; + +// bind "context" URL parameter. +var TwitterURL = bind.call(newURL, null, new URL('https://www.twitter.com')); + +// now you can create context relative URLs using the bound constructor +print(new TwitterURL("sundararajan_a")); + +// read the URL content and print (optional part) + +var BufferedReader = Java.type("java.io.BufferedReader"); +var InputStreamReader = Java.type("java.io.InputStreamReader"); + +// function to retrieve text content of the given URL +function readTextFromURL(url) { + var str = ''; + var u = new URL(url); + var reader = new BufferedReader( + new InputStreamReader(u.openStream())); + try { + reader.lines().forEach(function(x) str += x); + return str; + } finally { + reader.close(); + } +} + +print(readTextFromURL(new TwitterURL("sundararajan_a"))); --- /dev/null 2015-06-29 20:14:30.008954322 +0530 +++ new/samples/mapwith.js 2015-06-29 21:14:35.856499054 +0530 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// Using a Java map with Javascript "with" statement + +var map = new java.util.HashMap(); +map.put("foo", 34); +map.put("bar", "hello"); + +var obj = { + __noSuchProperty__: function(name) { + return map.get(name); + } +}; + +with(obj) { + print(foo); + print(bar); +} --- /dev/null 2015-06-29 20:14:30.008954322 +0530 +++ new/test/script/basic/JDK-8114838.js 2015-06-29 21:14:36.384501678 +0530 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015 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-8114838: Anonymous functions escape to surrounding scope when defined under "with" statement + * + * @test + * @run + */ + +// do *not* introduce new lines! The next line should be 32 +with({}) { function () {} } +if (typeof this["L:32"] != 'undefined') { + throw new Error("anonymous name spills into global scope"); +} + +var func = eval("function() {}"); +if (typeof func != 'function') { + throw new Error("eval of anonymous function does not work!"); +} + +var ScriptEngineManager = Java.type("javax.script.ScriptEngineManager"); +var engine = new ScriptEngineManager().getEngineByName("nashorn"); +var func2 = engine.eval("function() {}"); +if (typeof func2 != 'function') { + throw new Error("eval of anonymous function does not work from script engine!"); +}