Tue, 24 Mar 2015 13:59:31 +0530
8074410: Startup time: Port shell.js to Java
Reviewed-by: lagergren, hannesw
1.1 --- a/src/jdk/nashorn/internal/objects/Global.java Fri Mar 20 20:04:18 2015 +0530 1.2 +++ b/src/jdk/nashorn/internal/objects/Global.java Tue Mar 24 13:59:31 2015 +0530 1.3 @@ -77,6 +77,7 @@ 1.4 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; 1.5 import jdk.nashorn.internal.runtime.regexp.RegExpResult; 1.6 import jdk.nashorn.internal.scripts.JO; 1.7 +import jdk.nashorn.tools.ShellFunctions; 1.8 1.9 /** 1.10 * Representation of global scope. 1.11 @@ -1817,6 +1818,17 @@ 1.12 return invocation; 1.13 } 1.14 1.15 + /** 1.16 + * Adds jjs shell interactive mode builtin functions to global scope. 1.17 + */ 1.18 + public void addShellBuiltins() { 1.19 + Object value = ScriptFunctionImpl.makeFunction("input", ShellFunctions.INPUT); 1.20 + addOwnProperty("input", Attribute.NOT_ENUMERABLE, value); 1.21 + 1.22 + value = ScriptFunctionImpl.makeFunction("evalinput", ShellFunctions.EVALINPUT); 1.23 + addOwnProperty("evalinput", Attribute.NOT_ENUMERABLE, value); 1.24 + } 1.25 + 1.26 private synchronized SwitchPoint getLexicalScopeSwitchPoint() { 1.27 SwitchPoint switchPoint = lexicalScopeSwitchPoint; 1.28 if (switchPoint == null || switchPoint.hasBeenInvalidated()) {
2.1 --- a/src/jdk/nashorn/tools/Shell.java Fri Mar 20 20:04:18 2015 +0530 2.2 +++ b/src/jdk/nashorn/tools/Shell.java Tue Mar 24 13:59:31 2015 +0530 2.3 @@ -417,18 +417,7 @@ 2.4 Context.setGlobal(global); 2.5 } 2.6 2.7 - // initialize with "shell.js" script 2.8 - try { 2.9 - final Source source = sourceFor("<shell.js>", Shell.class.getResource("resources/shell.js")); 2.10 - context.eval(global, source.getString(), global, "<shell.js>", false); 2.11 - } catch (final Exception e) { 2.12 - err.println(e); 2.13 - if (env._dump_on_error) { 2.14 - e.printStackTrace(err); 2.15 - } 2.16 - 2.17 - return INTERNAL_ERROR; 2.18 - } 2.19 + global.addShellBuiltins(); 2.20 2.21 while (true) { 2.22 err.print(prompt);
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/jdk/nashorn/tools/ShellFunctions.java Tue Mar 24 13:59:31 2015 +0530 3.3 @@ -0,0 +1,104 @@ 3.4 +/* 3.5 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.7 + * 3.8 + * This code is free software; you can redistribute it and/or modify it 3.9 + * under the terms of the GNU General Public License version 2 only, as 3.10 + * published by the Free Software Foundation. Oracle designates this 3.11 + * particular file as subject to the "Classpath" exception as provided 3.12 + * by Oracle in the LICENSE file that accompanied this code. 3.13 + * 3.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.17 + * version 2 for more details (a copy is included in the LICENSE file that 3.18 + * accompanied this code). 3.19 + * 3.20 + * You should have received a copy of the GNU General Public License version 3.21 + * 2 along with this work; if not, write to the Free Software Foundation, 3.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.23 + * 3.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.25 + * or visit www.oracle.com if you need additional information or have any 3.26 + * questions. 3.27 + */ 3.28 + 3.29 +package jdk.nashorn.tools; 3.30 + 3.31 +import static jdk.nashorn.internal.lookup.Lookup.MH; 3.32 +import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; 3.33 + 3.34 +import java.io.BufferedReader; 3.35 +import java.io.File; 3.36 +import java.io.IOException; 3.37 +import java.io.InputStreamReader; 3.38 +import java.io.OutputStreamWriter; 3.39 +import java.lang.invoke.MethodHandle; 3.40 +import java.lang.invoke.MethodHandles; 3.41 +import jdk.nashorn.internal.runtime.JSType; 3.42 +import jdk.nashorn.internal.objects.Global; 3.43 + 3.44 +/** 3.45 + * Global functions supported only in shell interactive mode. 3.46 + */ 3.47 +public final class ShellFunctions { 3.48 + 3.49 + /** Handle to implementation of {@link ShellFunctions#input} - Nashorn extension */ 3.50 + public static final MethodHandle INPUT = findOwnMH("input", Object.class, Object.class, Object.class, Object.class); 3.51 + 3.52 + /** Handle to implementation of {@link ShellFunctions#evalinput} - Nashorn extension */ 3.53 + public static final MethodHandle EVALINPUT = findOwnMH("evalinput", Object.class, Object.class, Object.class, Object.class); 3.54 + 3.55 + private ShellFunctions() { 3.56 + } 3.57 + 3.58 + /** 3.59 + * Nashorn extension: global.input (shell-interactive-mode-only) 3.60 + * Read one or more lines of input from the standard input till the 3.61 + * given end marker is seen in standard input. 3.62 + * 3.63 + * @param self self reference 3.64 + * @param endMarker String used as end marker for input 3.65 + * @param prompt String used as input prompt 3.66 + * 3.67 + * @return line that was read 3.68 + * 3.69 + * @throws IOException if an exception occurs 3.70 + */ 3.71 + public static Object input(final Object self, final Object endMarker, final Object prompt) throws IOException { 3.72 + final String endMarkerStr = (endMarker != UNDEFINED)? JSType.toString(endMarker) : ""; 3.73 + final String promptStr = (prompt != UNDEFINED)? JSType.toString(prompt) : ">> "; 3.74 + final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 3.75 + final StringBuilder buf = new StringBuilder(); 3.76 + while (true) { 3.77 + System.out.print(promptStr); 3.78 + final String line = reader.readLine(); 3.79 + if (line == null || line.equals(endMarkerStr)) { 3.80 + break; 3.81 + } 3.82 + buf.append(line); 3.83 + buf.append('\n'); 3.84 + } 3.85 + return buf.toString(); 3.86 + } 3.87 + 3.88 + /** 3.89 + * Nashorn extension: Reads zero or more lines from standard input and 3.90 + * evaluates the concatenated string as code 3.91 + * 3.92 + * @param self self reference 3.93 + * @param endMarker String used as end marker for input 3.94 + * @param prompt String used as input prompt 3.95 + * 3.96 + * @return output from evaluating the script 3.97 + * 3.98 + * @throws IOException if an exception occurs 3.99 + */ 3.100 + public static Object evalinput(final Object self, final Object endMarker, final Object prompt) throws IOException { 3.101 + return Global.eval(self, input(self, endMarker, prompt)); 3.102 + } 3.103 + 3.104 + private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) { 3.105 + return MH.findStatic(MethodHandles.lookup(), ShellFunctions.class, name, MH.type(rtype, types)); 3.106 + } 3.107 +}
4.1 --- a/src/jdk/nashorn/tools/resources/shell.js Fri Mar 20 20:04:18 2015 +0530 4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 4.3 @@ -1,83 +0,0 @@ 4.4 -/* 4.5 - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 4.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 - * 4.8 - * This code is free software; you can redistribute it and/or modify it 4.9 - * under the terms of the GNU General Public License version 2 only, as 4.10 - * published by the Free Software Foundation. 4.11 - * 4.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 4.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.15 - * version 2 for more details (a copy is included in the LICENSE file that 4.16 - * accompanied this code). 4.17 - * 4.18 - * You should have received a copy of the GNU General Public License version 4.19 - * 2 along with this work; if not, write to the Free Software Foundation, 4.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.21 - * 4.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.23 - * or visit www.oracle.com if you need additional information or have any 4.24 - * questions. 4.25 - */ 4.26 - 4.27 -/* 4.28 - * Initialization script for shell when running in interactive mode. 4.29 - */ 4.30 - 4.31 -/** 4.32 - * Reads zero or more lines from standard input and returns concatenated string 4.33 - * 4.34 - * @param endMarker marker string that signals end of input 4.35 - * @param prompt prompt printed for each line 4.36 - */ 4.37 -Object.defineProperty(this, "input", { 4.38 - value: function input(endMarker, prompt) { 4.39 - if (!endMarker) { 4.40 - endMarker = ""; 4.41 - } 4.42 - 4.43 - if (!prompt) { 4.44 - prompt = " >> "; 4.45 - } 4.46 - 4.47 - var imports = new JavaImporter(java.io, java.lang); 4.48 - var str = ""; 4.49 - with (imports) { 4.50 - var reader = new BufferedReader(new InputStreamReader(System['in'])); 4.51 - var line; 4.52 - while (true) { 4.53 - System.out.print(prompt); 4.54 - line = reader.readLine(); 4.55 - if (line == null || line == endMarker) { 4.56 - break; 4.57 - } 4.58 - str += line + "\n"; 4.59 - } 4.60 - } 4.61 - 4.62 - return str; 4.63 - }, 4.64 - enumerable: false, 4.65 - writable: true, 4.66 - configurable: true 4.67 -}); 4.68 - 4.69 - 4.70 -/** 4.71 - * Reads zero or more lines from standard input and evaluates the concatenated 4.72 - * string as code 4.73 - * 4.74 - * @param endMarker marker string that signals end of input 4.75 - * @param prompt prompt printed for each line 4.76 - */ 4.77 -Object.defineProperty(this, "evalinput", { 4.78 - value: function evalinput(endMarker, prompt) { 4.79 - var code = input(endMarker, prompt); 4.80 - // make sure everything is evaluated in global scope! 4.81 - return this.eval(code); 4.82 - }, 4.83 - enumerable: false, 4.84 - writable: true, 4.85 - configurable: true 4.86 -});