changeset 898:d703c59c556f jdk9-b20

Merge
author lana
date Fri, 20 Jun 2014 10:14:50 -0700
parents ada4855e44e2 fdfda6a035c6
children 174cf53bce4e
files
diffstat 20 files changed, 230 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java	Thu Jun 19 11:22:50 2014 -0700
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java	Fri Jun 20 10:14:50 2014 -0700
@@ -412,6 +412,10 @@
                     }
                 }
             }
+            break;
+
+            default:
+            break;
         }
     }
 
@@ -450,7 +454,7 @@
 
         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;
--- a/make/project.properties	Thu Jun 19 11:22:50 2014 -0700
+++ b/make/project.properties	Fri Jun 20 10:14:50 2014 -0700
@@ -283,7 +283,7 @@
   -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 @@
 # -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
--- a/src/jdk/nashorn/internal/codegen/Compiler.java	Thu Jun 19 11:22:50 2014 -0700
+++ b/src/jdk/nashorn/internal/codegen/Compiler.java	Fri Jun 20 10:14:50 2014 -0700
@@ -47,7 +47,9 @@
 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 @@
 
     @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() {
--- a/src/jdk/nashorn/internal/ir/BinaryNode.java	Thu Jun 19 11:22:50 2014 -0700
+++ b/src/jdk/nashorn/internal/ir/BinaryNode.java	Fri Jun 20 10:14:50 2014 -0700
@@ -45,7 +45,7 @@
 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;
--- a/src/jdk/nashorn/internal/ir/FunctionNode.java	Thu Jun 19 11:22:50 2014 -0700
+++ b/src/jdk/nashorn/internal/ir/FunctionNode.java	Fri Jun 20 10:14:50 2014 -0700
@@ -99,7 +99,7 @@
         BYTECODE_GENERATED,
         /** method has been installed */
         BYTECODE_INSTALLED
-    };
+    }
 
     /** Source of entity. */
     private final Source source;
@@ -388,10 +388,11 @@
     }
 
     /**
-     * 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();
--- a/src/jdk/nashorn/internal/objects/NativeObject.java	Thu Jun 19 11:22:50 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeObject.java	Fri Jun 20 10:14:50 2014 -0700
@@ -75,7 +75,10 @@
  */
 @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();
--- a/src/jdk/nashorn/internal/parser/Parser.java	Thu Jun 19 11:22:50 2014 -0700
+++ b/src/jdk/nashorn/internal/parser/Parser.java	Fri Jun 20 10:14:50 2014 -0700
@@ -680,7 +680,7 @@
      */
     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.
 
@@ -711,20 +711,6 @@
     }
 
     /**
-     * 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.
      *
      * @param stmt Statement to be checked
--- a/src/jdk/nashorn/internal/parser/Token.java	Thu Jun 19 11:22:50 2014 -0700
+++ b/src/jdk/nashorn/internal/parser/Token.java	Fri Jun 20 10:14:50 2014 -0700
@@ -61,6 +61,28 @@
     }
 
     /**
+     * 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.
      * @return Length of the token.
--- a/src/jdk/nashorn/internal/runtime/Context.java	Thu Jun 19 11:22:50 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/Context.java	Fri Jun 20 10:14:50 2014 -0700
@@ -1236,6 +1236,16 @@
      * @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 @@
             }
             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;
--- a/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java	Thu Jun 19 11:22:50 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java	Fri Jun 20 10:14:50 2014 -0700
@@ -34,6 +34,8 @@
  */
 final class FinalScriptFunctionData extends ScriptFunctionData {
 
+    private static final long serialVersionUID = -930632846167768864L;
+
     /**
      * Constructor - used for bind
      *
--- a/src/jdk/nashorn/internal/runtime/PropertyMap.java	Thu Jun 19 11:22:50 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/PropertyMap.java	Fri Jun 20 10:14:50 2014 -0700
@@ -185,6 +185,7 @@
      * 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.
--- a/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Thu Jun 19 11:22:50 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Fri Jun 20 10:14:50 2014 -0700
@@ -54,7 +54,6 @@
 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 @@
  */
 @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 @@
         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 @@
 
     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));
 
--- a/src/jdk/nashorn/internal/runtime/ScriptObject.java	Thu Jun 19 11:22:50 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java	Fri Jun 20 10:14:50 2014 -0700
@@ -2267,7 +2267,7 @@
 
             if (mh != null) {
                 assert func != null;
-                if (scopeAccess && func != null && func.isStrict()) {
+                if (scopeAccess && func.isStrict()) {
                     mh = bindTo(mh, UNDEFINED);
                 }
                 return new GuardedInvocation(
--- a/src/jdk/nashorn/internal/runtime/Source.java	Thu Jun 19 11:22:50 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/Source.java	Fri Jun 20 10:14:50 2014 -0700
@@ -99,12 +99,13 @@
                 // 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 @@
         }
 
         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 @@
     }
 
     /**
-     * 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 @@
      * @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 @@
      * @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 @@
      * @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 @@
      * @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 @@
      *
      * @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 @@
      * @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 @@
      * @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 @@
      * @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++;
--- a/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java	Thu Jun 19 11:22:50 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java	Fri Jun 20 10:14:50 2014 -0700
@@ -141,21 +141,6 @@
         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();
--- a/src/jdk/nashorn/internal/runtime/logging/DebugLogger.java	Thu Jun 19 11:22:50 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/logging/DebugLogger.java	Fri Jun 20 10:14:50 2014 -0700
@@ -540,7 +540,7 @@
 
     /**
      * 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) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8047035.js	Fri Jun 20 10:14:50 2014 -0700
@@ -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")());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8047035.js.EXPECTED	Fri Jun 20 10:14:50 2014 -0700
@@ -0,0 +1,4 @@
+function() "hello"
+function() ''
+
+hello
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8047057.js	Fri Jun 20 10:14:50 2014 -0700
@@ -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);
--- a/test/src/UnnamedPackageTestCallback.java	Thu Jun 19 11:22:50 2014 -0700
+++ b/test/src/UnnamedPackageTestCallback.java	Fri Jun 20 10:14:50 2014 -0700
@@ -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);
 }