This commit is contained in:
Lana Steuck 2014-06-20 10:14:50 -07:00
commit e6a9b34299
20 changed files with 230 additions and 60 deletions

View File

@ -412,6 +412,10 @@ public final class MemberInfo implements Cloneable {
}
}
}
break;
default:
break;
}
}
@ -450,7 +454,7 @@ public final class MemberInfo implements Cloneable {
if (type.getSort() == Type.OBJECT) {
try {
final Class clazz = Class.forName(type.getClassName(), false, myLoader);
final Class<?> clazz = Class.forName(type.getClassName(), false, myLoader);
return ScriptObject.class.isAssignableFrom(clazz);
} catch (final ClassNotFoundException cnfe) {
return false;

View File

@ -283,7 +283,7 @@ run.test.jvmargs.common=\
-XX:+HeapDumpOnOutOfMemoryError
# turn on assertions for tests
run.test.jvmargs.main=${run.test.jvmargs.common} -ea -Dnashorn.lazy
run.test.jvmargs.main=${run.test.jvmargs.common} -ea
# extra jvmargs that might be useful for debugging
#
@ -305,7 +305,7 @@ run.test.jvmargs.main=${run.test.jvmargs.common} -ea -Dnashorn.lazy
# -XX:+PrintNMethods
# Use best known performance options for octane
run.test.jvmargs.octane.main=${run.test.jvmargs.common} -Dnashorn.lazy -XX:+UnlockDiagnosticVMOptions -XX:+UseNewCode -XX:TypeProfileLevel=222
run.test.jvmargs.octane.main=${run.test.jvmargs.common} -XX:+UnlockDiagnosticVMOptions -XX:+UseNewCode -XX:TypeProfileLevel=222
# Security manager args - make sure that we run with the nashorn.policy that the build creates
run.test.jvmsecurityargs=-Xverify:all -Djava.security.manager -Djava.security.policy=${basedir}/build/nashorn.policy

View File

@ -47,7 +47,9 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.logging.Level;
import jdk.internal.dynalink.support.NameCodec;
import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
import jdk.nashorn.internal.codegen.types.Type;
@ -421,7 +423,14 @@ public final class Compiler implements Loggable {
@Override
public DebugLogger initLogger(final Context ctxt) {
return ctxt.getLogger(this.getClass());
return ctxt.getLogger(this.getClass(), new Consumer<DebugLogger>() {
@Override
public void accept(final DebugLogger newLogger) {
if (!Compiler.this.getScriptEnvironment()._lazy_compilation) {
newLogger.warning("WARNING: Running with lazy compilation switched off. This is not a default setting.");
}
}
});
}
ScriptEnvironment getScriptEnvironment() {

View File

@ -45,7 +45,7 @@ import jdk.nashorn.internal.parser.TokenType;
public final class BinaryNode extends Expression implements Assignment<Expression>, Optimistic {
// Placeholder for "undecided optimistic ADD type". Unfortunately, we can't decide the type of ADD during optimistic
// type calculation as it can have local variables as its operands that will decide its ultimate type.
private static final Type OPTIMISTIC_UNDECIDED_TYPE = Type.typeFor(new Object(){}.getClass());
private static final Type OPTIMISTIC_UNDECIDED_TYPE = Type.typeFor(new Object(){/*empty*/}.getClass());
/** Left hand side argument. */
private final Expression lhs;

View File

@ -99,7 +99,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
BYTECODE_GENERATED,
/** method has been installed */
BYTECODE_INSTALLED
};
}
/** Source of entity. */
private final Source source;
@ -388,10 +388,11 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
}
/**
* static source name getter
* Static source name getter
*
* @param source
* @param sourceURL
* @return
* @return source name
*/
public static String getSourceName(final Source source, final String sourceURL) {
return sourceURL != null ? sourceURL : source.getName();

View File

@ -75,7 +75,10 @@ import jdk.nashorn.internal.runtime.linker.NashornBeansLinker;
*/
@ScriptClass("Object")
public final class NativeObject {
/** Methodhandle to proto getter */
public static final MethodHandle GET__PROTO__ = findOwnMH("get__proto__", ScriptObject.class, Object.class);
/** Methodhandle to proto setter */
public static final MethodHandle SET__PROTO__ = findOwnMH("set__proto__", Object.class, Object.class, Object.class);
private static final Object TO_STRING = new Object();

View File

@ -680,7 +680,7 @@ loop:
*/
private FunctionNode program(final String scriptName, final boolean allowPropertyFunction) {
// Make a pseudo-token for the script holding its start and length.
final long functionToken = Token.toDesc(FUNCTION, getProgramStartPosition(token), source.getLength());
final long functionToken = Token.toDesc(FUNCTION, Token.descPosition(Token.withDelimiter(token)), source.getLength());
final int functionLine = line;
// Set up the script to append elements.
@ -710,20 +710,6 @@ loop:
return script;
}
/**
* Returns the start position of the program based on its first token. Normally returns the position of the token
* itself, except in case of string tokens which report their position past their opening delimiter and thus need
* to have one subtracted from their position.
* @param firstToken the first token of the program
* @return the start position of the program
*/
private static int getProgramStartPosition(final long firstToken) {
final int start = Token.descPosition(firstToken);
switch(Token.descType(firstToken)) {
case STRING: case ESCSTRING: case EXECSTRING: return start - 1;
default: return start;
}
}
/**
* Directive value or null if statement is not a directive.
*

View File

@ -60,6 +60,28 @@ public class Token {
return (int)(token >>> 32);
}
/**
* Normally returns the token itself, except in case of string tokens
* which report their position past their opening delimiter and thus
* need to have position and length adjusted.
*
* @param token Token descriptor.
* @return same or adjusted token.
*/
public static long withDelimiter(final long token) {
final TokenType tokenType = Token.descType(token);
switch(tokenType) {
case STRING: case ESCSTRING: case EXECSTRING: {
final int start = Token.descPosition(token) - 1;
final int len = Token.descLength(token) + 2;
return toDesc(tokenType, start, len);
}
default: {
return token;
}
}
}
/**
* Extract token length from a token descriptor.
* @param token Token descriptor.

View File

@ -1236,6 +1236,16 @@ public final class Context {
* @return debuglogger associated with that class
*/
public DebugLogger getLogger(final Class<? extends Loggable> clazz) {
return getLogger(clazz, null);
}
/**
* Get a logger, given a loggable class
* @param clazz a Loggable class
* @param initHook an init hook - if this is the first time the logger is created in the context, run the init hook
* @return debuglogger associated with that class
*/
public DebugLogger getLogger(final Class<? extends Loggable> clazz, final Consumer<DebugLogger> initHook) {
final String name = getLoggerName(clazz);
DebugLogger logger = loggers.get(name);
if (logger == null) {
@ -1244,6 +1254,9 @@ public final class Context {
}
final LoggerInfo info = env._loggers.get(name);
logger = new DebugLogger(name, info.getLevel(), info.isQuiet());
if (initHook != null) {
initHook.accept(logger);
}
loggers.put(name, logger);
}
return logger;

View File

@ -34,6 +34,8 @@ import java.lang.invoke.MethodType;
*/
final class FinalScriptFunctionData extends ScriptFunctionData {
private static final long serialVersionUID = -930632846167768864L;
/**
* Constructor - used for bind
*

View File

@ -185,6 +185,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
* properties with keys that are valid array indices.</p>
*
* @param properties Collection of initial properties.
* @param className class name
* @param fieldCount Number of fields in use.
* @param fieldMaximum Number of fields available.
* @param spillLength Number of used spill slots.

View File

@ -54,7 +54,6 @@ import jdk.nashorn.internal.parser.TokenType;
import jdk.nashorn.internal.runtime.logging.DebugLogger;
import jdk.nashorn.internal.runtime.logging.Loggable;
import jdk.nashorn.internal.runtime.logging.Logger;
import jdk.nashorn.internal.runtime.options.Options;
import jdk.nashorn.internal.scripts.JS;
/**
@ -65,9 +64,6 @@ import jdk.nashorn.internal.scripts.JS;
*/
@Logger(name="recompile")
public final class RecompilableScriptFunctionData extends ScriptFunctionData implements Loggable {
/** Is lazy compilation enabled? TODO: this should be the default */
public static final boolean LAZY_COMPILATION = Options.getBooleanProperty("nashorn.lazy");
/** Prefix used for all recompiled script classes */
public static final String RECOMPILATION_PREFIX = "Recompilation$";
@ -240,6 +236,12 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
return "function " + (name == null ? "" : name) + "() { [native code] }";
}
/**
* Setter for code and source
*
* @param code map of code, class name to class
* @param source source
*/
public void setCodeAndSource(final Map<String, Class<?>> code, final Source source) {
this.source = source;
if (methodLocator != null) {
@ -292,7 +294,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
private static long tokenFor(final FunctionNode fn) {
final int position = Token.descPosition(fn.getFirstToken());
final long lastToken = fn.getLastToken();
final long lastToken = Token.withDelimiter(fn.getLastToken());
// EOL uses length field to store the line number
final int length = Token.descPosition(lastToken) - position + (Token.descType(lastToken) == TokenType.EOL ? 0 : Token.descLength(lastToken));

View File

@ -2267,7 +2267,7 @@ public abstract class ScriptObject implements PropertyAccess {
if (mh != null) {
assert func != null;
if (scopeAccess && func != null && func.isStrict()) {
if (scopeAccess && func.isStrict()) {
mh = bindTo(mh, UNDEFINED);
}
return new GuardedInvocation(

View File

@ -99,12 +99,13 @@ public final class Source implements Loggable {
// Force any access errors
data.checkPermissionAndClose();
return existingSource;
} else {
// All sources in cache must be fully loaded
data.load();
CACHE.put(newSource, newSource);
return newSource;
}
// All sources in cache must be fully loaded
data.load();
CACHE.put(newSource, newSource);
return newSource;
} catch (final RuntimeException e) {
final Throwable cause = e.getCause();
if (cause instanceof IOException) {
@ -291,7 +292,9 @@ public final class Source implements Loggable {
}
protected void checkPermissionAndClose() throws IOException {
try (InputStream in = url.openStream()) {}
try (InputStream in = url.openStream()) {
// empty
}
debug("permission checked for ", url);
}
@ -366,20 +369,24 @@ public final class Source implements Loggable {
}
/**
* Returns an instance
* Returns a Source instance
*
* @param name source name
* @param content contents as char array
*
* @return source instance
*/
public static Source sourceFor(final String name, final char[] content) {
return new Source(name, baseName(name), new RawData(content));
}
/**
* Returns an instance
* Returns a Source instance
*
* @param name source name
* @param content contents as string
*
* @return source instance
*/
public static Source sourceFor(final String name, final String content) {
return new Source(name, baseName(name), new RawData(content));
@ -391,6 +398,8 @@ public final class Source implements Loggable {
* @param name source name
* @param url url from which source can be loaded
*
* @return source instance
*
* @throws IOException if source cannot be loaded
*/
public static Source sourceFor(final String name, final URL url) throws IOException {
@ -404,6 +413,8 @@ public final class Source implements Loggable {
* @param url url from which source can be loaded
* @param cs Charset used to convert bytes to chars
*
* @return source instance
*
* @throws IOException if source cannot be loaded
*/
public static Source sourceFor(final String name, final URL url, final Charset cs) throws IOException {
@ -416,6 +427,8 @@ public final class Source implements Loggable {
* @param name source name
* @param file file from which source can be loaded
*
* @return source instance
*
* @throws IOException if source cannot be loaded
*/
public static Source sourceFor(final String name, final File file) throws IOException {
@ -429,6 +442,8 @@ public final class Source implements Loggable {
* @param file file from which source can be loaded
* @param cs Charset used to convert bytes to chars
*
* @return source instance
*
* @throws IOException if source cannot be loaded
*/
public static Source sourceFor(final String name, final File file, final Charset cs) throws IOException {
@ -441,6 +456,9 @@ public final class Source implements Loggable {
*
* @param name source name
* @param reader reader from which source can be loaded
*
* @return source instance
*
* @throws IOException if source cannot be loaded
*/
public static Source sourceFor(final String name, final Reader reader) throws IOException {
@ -542,9 +560,9 @@ public final class Source implements Loggable {
* @return Index of first character of line.
*/
private int findBOLN(final int position) {
final char[] data = data();
final char[] d = data();
for (int i = position - 1; i > 0; i--) {
final char ch = data[i];
final char ch = d[i];
if (ch == '\n' || ch == '\r') {
return i + 1;
@ -560,10 +578,10 @@ public final class Source implements Loggable {
* @return Index of last character of line.
*/
private int findEOLN(final int position) {
final char[] data = data();
final int length = data.length;
final char[] d = data();
final int length = d.length;
for (int i = position; i < length; i++) {
final char ch = data[i];
final char ch = d[i];
if (ch == '\n' || ch == '\r') {
return i - 1;
@ -583,12 +601,12 @@ public final class Source implements Loggable {
* @return Line number.
*/
public int getLine(final int position) {
final char[] data = data();
final char[] d = data();
// Line count starts at 1.
int line = 1;
for (int i = 0; i < position; i++) {
final char ch = data[i];
final char ch = d[i];
// Works for both \n and \r\n.
if (ch == '\n') {
line++;

View File

@ -141,21 +141,6 @@ abstract class ArrayFilter extends ArrayData {
return this;
}
private static void printTrace(final Throwable t, final String msg) {
final java.io.StringWriter sw = new java.io.StringWriter();
final java.io.PrintWriter pw = new java.io.PrintWriter(sw, false);
pw.println(msg);
final StackTraceElement[] trace = t.getStackTrace();
for(final StackTraceElement e: trace) {
pw.println(" at " + e);
if(e.getClassName().startsWith("jdk.nashorn.")) {
break;
}
}
pw.flush();
System.out.println(sw.toString());
}
@Override
public Type getOptimisticType() {
return underlying.getOptimisticType();

View File

@ -540,7 +540,7 @@ public final class DebugLogger {
/**
* Shorthand for outputting a log string as log level
* {@link java.util.logging.Level#FINE} on this logger
* {@link java.util.logging.Level#SEVERE} on this logger
* @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
*/
public void severe(final Object... objs) {

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2014, 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-8047035: (function() "hello")() crashes in Lexer with jdk9
*
* @test
* @run
*/
// should not print ")" at the end
print(function() "hello");
print(function() '');
// The following should not crash inside lexer
print((function() '')());
print((function() "hello")());

View File

@ -0,0 +1,4 @@
function() "hello"
function() ''
hello

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2014, 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-8047057: Add a regression test for the passing test cases from JDK-8042304
*
* @test
* @run
*/
// commented out makeFuncAndCall calls are still result in crash
// Tests commented with //** fail only within test framework.
// Pass fine with standalone "jjs" mode.
function makeFuncAndCall(code) {
Function(code)();
}
function makeFuncExpectError(code, ErrorType) {
try {
makeFuncAndCall(code);
} catch (e) {
if (! (e instanceof ErrorType)) {
fail(ErrorType.name + " expected, got " + e);
}
}
}
// makeFuncAndCall("switch(0) { default: {break;} return }");
// makeFuncAndCall("L: { { break L; } return; }");
makeFuncAndCall("L: { while(0) break L; return; }");
makeFuncExpectError("L: {while(0) break L; return [](); }", TypeError);
// makeFuncAndCall("do with({}) break ; while(0);");
makeFuncAndCall("while(0) with({}) continue ;");
//** makeFuncAndCall("eval([]);");
//** makeFuncAndCall("try{} finally{[]}");
makeFuncAndCall("try { } catch(x if 1) { try { } catch(x2) { } }");
makeFuncAndCall("try { } catch(x if 1) { try { return; } catch(x2) { { } } }");
makeFuncAndCall("Error() * (false)[-0]--");
makeFuncAndCall("try { var x = 1, x = null; } finally { }");
makeFuncAndCall("try { var x = {}, x = []; } catch(x3) { }");
//** makeFuncAndCall("[delete this]");
// makeFuncAndCall("if(eval('', eval('', function() {}))) { }");
// makeFuncAndCall("if(eval('', eval('', function() {}))) { }");
// makeFuncAndCall("eval(\"[,,];\", [11,12,13,14].some)");
// makeFuncAndCall("eval(\"1.2e3\", ({})[ /x/ ])");
// makeFuncAndCall("eval(\"x4\", x3);");
makeFuncAndCall("with({5.0000000000000000000000: String()}){(false); }");
makeFuncAndCall("try { var x = undefined, x = 5.0000000000000000000000; } catch(x) { x = undefined; }");
makeFuncAndCall("(function (x){ x %= this}(false))");
// makeFuncAndCall("eval.apply.apply(function(){ eval('') })");
makeFuncAndCall("(false % !this) && 0");
makeFuncAndCall("with({8: 'fafafa'.replace()}){ }");
makeFuncAndCall("(function (x) '' )(true)");
makeFuncExpectError("new eval(function(){})", TypeError);

View File

@ -23,6 +23,14 @@
* questions.
*/
/**
* Interface for callbacks used by the test suite.
*/
public interface UnnamedPackageTestCallback {
/**
* Call function
* @param s string argument
* @return string
*/
String call(String s);
}