diff options
Diffstat (limited to 'src/jdk/nashorn/internal/runtime')
7 files changed, 116 insertions, 30 deletions
diff --git a/src/jdk/nashorn/internal/runtime/CodeInstaller.java b/src/jdk/nashorn/internal/runtime/CodeInstaller.java index 789eb2ce..3ec272a8 100644 --- a/src/jdk/nashorn/internal/runtime/CodeInstaller.java +++ b/src/jdk/nashorn/internal/runtime/CodeInstaller.java @@ -34,14 +34,21 @@ package jdk.nashorn.internal.runtime; * The compiler still retains most of the state around code emission * and management internally, so this is to avoid passing around any * logic that isn't directly related to installing a class + * @param <T> owner class type for this code installer * */ -public interface CodeInstaller { +public interface CodeInstaller<T> { + /** + * Return the owner for the CodeInstaller, e.g. a {@link Context} + * @return owner + */ + public T getOwner(); + /** * Install a class * @param className name of the class with / separation - * @param bytecode bytecode - * @return the installed class + * @param bytecode bytecode + * @return the installed class */ public Class<?> install(final String className, final byte[] bytecode); } diff --git a/src/jdk/nashorn/internal/runtime/Context.java b/src/jdk/nashorn/internal/runtime/Context.java index d220e299..8a7507fd 100644 --- a/src/jdk/nashorn/internal/runtime/Context.java +++ b/src/jdk/nashorn/internal/runtime/Context.java @@ -45,12 +45,16 @@ import java.security.CodeSource; import java.security.PrivilegedAction; import java.util.Locale; import java.util.TimeZone; + import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.util.CheckClassAdapter; import jdk.nashorn.internal.codegen.ClassEmitter; import jdk.nashorn.internal.codegen.Compiler; import jdk.nashorn.internal.codegen.Namespace; import jdk.nashorn.internal.codegen.objects.ObjectClassGenerator; +import jdk.nashorn.internal.ir.FunctionNode; +import jdk.nashorn.internal.ir.debug.PrintVisitor; +import jdk.nashorn.internal.parser.Parser; import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory; import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; import jdk.nashorn.internal.runtime.options.KeyValueOption; @@ -63,6 +67,36 @@ import sun.reflect.Reflection; */ public final class Context { + /** + * ContextCodeInstaller that has the privilege of installing classes in the Context. + * Can only be instantiated from inside the context and is opaque to other classes + */ + public static class ContextCodeInstaller implements CodeInstaller<Context> { + private final Context context; + private final ScriptLoader loader; + private final CodeSource codeSource; + + private ContextCodeInstaller(final Context context, final ScriptLoader loader, final CodeSource codeSource) { + this.context = context; + this.loader = loader; + this.codeSource = codeSource; + } + + /** + * Return the context for this installer + * @return context + */ + @Override + public Context getOwner() { + return context; + } + + @Override + public Class<?> install(final String className, final byte[] bytecode) { + return loader.installClass(className, bytecode, codeSource); + } + } + /** Is Context global debug mode enabled ? */ public static final boolean DEBUG = Options.getBooleanProperty("nashorn.debug"); @@ -751,6 +785,7 @@ public final class Context { /** * Initialize given global scope object. * + * @param global the global * @return the initialized global scope object. */ public ScriptObject initGlobal(final ScriptObject global) { @@ -877,22 +912,24 @@ public final class Context { } } - final Compiler compiler = Compiler.compiler(source, this, errMan, strict); - - if (!compiler.compile()) { + final FunctionNode functionNode = new Parser(this, source, errMan, strict).parse(); + if (errors.hasErrors() || _parse_only) { return null; } - final URL url = source.getURL(); + if (_print_lower_parse) { + getErr().println(new PrintVisitor(functionNode)); + } + + final URL url = source.getURL(); final ScriptLoader loader = _loader_per_compile ? createNewLoader() : scriptLoader; final CodeSource cs = url == null ? null : new CodeSource(url, (CodeSigner[])null); + final CodeInstaller<Context> installer = new ContextCodeInstaller(this, loader, cs); - script = compiler.install(new CodeInstaller() { - @Override - public Class<?> install(final String className, final byte[] bytecode) { - return loader.installClass(className, bytecode, cs); - } - }); + final Compiler compiler = new Compiler(installer, functionNode, strict); + + compiler.compile(); + script = compiler.install(); if (global != null) { global.cacheClass(source, script); @@ -917,15 +954,14 @@ public final class Context { private ScriptObject newGlobalTrusted() { try { final Class<?> clazz = Class.forName("jdk.nashorn.internal.objects.Global", true, scriptLoader); - final Constructor cstr = clazz.getConstructor(Context.class); + final Constructor<?> cstr = clazz.getConstructor(Context.class); return (ScriptObject) cstr.newInstance(this); } catch (final Exception e) { printStackTrace(e); if (e instanceof RuntimeException) { throw (RuntimeException)e; - } else { - throw new RuntimeException(e); } + throw new RuntimeException(e); } } } diff --git a/src/jdk/nashorn/internal/runtime/DebugLogger.java b/src/jdk/nashorn/internal/runtime/DebugLogger.java index dbbaeef6..aa7f05d4 100644 --- a/src/jdk/nashorn/internal/runtime/DebugLogger.java +++ b/src/jdk/nashorn/internal/runtime/DebugLogger.java @@ -73,8 +73,11 @@ public final class DebugLogger { * Get the output writer for the logger. Loggers always default to * stderr for output as they are used mainly to output debug info * + * Can be inherited so this should not be static. + * * @return print writer for log output. */ + @SuppressWarnings("static-method") public PrintWriter getOutputStream() { return Context.getCurrentErr(); } diff --git a/src/jdk/nashorn/internal/runtime/FindProperty.java b/src/jdk/nashorn/internal/runtime/FindProperty.java index 7089d1f6..2df165a1 100644 --- a/src/jdk/nashorn/internal/runtime/FindProperty.java +++ b/src/jdk/nashorn/internal/runtime/FindProperty.java @@ -36,7 +36,7 @@ import jdk.nashorn.internal.codegen.objects.ObjectClassGenerator; public final class FindProperty { /** Object where search began. */ private final ScriptObject self; - ; + /** Object where search finish. */ private final ScriptObject prototype; diff --git a/src/jdk/nashorn/internal/runtime/ScriptFunction.java b/src/jdk/nashorn/internal/runtime/ScriptFunction.java index d0b24b2c..48525058 100644 --- a/src/jdk/nashorn/internal/runtime/ScriptFunction.java +++ b/src/jdk/nashorn/internal/runtime/ScriptFunction.java @@ -78,12 +78,14 @@ public abstract class ScriptFunction extends ScriptObject { /** * Constructor * - * @param name function name - * @param methodHandle method handle to function (if specializations are present, assumed to be most generic) - * @param map property map - * @param scope scope - * @param specs specialized version of this function - other method handles - * + * @param name function name + * @param methodHandle method handle to function (if specializations are present, assumed to be most generic) + * @param map property map + * @param scope scope + * @param specs specialized version of this function - other method handles + * @param strict is this a strict mode function? + * @param builtin is this a built in function? + * @param isConstructor is this a constructor? */ protected ScriptFunction( final String name, @@ -240,10 +242,17 @@ public abstract class ScriptFunction extends ScriptObject { * @param args additional arguments to bind to this function. Can be null or empty to not bind additional arguments. * @return a function with the specified self and parameters bound. */ - protected ScriptFunction makeBoundFunction(Object self, Object[] args) { + protected ScriptFunction makeBoundFunction(final Object self, final Object[] args) { return makeBoundFunction(data.makeBoundFunctionData(this, self, args)); } + /** + * Create a version of this function as in {@link ScriptFunction#makeBoundFunction(Object, Object[])}, + * but using a {@link ScriptFunctionData} for the bound data. + * + * @param boundData ScriptFuntionData for the bound function + * @return a function with the bindings performed according to the given data + */ protected abstract ScriptFunction makeBoundFunction(ScriptFunctionData boundData); @Override @@ -350,6 +359,15 @@ public abstract class ScriptFunction extends ScriptObject { } /** + * Reset the invoker handle. This is used by trampolines for + * lazy code generation + * @param invoker new invoker + */ + protected void resetInvoker(final MethodHandle invoker) { + data.resetInvoker(invoker); + } + + /** * Prototype getter for this ScriptFunction - follows the naming convention * used by Nasgen and the code generator * diff --git a/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java b/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java index 3366993c..37e0246f 100644 --- a/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java +++ b/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java @@ -101,11 +101,13 @@ public final class ScriptFunctionData { /** * Constructor + * * @param name the function name * @param methodHandle the method handle * @param specs array of specialized method handles * @param strict strict flag * @param builtin builtin flag + * @param isConstructor constructor flags */ public ScriptFunctionData(final String name, final MethodHandle methodHandle, final MethodHandle[] specs, final boolean strict, final boolean builtin, final boolean isConstructor) { this(name, null, 0L, methodHandle, specs, strict, builtin, isConstructor); @@ -432,7 +434,7 @@ public final class ScriptFunctionData { * @param invoker the invoker handle * @param allocator the allocator handle */ - public void setMethodHandles(MethodHandle invoker, MethodHandle allocator) { + public void setMethodHandles(final MethodHandle invoker, final MethodHandle allocator) { // We can't make method handle fields final because they're not available during codegen // and they're set when first called, so we enforce set-once here. if (this.invoker == null) { @@ -443,6 +445,16 @@ public final class ScriptFunctionData { } /** + * Used by the trampoline. Must not be any wider than package + * private + * @param invoker new invoker + */ + void resetInvoker(final MethodHandle invoker) { + this.invoker = invoker; + this.constructor = null; //delay constructor composition + } + + /** * Allocates an object using this function's allocator. * @return the object allocated using this function's allocator, or null if the function doesn't have an allocator. */ diff --git a/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java b/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java index 523179ad..2925c8da 100644 --- a/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java +++ b/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java @@ -54,14 +54,21 @@ public final class ScriptingFunctions { /** Handle to implementation of {@link ScriptingFunctions#exec} - Nashorn extension */ public static final MethodHandle EXEC = findOwnMH("exec", Object.class, Object.class, Object.class, Object.class); - /** Names of special properties used by $EXEC API. */ - public static final String EXEC_NAME = "$EXEC"; - public static final String OUT_NAME = "$OUT"; - public static final String ERR_NAME = "$ERR"; - public static final String EXIT_NAME = "$EXIT"; + /** EXEC name - special property used by $EXEC API. */ + public static final String EXEC_NAME = "$EXEC"; + + /** OUT name - special property used by $EXEC API. */ + public static final String OUT_NAME = "$OUT"; + + /** ERR name - special property used by $EXEC API. */ + public static final String ERR_NAME = "$ERR"; + + /** EXIT name - special property used by $EXEC API. */ + public static final String EXIT_NAME = "$EXIT"; /** Names of special properties used by $ENV API. */ public static final String ENV_NAME = "$ENV"; + private static final String PWD_NAME = "PWD"; private ScriptingFunctions() { @@ -114,8 +121,11 @@ public final class ScriptingFunctions { * * @param self self reference * @param string string to execute + * @param input * * @return output string from the request + * @throws IOException + * @throws InterruptedException */ public static Object exec(final Object self, final Object string, final Object input) throws IOException, InterruptedException { // Current global is need to fetch additional inputs and for additional results. |