src/jdk/nashorn/internal/runtime/Context.java

Print this page

        

*** 488,497 **** --- 488,530 ---- public ScriptFunction compileScript(final Source source, final ScriptObject scope) { return compileScript(source, scope, this.errors); } /** + * Interface to represent compiled code that can be re-used across many + * global scope instances + */ + public static interface MultiGlobalCompiledScript { + /** + * Obtain script function object for a specific global scope object. + * + * @param newGlobal global scope for which function object is obtained + * @return script function for script level expressions + */ + public ScriptFunction getFunction(final Global newGlobal); + } + + /** + * Compile a top level script. + * + * @param source the script source + * @return reusable compiled script across many global scopes. + */ + public MultiGlobalCompiledScript compileScript(final Source source) { + final Class<?> clazz = compile(source, this.errors, this._strict); + final MethodHandle runMethodHandle = getRunScriptHandle(clazz); + final boolean strict = isStrict(clazz); + + return new MultiGlobalCompiledScript() { + @Override + public ScriptFunction getFunction(final Global newGlobal) { + return Context.getGlobal().newScriptFunction(RUN_SCRIPT.symbolName(), runMethodHandle, newGlobal, strict); + } + }; + } + + /** * Entry point for {@code eval} * * @param initialScope The scope of this eval call * @param string Evaluated code as a String * @param callThis "this" to be passed to the evaluated code
*** 947,979 **** } return ScriptRuntime.apply(script, thiz); } ! private static ScriptFunction getRunScriptFunction(final Class<?> script, final ScriptObject scope) { ! if (script == null) { ! return null; ! } ! ! // Get run method - the entry point to the script ! final MethodHandle runMethodHandle = ! MH.findStatic( MethodHandles.lookup(), script, RUN_SCRIPT.symbolName(), MH.type( Object.class, ScriptFunction.class, Object.class)); ! boolean strict; ! try { ! strict = script.getField(STRICT_MODE.symbolName()).getBoolean(null); } catch (final NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { ! strict = false; } // Package as a JavaScript function and pass function back to shell. return Context.getGlobal().newScriptFunction(RUN_SCRIPT.symbolName(), runMethodHandle, scope, strict); } --- 980,1016 ---- } return ScriptRuntime.apply(script, thiz); } ! private static MethodHandle getRunScriptHandle(final Class<?> script) { ! return MH.findStatic( MethodHandles.lookup(), script, RUN_SCRIPT.symbolName(), MH.type( Object.class, ScriptFunction.class, Object.class)); + } ! private static boolean isStrict(final Class<?> script) { try { ! return script.getField(STRICT_MODE.symbolName()).getBoolean(null); } catch (final NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { ! return false; } + } + + private static ScriptFunction getRunScriptFunction(final Class<?> script, final ScriptObject scope) { + if (script == null) { + return null; + } + + // Get run method - the entry point to the script + final MethodHandle runMethodHandle = getRunScriptHandle(script); + boolean strict = isStrict(script); // Package as a JavaScript function and pass function back to shell. return Context.getGlobal().newScriptFunction(RUN_SCRIPT.symbolName(), runMethodHandle, scope, strict); }