mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 03:24:38 +02:00
8008103: Source object should maintain URL of the script source as a private field
Reviewed-by: lagergren, jlaskey
This commit is contained in:
parent
b8d10c0a0e
commit
ecc2be22e3
7 changed files with 64 additions and 89 deletions
|
@ -453,7 +453,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
||||||
setNashornGlobal(ctxtGlobal);
|
setNashornGlobal(ctxtGlobal);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nashornContext.compileScript(source, ctxtGlobal, nashornContext._strict);
|
return nashornContext.compileScript(source, ctxtGlobal);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
throwAsScriptException(e);
|
throwAsScriptException(e);
|
||||||
throw new AssertionError("should not reach here");
|
throw new AssertionError("should not reach here");
|
||||||
|
|
|
@ -492,29 +492,11 @@ public final class Context {
|
||||||
*
|
*
|
||||||
* @param source the source
|
* @param source the source
|
||||||
* @param scope the scope
|
* @param scope the scope
|
||||||
* @param strict are we in strict mode
|
|
||||||
*
|
*
|
||||||
* @return top level function for script
|
* @return top level function for script
|
||||||
*/
|
*/
|
||||||
public ScriptFunction compileScript(final Source source, final ScriptObject scope, final boolean strict) {
|
public ScriptFunction compileScript(final Source source, final ScriptObject scope) {
|
||||||
return compileScript(source, scope, this.errors, strict);
|
return compileScript(source, scope, this.errors);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compile a top level script - no Source given, but an URL to
|
|
||||||
* load it from
|
|
||||||
*
|
|
||||||
* @param name name of script/source
|
|
||||||
* @param url URL to source
|
|
||||||
* @param scope the scope
|
|
||||||
* @param strict are we in strict mode
|
|
||||||
*
|
|
||||||
* @return top level function for the script
|
|
||||||
*
|
|
||||||
* @throws IOException if URL cannot be resolved
|
|
||||||
*/
|
|
||||||
public ScriptFunction compileScript(final String name, final URL url, final ScriptObject scope, final boolean strict) throws IOException {
|
|
||||||
return compileScript(name, url, scope, this.errors, strict);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -591,26 +573,25 @@ public final class Context {
|
||||||
* expression
|
* expression
|
||||||
*
|
*
|
||||||
* @param scope the scope
|
* @param scope the scope
|
||||||
* @param source source expression for script
|
* @param from source expression for script
|
||||||
*
|
*
|
||||||
* @return return value for load call (undefined)
|
* @return return value for load call (undefined)
|
||||||
*
|
*
|
||||||
* @throws IOException if source cannot be found or loaded
|
* @throws IOException if source cannot be found or loaded
|
||||||
*/
|
*/
|
||||||
public Object load(final ScriptObject scope, final Object source) throws IOException {
|
public Object load(final ScriptObject scope, final Object from) throws IOException {
|
||||||
Object src = source;
|
Object src = (from instanceof ConsString)? from.toString() : from;
|
||||||
URL url = null;
|
Source source = null;
|
||||||
String srcName = null;
|
|
||||||
|
|
||||||
if (src instanceof ConsString) {
|
// load accepts a String (which could be a URL or a file name), a File, a URL
|
||||||
src = src.toString();
|
// or a ScriptObject that has "name" and "source" (string valued) properties.
|
||||||
}
|
|
||||||
if (src instanceof String) {
|
if (src instanceof String) {
|
||||||
srcName = (String)src;
|
String srcStr = (String)src;
|
||||||
final File file = new File((String)src);
|
final File file = new File((String)src);
|
||||||
if (srcName.indexOf(':') != -1) {
|
if (srcStr.indexOf(':') != -1) {
|
||||||
try {
|
try {
|
||||||
url = new URL((String)src);
|
final URL url = new URL((String)src);
|
||||||
|
source = new Source(url.toString(), url);
|
||||||
} catch (final MalformedURLException e) {
|
} catch (final MalformedURLException e) {
|
||||||
// fallback URL - nashorn:foo.js - check under jdk/nashorn/internal/runtime/resources
|
// fallback URL - nashorn:foo.js - check under jdk/nashorn/internal/runtime/resources
|
||||||
final String str = (String)src;
|
final String str = (String)src;
|
||||||
|
@ -618,7 +599,7 @@ public final class Context {
|
||||||
final String resource = "resources/" + str.substring("nashorn:".length());
|
final String resource = "resources/" + str.substring("nashorn:".length());
|
||||||
// NOTE: even sandbox scripts should be able to load scripts in nashorn: scheme
|
// NOTE: even sandbox scripts should be able to load scripts in nashorn: scheme
|
||||||
// These scripts are always available and are loaded from nashorn.jar's resources.
|
// These scripts are always available and are loaded from nashorn.jar's resources.
|
||||||
final Source code = AccessController.doPrivileged(
|
source = AccessController.doPrivileged(
|
||||||
new PrivilegedAction<Source>() {
|
new PrivilegedAction<Source>() {
|
||||||
@Override
|
@Override
|
||||||
public Source run() {
|
public Source run() {
|
||||||
|
@ -630,45 +611,32 @@ public final class Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (code == null) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
return evaluateSource(code, scope, scope);
|
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (file.isFile()) {
|
} else if (file.isFile()) {
|
||||||
url = file.toURI().toURL();
|
source = new Source(srcStr, file);
|
||||||
}
|
}
|
||||||
src = url;
|
} else if (src instanceof File && ((File)src).isFile()) {
|
||||||
}
|
|
||||||
|
|
||||||
if (src instanceof File && ((File)src).isFile()) {
|
|
||||||
final File file = (File)src;
|
final File file = (File)src;
|
||||||
url = file.toURI().toURL();
|
source = new Source(file.getName(), file);
|
||||||
if (srcName == null) {
|
|
||||||
srcName = file.getCanonicalPath();
|
|
||||||
}
|
|
||||||
} else if (src instanceof URL) {
|
} else if (src instanceof URL) {
|
||||||
url = (URL)src;
|
final URL url = (URL)src;
|
||||||
if (srcName == null) {
|
source = new Source(url.toString(), url);
|
||||||
srcName = url.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (url != null) {
|
|
||||||
assert srcName != null : "srcName null here!";
|
|
||||||
return evaluateSource(srcName, url, scope, scope);
|
|
||||||
} else if (src instanceof ScriptObject) {
|
} else if (src instanceof ScriptObject) {
|
||||||
final ScriptObject sobj = (ScriptObject)src;
|
final ScriptObject sobj = (ScriptObject)src;
|
||||||
if (sobj.has("script") && sobj.has("name")) {
|
if (sobj.has("script") && sobj.has("name")) {
|
||||||
final String script = JSType.toString(sobj.get("script"));
|
final String script = JSType.toString(sobj.get("script"));
|
||||||
final String name = JSType.toString(sobj.get("name"));
|
final String name = JSType.toString(sobj.get("name"));
|
||||||
return evaluateSource(new Source(name, script), scope, scope);
|
source = new Source(name, script);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (source != null) {
|
||||||
|
return evaluateSource(source, scope, scope);
|
||||||
|
}
|
||||||
|
|
||||||
typeError("cant.load.script", ScriptRuntime.safeToString(source));
|
typeError("cant.load.script", ScriptRuntime.safeToString(source));
|
||||||
|
|
||||||
return UNDEFINED;
|
return UNDEFINED;
|
||||||
|
@ -850,23 +818,11 @@ public final class Context {
|
||||||
return (context != null) ? context : Context.getContextTrusted();
|
return (context != null) ? context : Context.getContextTrusted();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object evaluateSource(final String name, final URL url, final ScriptObject scope, final ScriptObject thiz) throws IOException {
|
|
||||||
ScriptFunction script = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
script = compileScript(name, url, scope, new Context.ThrowErrorManager(), _strict);
|
|
||||||
} catch (final ParserException e) {
|
|
||||||
e.throwAsEcmaException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ScriptRuntime.apply(script, thiz);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object evaluateSource(final Source source, final ScriptObject scope, final ScriptObject thiz) {
|
private Object evaluateSource(final Source source, final ScriptObject scope, final ScriptObject thiz) {
|
||||||
ScriptFunction script = null;
|
ScriptFunction script = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
script = compileScript(source, scope, new Context.ThrowErrorManager(), _strict);
|
script = compileScript(source, scope, new Context.ThrowErrorManager());
|
||||||
} catch (final ParserException e) {
|
} catch (final ParserException e) {
|
||||||
e.throwAsEcmaException();
|
e.throwAsEcmaException();
|
||||||
}
|
}
|
||||||
|
@ -902,19 +858,11 @@ public final class Context {
|
||||||
return ((GlobalObject)Context.getGlobalTrusted()).newScriptFunction(RUN_SCRIPT.tag(), runMethodHandle, scope, strict);
|
return ((GlobalObject)Context.getGlobalTrusted()).newScriptFunction(RUN_SCRIPT.tag(), runMethodHandle, scope, strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScriptFunction compileScript(final String name, final URL url, final ScriptObject scope, final ErrorManager errMan, final boolean strict) throws IOException {
|
private ScriptFunction compileScript(final Source source, final ScriptObject scope, final ErrorManager errMan) {
|
||||||
return getRunScriptFunction(compile(new Source(name, url), url, errMan, strict), scope);
|
return getRunScriptFunction(compile(source, errMan, this._strict), scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScriptFunction compileScript(final Source source, final ScriptObject scope, final ErrorManager errMan, final boolean strict) {
|
private synchronized Class<?> compile(final Source source, final ErrorManager errMan, final boolean strict) {
|
||||||
return getRunScriptFunction(compile(source, null, errMan, strict), scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Class<?> compile(final Source source, final ErrorManager errMan, final boolean strict) {
|
|
||||||
return compile(source, null, errMan, strict);
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized Class<?> compile(final Source source, final URL url, final ErrorManager errMan, final boolean strict) {
|
|
||||||
// start with no errors, no warnings.
|
// start with no errors, no warnings.
|
||||||
errMan.reset();
|
errMan.reset();
|
||||||
|
|
||||||
|
@ -935,6 +883,7 @@ public final class Context {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final URL url = source.getURL();
|
||||||
final ScriptLoader loader = _loader_per_compile ? createNewLoader() : scriptLoader;
|
final ScriptLoader loader = _loader_per_compile ? createNewLoader() : scriptLoader;
|
||||||
final CodeSource cs = url == null ? null : new CodeSource(url, (CodeSigner[])null);
|
final CodeSource cs = url == null ? null : new CodeSource(url, (CodeSigner[])null);
|
||||||
|
|
||||||
|
|
|
@ -71,13 +71,20 @@ public final class Source {
|
||||||
/** Cached hash code */
|
/** Cached hash code */
|
||||||
private int hash;
|
private int hash;
|
||||||
|
|
||||||
|
/** Source URL if available */
|
||||||
|
private final URL url;
|
||||||
|
|
||||||
private static final int BUFSIZE = 8 * 1024;
|
private static final int BUFSIZE = 8 * 1024;
|
||||||
|
|
||||||
private Source(final String name, final String base, final char[] content) {
|
// Do *not* make this public ever! Trusts the URL and content. So has to be called
|
||||||
|
// from other public constructors. Note that this can not be some init method as
|
||||||
|
// we initialize final fields from here.
|
||||||
|
private Source(final String name, final String base, final char[] content, final URL url) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.base = base;
|
this.base = base;
|
||||||
this.content = content;
|
this.content = content;
|
||||||
this.length = content.length;
|
this.length = content.length;
|
||||||
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,7 +94,7 @@ public final class Source {
|
||||||
* @param content contents as char array
|
* @param content contents as char array
|
||||||
*/
|
*/
|
||||||
public Source(final String name, final char[] content) {
|
public Source(final String name, final char[] content) {
|
||||||
this(name, baseName(name, null), content);
|
this(name, baseName(name, null), content, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -109,7 +116,7 @@ public final class Source {
|
||||||
* @throws IOException if source cannot be loaded
|
* @throws IOException if source cannot be loaded
|
||||||
*/
|
*/
|
||||||
public Source(final String name, final URL url) throws IOException {
|
public Source(final String name, final URL url) throws IOException {
|
||||||
this(name, baseURL(url, null), readFully(url.openStream()));
|
this(name, baseURL(url, null), readFully(url.openStream()), url);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -121,7 +128,7 @@ public final class Source {
|
||||||
* @throws IOException if source cannot be loaded
|
* @throws IOException if source cannot be loaded
|
||||||
*/
|
*/
|
||||||
public Source(final String name, final File file) throws IOException {
|
public Source(final String name, final File file) throws IOException {
|
||||||
this(name, dirName(file, null), readFully(file));
|
this(name, dirName(file, null), readFully(file), getURLFromFile(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -205,6 +212,16 @@ public final class Source {
|
||||||
return new String(content, start, end - start);
|
return new String(content, start, end - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the source URL of this script Source. Can be null if Source
|
||||||
|
* was created from a String or a char[].
|
||||||
|
*
|
||||||
|
* @return URL source or null
|
||||||
|
*/
|
||||||
|
public URL getURL() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the beginning of the line containing position.
|
* Find the beginning of the line containing position.
|
||||||
* @param position Index to offending token.
|
* @param position Index to offending token.
|
||||||
|
@ -288,7 +305,7 @@ public final class Source {
|
||||||
* @return content
|
* @return content
|
||||||
*/
|
*/
|
||||||
public char[] getContent() {
|
public char[] getContent() {
|
||||||
return content;
|
return content.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -433,4 +450,12 @@ public final class Source {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getName();
|
return getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static URL getURLFromFile(final File file) {
|
||||||
|
try {
|
||||||
|
return file.toURI().toURL();
|
||||||
|
} catch (final SecurityException | MalformedURLException ignored) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -282,7 +282,7 @@ public class Shell {
|
||||||
// For each file on the command line.
|
// For each file on the command line.
|
||||||
for (final String fileName : files) {
|
for (final String fileName : files) {
|
||||||
final File file = new File(fileName);
|
final File file = new File(fileName);
|
||||||
ScriptFunction script = context.compileScript(fileName, file.toURI().toURL(), global, context._strict);
|
ScriptFunction script = context.compileScript(new Source(fileName, file.toURI().toURL()), global);
|
||||||
if (script == null || errors.getNumberOfErrors() != 0) {
|
if (script == null || errors.getNumberOfErrors() != 0) {
|
||||||
return COMPILATION_ERROR;
|
return COMPILATION_ERROR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,7 @@ public class CompilerTest {
|
||||||
Context.setGlobal(global);
|
Context.setGlobal(global);
|
||||||
}
|
}
|
||||||
final Source source = new Source(file.getAbsolutePath(), buffer);
|
final Source source = new Source(file.getAbsolutePath(), buffer);
|
||||||
final ScriptFunction script = context.compileScript(source, global, context._strict);
|
final ScriptFunction script = context.compileScript(source, global);
|
||||||
if (script == null || context.getErrorManager().getNumberOfErrors() > 0) {
|
if (script == null || context.getErrorManager().getNumberOfErrors() > 0) {
|
||||||
log("Compile failed: " + file.getAbsolutePath());
|
log("Compile failed: " + file.getAbsolutePath());
|
||||||
failed++;
|
failed++;
|
||||||
|
|
|
@ -111,7 +111,7 @@ public class ContextTest {
|
||||||
private Object eval(final Context cx, final String name, final String code) {
|
private Object eval(final Context cx, final String name, final String code) {
|
||||||
final Source source = new Source(name, code);
|
final Source source = new Source(name, code);
|
||||||
final ScriptObject global = Context.getGlobal();
|
final ScriptObject global = Context.getGlobal();
|
||||||
final ScriptFunction func = cx.compileScript(source, global, cx._strict);
|
final ScriptFunction func = cx.compileScript(source, global);
|
||||||
return func != null ? ScriptRuntime.apply(func, global) : null;
|
return func != null ? ScriptRuntime.apply(func, global) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ import jdk.nashorn.internal.runtime.ErrorManager;
|
||||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||||
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||||
|
import jdk.nashorn.internal.runtime.Source;
|
||||||
import jdk.nashorn.internal.runtime.options.Options;
|
import jdk.nashorn.internal.runtime.options.Options;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -124,7 +125,7 @@ public final class SharedContextEvaluator implements ScriptEvaluator {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final File file = new File(fileName);
|
final File file = new File(fileName);
|
||||||
ScriptFunction script = context.compileScript(fileName, file.toURI().toURL(), global, context._strict);
|
ScriptFunction script = context.compileScript(new Source(fileName, file.toURI().toURL()), global);
|
||||||
if (script == null || errors.getNumberOfErrors() != 0) {
|
if (script == null || errors.getNumberOfErrors() != 0) {
|
||||||
return COMPILATION_ERROR;
|
return COMPILATION_ERROR;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue