8008103: Source object should maintain URL of the script source as a private field

Wed, 13 Feb 2013 19:59:30 +0530

author
sundar
date
Wed, 13 Feb 2013 19:59:30 +0530
changeset 86
38c44687e4bd
parent 85
a3dc1b180ce7
child 87
222b9f32b674

8008103: Source object should maintain URL of the script source as a private field
Reviewed-by: lagergren, jlaskey

src/jdk/nashorn/api/scripting/NashornScriptEngine.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/Context.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/Source.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/tools/Shell.java file | annotate | diff | comparison | revisions
test/src/jdk/nashorn/internal/codegen/CompilerTest.java file | annotate | diff | comparison | revisions
test/src/jdk/nashorn/internal/runtime/ContextTest.java file | annotate | diff | comparison | revisions
test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java	Wed Feb 13 13:30:21 2013 +0100
     1.2 +++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java	Wed Feb 13 19:59:30 2013 +0530
     1.3 @@ -453,7 +453,7 @@
     1.4                  setNashornGlobal(ctxtGlobal);
     1.5              }
     1.6  
     1.7 -            return nashornContext.compileScript(source, ctxtGlobal, nashornContext._strict);
     1.8 +            return nashornContext.compileScript(source, ctxtGlobal);
     1.9          } catch (final Exception e) {
    1.10              throwAsScriptException(e);
    1.11              throw new AssertionError("should not reach here");
     2.1 --- a/src/jdk/nashorn/internal/runtime/Context.java	Wed Feb 13 13:30:21 2013 +0100
     2.2 +++ b/src/jdk/nashorn/internal/runtime/Context.java	Wed Feb 13 19:59:30 2013 +0530
     2.3 @@ -492,29 +492,11 @@
     2.4       *
     2.5       * @param source the source
     2.6       * @param scope  the scope
     2.7 -     * @param strict are we in strict mode
     2.8       *
     2.9       * @return top level function for script
    2.10       */
    2.11 -    public ScriptFunction compileScript(final Source source, final ScriptObject scope, final boolean strict) {
    2.12 -        return compileScript(source, scope, this.errors, strict);
    2.13 -    }
    2.14 -
    2.15 -    /**
    2.16 -     * Compile a top level script - no Source given, but an URL to
    2.17 -     * load it from
    2.18 -     *
    2.19 -     * @param name    name of script/source
    2.20 -     * @param url     URL to source
    2.21 -     * @param scope   the scope
    2.22 -     * @param strict  are we in strict mode
    2.23 -     *
    2.24 -     * @return top level function for the script
    2.25 -     *
    2.26 -     * @throws IOException if URL cannot be resolved
    2.27 -     */
    2.28 -    public ScriptFunction compileScript(final String name, final URL url, final ScriptObject scope, final boolean strict) throws IOException {
    2.29 -        return compileScript(name, url, scope, this.errors, strict);
    2.30 +    public ScriptFunction compileScript(final Source source, final ScriptObject scope) {
    2.31 +        return compileScript(source, scope, this.errors);
    2.32      }
    2.33  
    2.34      /**
    2.35 @@ -591,26 +573,25 @@
    2.36       * expression
    2.37       *
    2.38       * @param scope  the scope
    2.39 -     * @param source source expression for script
    2.40 +     * @param from   source expression for script
    2.41       *
    2.42       * @return return value for load call (undefined)
    2.43       *
    2.44       * @throws IOException if source cannot be found or loaded
    2.45       */
    2.46 -    public Object load(final ScriptObject scope, final Object source) throws IOException {
    2.47 -        Object src = source;
    2.48 -        URL url = null;
    2.49 -        String srcName = null;
    2.50 +    public Object load(final ScriptObject scope, final Object from) throws IOException {
    2.51 +        Object src = (from instanceof ConsString)?  from.toString() : from;
    2.52 +        Source source = null;
    2.53  
    2.54 -        if (src instanceof ConsString) {
    2.55 -            src = src.toString();
    2.56 -        }
    2.57 +        // load accepts a String (which could be a URL or a file name), a File, a URL
    2.58 +        // or a ScriptObject that has "name" and "source" (string valued) properties.
    2.59          if (src instanceof String) {
    2.60 -            srcName = (String)src;
    2.61 +            String srcStr = (String)src;
    2.62              final File file = new File((String)src);
    2.63 -            if (srcName.indexOf(':') != -1) {
    2.64 +            if (srcStr.indexOf(':') != -1) {
    2.65                  try {
    2.66 -                    url = new URL((String)src);
    2.67 +                    final URL url = new URL((String)src);
    2.68 +                    source = new Source(url.toString(), url);
    2.69                  } catch (final MalformedURLException e) {
    2.70                      // fallback URL - nashorn:foo.js - check under jdk/nashorn/internal/runtime/resources
    2.71                      final String str = (String)src;
    2.72 @@ -618,7 +599,7 @@
    2.73                          final String resource = "resources/" + str.substring("nashorn:".length());
    2.74                          // NOTE: even sandbox scripts should be able to load scripts in nashorn: scheme
    2.75                          // These scripts are always available and are loaded from nashorn.jar's resources.
    2.76 -                        final Source code = AccessController.doPrivileged(
    2.77 +                        source = AccessController.doPrivileged(
    2.78                                  new PrivilegedAction<Source>() {
    2.79                                      @Override
    2.80                                      public Source run() {
    2.81 @@ -630,45 +611,32 @@
    2.82                                          }
    2.83                                      }
    2.84                                  });
    2.85 -                        if (code == null) {
    2.86 -                            throw e;
    2.87 -                        }
    2.88 -                        return evaluateSource(code, scope, scope);
    2.89                      } else {
    2.90                          throw e;
    2.91                      }
    2.92                  }
    2.93              } else if (file.isFile()) {
    2.94 -                url = file.toURI().toURL();
    2.95 +                source = new Source(srcStr, file);
    2.96              }
    2.97 -            src = url;
    2.98 -        }
    2.99 -
   2.100 -        if (src instanceof File && ((File)src).isFile()) {
   2.101 +        } else if (src instanceof File && ((File)src).isFile()) {
   2.102              final File file = (File)src;
   2.103 -            url = file.toURI().toURL();
   2.104 -            if (srcName == null) {
   2.105 -                srcName = file.getCanonicalPath();
   2.106 -            }
   2.107 +            source = new Source(file.getName(), file);
   2.108          } else if (src instanceof URL) {
   2.109 -            url = (URL)src;
   2.110 -            if (srcName == null) {
   2.111 -                srcName = url.toString();
   2.112 -            }
   2.113 -        }
   2.114 -
   2.115 -        if (url != null) {
   2.116 -            assert srcName != null : "srcName null here!";
   2.117 -            return evaluateSource(srcName, url, scope, scope);
   2.118 +            final URL url = (URL)src;
   2.119 +            source = new Source(url.toString(), url);
   2.120          } else if (src instanceof ScriptObject) {
   2.121              final ScriptObject sobj = (ScriptObject)src;
   2.122              if (sobj.has("script") && sobj.has("name")) {
   2.123                  final String script = JSType.toString(sobj.get("script"));
   2.124                  final String name   = JSType.toString(sobj.get("name"));
   2.125 -                return evaluateSource(new Source(name, script), scope, scope);
   2.126 +                source = new Source(name, script);
   2.127              }
   2.128          }
   2.129  
   2.130 +        if (source != null) {
   2.131 +            return evaluateSource(source, scope, scope);
   2.132 +        }
   2.133 +
   2.134          typeError("cant.load.script", ScriptRuntime.safeToString(source));
   2.135  
   2.136          return UNDEFINED;
   2.137 @@ -850,23 +818,11 @@
   2.138          return (context != null) ? context : Context.getContextTrusted();
   2.139      }
   2.140  
   2.141 -    private Object evaluateSource(final String name, final URL url, final ScriptObject scope, final ScriptObject thiz) throws IOException {
   2.142 -        ScriptFunction script = null;
   2.143 -
   2.144 -        try {
   2.145 -            script = compileScript(name, url, scope, new Context.ThrowErrorManager(), _strict);
   2.146 -        } catch (final ParserException e) {
   2.147 -            e.throwAsEcmaException();
   2.148 -        }
   2.149 -
   2.150 -        return ScriptRuntime.apply(script, thiz);
   2.151 -    }
   2.152 -
   2.153      private Object evaluateSource(final Source source, final ScriptObject scope, final ScriptObject thiz) {
   2.154          ScriptFunction script = null;
   2.155  
   2.156          try {
   2.157 -            script = compileScript(source, scope, new Context.ThrowErrorManager(), _strict);
   2.158 +            script = compileScript(source, scope, new Context.ThrowErrorManager());
   2.159          } catch (final ParserException e) {
   2.160              e.throwAsEcmaException();
   2.161          }
   2.162 @@ -902,19 +858,11 @@
   2.163          return ((GlobalObject)Context.getGlobalTrusted()).newScriptFunction(RUN_SCRIPT.tag(), runMethodHandle, scope, strict);
   2.164      }
   2.165  
   2.166 -    private ScriptFunction compileScript(final String name, final URL url, final ScriptObject scope, final ErrorManager errMan, final boolean strict) throws IOException {
   2.167 -        return getRunScriptFunction(compile(new Source(name, url), url, errMan, strict), scope);
   2.168 +    private ScriptFunction compileScript(final Source source, final ScriptObject scope, final ErrorManager errMan) {
   2.169 +        return getRunScriptFunction(compile(source, errMan, this._strict), scope);
   2.170      }
   2.171  
   2.172 -    private ScriptFunction compileScript(final Source source, final ScriptObject scope, final ErrorManager errMan, final boolean strict) {
   2.173 -        return getRunScriptFunction(compile(source, null, errMan, strict), scope);
   2.174 -    }
   2.175 -
   2.176 -    private Class<?> compile(final Source source, final ErrorManager errMan, final boolean strict) {
   2.177 -        return compile(source, null, errMan, strict);
   2.178 -    }
   2.179 -
   2.180 -   private synchronized Class<?> compile(final Source source, final URL url, final ErrorManager errMan, final boolean strict) {
   2.181 +    private synchronized Class<?> compile(final Source source, final ErrorManager errMan, final boolean strict) {
   2.182          // start with no errors, no warnings.
   2.183          errMan.reset();
   2.184  
   2.185 @@ -935,6 +883,7 @@
   2.186              return null;
   2.187          }
   2.188  
   2.189 +        final URL url = source.getURL();
   2.190          final ScriptLoader loader = _loader_per_compile ? createNewLoader() : scriptLoader;
   2.191          final CodeSource   cs     = url == null ? null : new CodeSource(url, (CodeSigner[])null);
   2.192  
     3.1 --- a/src/jdk/nashorn/internal/runtime/Source.java	Wed Feb 13 13:30:21 2013 +0100
     3.2 +++ b/src/jdk/nashorn/internal/runtime/Source.java	Wed Feb 13 19:59:30 2013 +0530
     3.3 @@ -71,13 +71,20 @@
     3.4      /** Cached hash code */
     3.5      private int hash;
     3.6  
     3.7 +    /** Source URL if available */
     3.8 +    private final URL url;
     3.9 +
    3.10      private static final int BUFSIZE = 8 * 1024;
    3.11  
    3.12 -    private Source(final String name, final String base, final char[] content) {
    3.13 +    // Do *not* make this public ever! Trusts the URL and content. So has to be called
    3.14 +    // from other public constructors. Note that this can not be some init method as
    3.15 +    // we initialize final fields from here.
    3.16 +    private Source(final String name, final String base, final char[] content, final URL url) {
    3.17          this.name    = name;
    3.18          this.base    = base;
    3.19          this.content = content;
    3.20          this.length  = content.length;
    3.21 +        this.url     = url;
    3.22      }
    3.23  
    3.24      /**
    3.25 @@ -87,7 +94,7 @@
    3.26       * @param content contents as char array
    3.27       */
    3.28      public Source(final String name, final char[] content) {
    3.29 -        this(name, baseName(name, null), content);
    3.30 +        this(name, baseName(name, null), content, null);
    3.31      }
    3.32  
    3.33      /**
    3.34 @@ -109,7 +116,7 @@
    3.35       * @throws IOException if source cannot be loaded
    3.36       */
    3.37      public Source(final String name, final URL url) throws IOException {
    3.38 -        this(name, baseURL(url, null), readFully(url.openStream()));
    3.39 +        this(name, baseURL(url, null), readFully(url.openStream()), url);
    3.40      }
    3.41  
    3.42      /**
    3.43 @@ -121,7 +128,7 @@
    3.44       * @throws IOException if source cannot be loaded
    3.45       */
    3.46      public Source(final String name, final File file) throws IOException {
    3.47 -        this(name, dirName(file, null), readFully(file));
    3.48 +        this(name, dirName(file, null), readFully(file), getURLFromFile(file));
    3.49      }
    3.50  
    3.51      @Override
    3.52 @@ -206,6 +213,16 @@
    3.53      }
    3.54  
    3.55      /**
    3.56 +     * Returns the source URL of this script Source. Can be null if Source
    3.57 +     * was created from a String or a char[].
    3.58 +     *
    3.59 +     * @return URL source or null
    3.60 +     */
    3.61 +    public URL getURL() {
    3.62 +        return url;
    3.63 +    }
    3.64 +
    3.65 +    /**
    3.66       * Find the beginning of the line containing position.
    3.67       * @param position Index to offending token.
    3.68       * @return Index of first character of line.
    3.69 @@ -288,7 +305,7 @@
    3.70       * @return content
    3.71       */
    3.72      public char[] getContent() {
    3.73 -        return content;
    3.74 +        return content.clone();
    3.75      }
    3.76  
    3.77      /**
    3.78 @@ -433,4 +450,12 @@
    3.79      public String toString() {
    3.80          return getName();
    3.81      }
    3.82 +
    3.83 +    private static URL getURLFromFile(final File file) {
    3.84 +        try {
    3.85 +            return file.toURI().toURL();
    3.86 +        } catch (final SecurityException | MalformedURLException ignored) {
    3.87 +            return null;
    3.88 +        }
    3.89 +    }
    3.90  }
     4.1 --- a/src/jdk/nashorn/tools/Shell.java	Wed Feb 13 13:30:21 2013 +0100
     4.2 +++ b/src/jdk/nashorn/tools/Shell.java	Wed Feb 13 19:59:30 2013 +0530
     4.3 @@ -282,7 +282,7 @@
     4.4              // For each file on the command line.
     4.5              for (final String fileName : files) {
     4.6                  final File file = new File(fileName);
     4.7 -                ScriptFunction script = context.compileScript(fileName, file.toURI().toURL(), global, context._strict);
     4.8 +                ScriptFunction script = context.compileScript(new Source(fileName, file.toURI().toURL()), global);
     4.9                  if (script == null || errors.getNumberOfErrors() != 0) {
    4.10                      return COMPILATION_ERROR;
    4.11                  }
     5.1 --- a/test/src/jdk/nashorn/internal/codegen/CompilerTest.java	Wed Feb 13 13:30:21 2013 +0100
     5.2 +++ b/test/src/jdk/nashorn/internal/codegen/CompilerTest.java	Wed Feb 13 19:59:30 2013 +0530
     5.3 @@ -159,7 +159,7 @@
     5.4                  Context.setGlobal(global);
     5.5              }
     5.6              final Source source = new Source(file.getAbsolutePath(), buffer);
     5.7 -            final ScriptFunction script = context.compileScript(source, global, context._strict);
     5.8 +            final ScriptFunction script = context.compileScript(source, global);
     5.9              if (script == null || context.getErrorManager().getNumberOfErrors() > 0) {
    5.10                  log("Compile failed: " + file.getAbsolutePath());
    5.11                  failed++;
     6.1 --- a/test/src/jdk/nashorn/internal/runtime/ContextTest.java	Wed Feb 13 13:30:21 2013 +0100
     6.2 +++ b/test/src/jdk/nashorn/internal/runtime/ContextTest.java	Wed Feb 13 19:59:30 2013 +0530
     6.3 @@ -111,7 +111,7 @@
     6.4      private Object eval(final Context cx, final String name, final String code) {
     6.5          final Source source = new Source(name, code);
     6.6          final ScriptObject global = Context.getGlobal();
     6.7 -        final ScriptFunction func = cx.compileScript(source, global, cx._strict);
     6.8 +        final ScriptFunction func = cx.compileScript(source, global);
     6.9          return func != null ? ScriptRuntime.apply(func, global) : null;
    6.10      }
    6.11  
     7.1 --- a/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java	Wed Feb 13 13:30:21 2013 +0100
     7.2 +++ b/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java	Wed Feb 13 19:59:30 2013 +0530
     7.3 @@ -39,6 +39,7 @@
     7.4  import jdk.nashorn.internal.runtime.ScriptFunction;
     7.5  import jdk.nashorn.internal.runtime.ScriptObject;
     7.6  import jdk.nashorn.internal.runtime.ScriptRuntime;
     7.7 +import jdk.nashorn.internal.runtime.Source;
     7.8  import jdk.nashorn.internal.runtime.options.Options;
     7.9  
    7.10  /**
    7.11 @@ -124,7 +125,7 @@
    7.12                      continue;
    7.13                  }
    7.14                  final File file = new File(fileName);
    7.15 -                ScriptFunction script = context.compileScript(fileName, file.toURI().toURL(), global, context._strict);
    7.16 +                ScriptFunction script = context.compileScript(new Source(fileName, file.toURI().toURL()), global);
    7.17                  if (script == null || errors.getNumberOfErrors() != 0) {
    7.18                      return COMPILATION_ERROR;
    7.19                  }

mercurial