author | attila |
Wed, 26 Feb 2014 13:17:57 +0100 | |
changeset 24719 | f726e9d67629 |
parent 23076 | 8660ebaaa2f2 |
child 24725 | 7bb1f687a852 |
permissions | -rw-r--r-- |
16147 | 1 |
/* |
16151 | 2 |
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. |
16147 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
7 |
* published by the Free Software Foundation. Oracle designates this |
|
8 |
* particular file as subject to the "Classpath" exception as provided |
|
9 |
* by Oracle in the LICENSE file that accompanied this code. |
|
10 |
* |
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
24 |
*/ |
|
25 |
||
26 |
package jdk.nashorn.internal.runtime; |
|
27 |
||
24719 | 28 |
import static jdk.nashorn.internal.codegen.CompilerConstants.CREATE_PROGRAM_FUNCTION; |
16147 | 29 |
import static jdk.nashorn.internal.codegen.CompilerConstants.STRICT_MODE; |
30 |
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; |
|
31 |
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; |
|
32 |
||
33 |
import java.io.File; |
|
34 |
import java.io.IOException; |
|
35 |
import java.io.PrintWriter; |
|
24719 | 36 |
import java.lang.reflect.InvocationTargetException; |
19088
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
37 |
import java.lang.reflect.Modifier; |
16254 | 38 |
import java.net.MalformedURLException; |
16147 | 39 |
import java.net.URL; |
19097
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
19088
diff
changeset
|
40 |
import java.security.AccessControlContext; |
16147 | 41 |
import java.security.AccessController; |
42 |
import java.security.CodeSigner; |
|
43 |
import java.security.CodeSource; |
|
19097
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
19088
diff
changeset
|
44 |
import java.security.Permissions; |
16147 | 45 |
import java.security.PrivilegedAction; |
19097
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
19088
diff
changeset
|
46 |
import java.security.ProtectionDomain; |
18334
47413e8d71b5
8016618: script mirror object access should be improved
sundar
parents:
18328
diff
changeset
|
47 |
import java.util.Map; |
22669 | 48 |
import java.util.concurrent.atomic.AtomicLong; |
16147 | 49 |
import jdk.internal.org.objectweb.asm.ClassReader; |
50 |
import jdk.internal.org.objectweb.asm.util.CheckClassAdapter; |
|
17979
adae4d39ee07
8015945: loadWithNewGlobal return value has to be properly wrapped
sundar
parents:
17976
diff
changeset
|
51 |
import jdk.nashorn.api.scripting.ScriptObjectMirror; |
24719 | 52 |
import jdk.nashorn.internal.codegen.CompilationEnvironment; |
53 |
import jdk.nashorn.internal.codegen.CompilationEnvironment.CompilationPhases; |
|
16147 | 54 |
import jdk.nashorn.internal.codegen.Compiler; |
24719 | 55 |
import jdk.nashorn.internal.codegen.CompilerConstants; |
16240
e1468b33e201
8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
16233
diff
changeset
|
56 |
import jdk.nashorn.internal.codegen.ObjectClassGenerator; |
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
57 |
import jdk.nashorn.internal.ir.FunctionNode; |
16240
e1468b33e201
8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
16233
diff
changeset
|
58 |
import jdk.nashorn.internal.ir.debug.ASTWriter; |
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
59 |
import jdk.nashorn.internal.ir.debug.PrintVisitor; |
18851
bdb92c95f886
8019947: inherited property invalidation does not work with two globals in same context
sundar
parents:
18618
diff
changeset
|
60 |
import jdk.nashorn.internal.objects.Global; |
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
61 |
import jdk.nashorn.internal.parser.Parser; |
16147 | 62 |
import jdk.nashorn.internal.runtime.options.Options; |
63 |
||
64 |
/** |
|
65 |
* This class manages the global state of execution. Context is immutable. |
|
66 |
*/ |
|
67 |
public final class Context { |
|
19459 | 68 |
// nashorn specific security runtime access permission names |
69 |
/** |
|
70 |
* Permission needed to pass arbitrary nashorn command line options when creating Context. |
|
71 |
*/ |
|
72 |
public static final String NASHORN_SET_CONFIG = "nashorn.setConfig"; |
|
73 |
||
74 |
/** |
|
75 |
* Permission needed to create Nashorn Context instance. |
|
76 |
*/ |
|
77 |
public static final String NASHORN_CREATE_CONTEXT = "nashorn.createContext"; |
|
78 |
||
79 |
/** |
|
80 |
* Permission needed to create Nashorn Global instance. |
|
81 |
*/ |
|
82 |
public static final String NASHORN_CREATE_GLOBAL = "nashorn.createGlobal"; |
|
83 |
||
84 |
/** |
|
85 |
* Permission to get current Nashorn Context from thread local storage. |
|
86 |
*/ |
|
87 |
public static final String NASHORN_GET_CONTEXT = "nashorn.getContext"; |
|
88 |
||
89 |
/** |
|
90 |
* Permission to use Java reflection/jsr292 from script code. |
|
91 |
*/ |
|
92 |
public static final String NASHORN_JAVA_REFLECTION = "nashorn.JavaReflection"; |
|
16147 | 93 |
|
22389
ea3dda90768c
8032060: PropertyMap of Error objects is not stable
sundar
parents:
20933
diff
changeset
|
94 |
/** |
ea3dda90768c
8032060: PropertyMap of Error objects is not stable
sundar
parents:
20933
diff
changeset
|
95 |
* Permission to enable nashorn debug mode. |
ea3dda90768c
8032060: PropertyMap of Error objects is not stable
sundar
parents:
20933
diff
changeset
|
96 |
*/ |
ea3dda90768c
8032060: PropertyMap of Error objects is not stable
sundar
parents:
20933
diff
changeset
|
97 |
public static final String NASHORN_DEBUG_MODE = "nashorn.debugMode"; |
ea3dda90768c
8032060: PropertyMap of Error objects is not stable
sundar
parents:
20933
diff
changeset
|
98 |
|
20564
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
99 |
// nashorn load psuedo URL prefixes |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
100 |
private static final String LOAD_CLASSPATH = "classpath:"; |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
101 |
private static final String LOAD_FX = "fx:"; |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
102 |
private static final String LOAD_NASHORN = "nashorn:"; |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
103 |
|
19622
b042dad0de96
8023228: Debugger information gather is too slow.
jlaskey
parents:
19472
diff
changeset
|
104 |
/* Force DebuggerSupport to be loaded. */ |
b042dad0de96
8023228: Debugger information gather is too slow.
jlaskey
parents:
19472
diff
changeset
|
105 |
static { |
b042dad0de96
8023228: Debugger information gather is too slow.
jlaskey
parents:
19472
diff
changeset
|
106 |
DebuggerSupport.FORCELOAD = true; |
b042dad0de96
8023228: Debugger information gather is too slow.
jlaskey
parents:
19472
diff
changeset
|
107 |
} |
b042dad0de96
8023228: Debugger information gather is too slow.
jlaskey
parents:
19472
diff
changeset
|
108 |
|
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
109 |
/** |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
110 |
* ContextCodeInstaller that has the privilege of installing classes in the Context. |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
111 |
* Can only be instantiated from inside the context and is opaque to other classes |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
112 |
*/ |
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
113 |
public static class ContextCodeInstaller implements CodeInstaller<ScriptEnvironment> { |
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
114 |
private final Context context; |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
115 |
private final ScriptLoader loader; |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
116 |
private final CodeSource codeSource; |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
117 |
|
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
118 |
private ContextCodeInstaller(final Context context, final ScriptLoader loader, final CodeSource codeSource) { |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
119 |
this.context = context; |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
120 |
this.loader = loader; |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
121 |
this.codeSource = codeSource; |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
122 |
} |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
123 |
|
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
124 |
/** |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
125 |
* Return the context for this installer |
16523
af8b30edebce
8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change.
lagergren
parents:
16522
diff
changeset
|
126 |
* @return ScriptEnvironment |
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
127 |
*/ |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
128 |
@Override |
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
129 |
public ScriptEnvironment getOwner() { |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
130 |
return context.env; |
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
131 |
} |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
132 |
|
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
133 |
@Override |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
134 |
public Class<?> install(final String className, final byte[] bytecode) { |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
135 |
return loader.installClass(className, bytecode, codeSource); |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
136 |
} |
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
137 |
|
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
138 |
@Override |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
139 |
public void verify(final byte[] code) { |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
140 |
context.verify(code); |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
141 |
} |
18862
8b6a01b38cb8
8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents:
18860
diff
changeset
|
142 |
|
8b6a01b38cb8
8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents:
18860
diff
changeset
|
143 |
@Override |
8b6a01b38cb8
8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents:
18860
diff
changeset
|
144 |
public long getUniqueScriptId() { |
8b6a01b38cb8
8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents:
18860
diff
changeset
|
145 |
return context.getUniqueScriptId(); |
8b6a01b38cb8
8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents:
18860
diff
changeset
|
146 |
} |
20929
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
20928
diff
changeset
|
147 |
|
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
20928
diff
changeset
|
148 |
@Override |
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
20928
diff
changeset
|
149 |
public long getUniqueEvalId() { |
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
20928
diff
changeset
|
150 |
return context.getUniqueEvalId(); |
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
20928
diff
changeset
|
151 |
} |
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
152 |
} |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
153 |
|
16147 | 154 |
/** Is Context global debug mode enabled ? */ |
155 |
public static final boolean DEBUG = Options.getBooleanProperty("nashorn.debug"); |
|
156 |
||
18618
136279c4cbe6
8019157: Avoid calling ScriptObject.setProto() if possible
hannesw
parents:
18334
diff
changeset
|
157 |
private static final ThreadLocal<ScriptObject> currentGlobal = new ThreadLocal<>(); |
16147 | 158 |
|
159 |
/** |
|
16188 | 160 |
* Get the current global scope |
161 |
* @return the current global scope |
|
16147 | 162 |
*/ |
163 |
public static ScriptObject getGlobal() { |
|
17231 | 164 |
// This class in a package.access protected package. |
165 |
// Trusted code only can call this method. |
|
16188 | 166 |
return getGlobalTrusted(); |
16147 | 167 |
} |
168 |
||
169 |
/** |
|
170 |
* Set the current global scope |
|
171 |
* @param global the global scope |
|
172 |
*/ |
|
173 |
public static void setGlobal(final ScriptObject global) { |
|
18851
bdb92c95f886
8019947: inherited property invalidation does not work with two globals in same context
sundar
parents:
18618
diff
changeset
|
174 |
if (global != null && !(global instanceof Global)) { |
bdb92c95f886
8019947: inherited property invalidation does not work with two globals in same context
sundar
parents:
18618
diff
changeset
|
175 |
throw new IllegalArgumentException("global is not an instance of Global!"); |
16147 | 176 |
} |
177 |
||
16188 | 178 |
setGlobalTrusted(global); |
16147 | 179 |
} |
180 |
||
181 |
/** |
|
182 |
* Get context of the current global |
|
183 |
* @return current global scope's context. |
|
184 |
*/ |
|
185 |
public static Context getContext() { |
|
16185 | 186 |
final SecurityManager sm = System.getSecurityManager(); |
187 |
if (sm != null) { |
|
19459 | 188 |
sm.checkPermission(new RuntimePermission(NASHORN_GET_CONTEXT)); |
16185 | 189 |
} |
190 |
return getContextTrusted(); |
|
191 |
} |
|
192 |
||
193 |
/** |
|
194 |
* Get current context's error writer |
|
195 |
* |
|
196 |
* @return error writer of the current context |
|
197 |
*/ |
|
198 |
public static PrintWriter getCurrentErr() { |
|
16188 | 199 |
final ScriptObject global = getGlobalTrusted(); |
16185 | 200 |
return (global != null)? global.getContext().getErr() : new PrintWriter(System.err); |
16147 | 201 |
} |
202 |
||
203 |
/** |
|
204 |
* Output text to this Context's error stream |
|
205 |
* @param str text to write |
|
206 |
*/ |
|
207 |
public static void err(final String str) { |
|
208 |
err(str, true); |
|
209 |
} |
|
210 |
||
211 |
/** |
|
212 |
* Output text to this Context's error stream, optionally with |
|
213 |
* a newline afterwards |
|
214 |
* |
|
215 |
* @param str text to write |
|
216 |
* @param crlf write a carriage return/new line after text |
|
217 |
*/ |
|
17524
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17519
diff
changeset
|
218 |
@SuppressWarnings("resource") |
16147 | 219 |
public static void err(final String str, final boolean crlf) { |
16185 | 220 |
final PrintWriter err = Context.getCurrentErr(); |
16155
a8ab83cbaa49
8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents:
16151
diff
changeset
|
221 |
if (err != null) { |
a8ab83cbaa49
8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents:
16151
diff
changeset
|
222 |
if (crlf) { |
a8ab83cbaa49
8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents:
16151
diff
changeset
|
223 |
err.println(str); |
16147 | 224 |
} else { |
16155
a8ab83cbaa49
8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents:
16151
diff
changeset
|
225 |
err.print(str); |
16147 | 226 |
} |
227 |
} |
|
228 |
} |
|
229 |
||
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
230 |
/** Current environment. */ |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
231 |
private final ScriptEnvironment env; |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
232 |
|
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
233 |
/** is this context in strict mode? Cached from env. as this is used heavily. */ |
18328
ebd24057f163
8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents:
18321
diff
changeset
|
234 |
final boolean _strict; |
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
235 |
|
16185 | 236 |
/** class loader to resolve classes from script. */ |
237 |
private final ClassLoader appLoader; |
|
238 |
||
16147 | 239 |
/** Class loader to load classes from -classpath option, if set. */ |
240 |
private final ClassLoader classPathLoader; |
|
241 |
||
242 |
/** Class loader to load classes compiled from scripts. */ |
|
243 |
private final ScriptLoader scriptLoader; |
|
244 |
||
245 |
/** Current error manager. */ |
|
246 |
private final ErrorManager errors; |
|
247 |
||
18862
8b6a01b38cb8
8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents:
18860
diff
changeset
|
248 |
/** Unique id for script. Used only when --loader-per-compile=false */ |
18864
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
249 |
private final AtomicLong uniqueScriptId; |
18862
8b6a01b38cb8
8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents:
18860
diff
changeset
|
250 |
|
20929
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
20928
diff
changeset
|
251 |
/** Unique id for 'eval' */ |
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
20928
diff
changeset
|
252 |
private final AtomicLong uniqueEvalId; |
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
20928
diff
changeset
|
253 |
|
16185 | 254 |
private static final ClassLoader myLoader = Context.class.getClassLoader(); |
16147 | 255 |
private static final StructureLoader sharedLoader; |
19459 | 256 |
|
20933
89748612fd1d
8026250: Logging nullpointer bugfix and javadoc warnings
lagergren
parents:
20929
diff
changeset
|
257 |
/*package-private*/ @SuppressWarnings("static-method") |
89748612fd1d
8026250: Logging nullpointer bugfix and javadoc warnings
lagergren
parents:
20929
diff
changeset
|
258 |
ClassLoader getSharedLoader() { |
19895
965b12eb322e
8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents:
19884
diff
changeset
|
259 |
return sharedLoader; |
965b12eb322e
8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents:
19884
diff
changeset
|
260 |
} |
965b12eb322e
8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents:
19884
diff
changeset
|
261 |
|
19459 | 262 |
private static AccessControlContext createNoPermAccCtxt() { |
263 |
return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) }); |
|
264 |
} |
|
265 |
||
266 |
private static AccessControlContext createPermAccCtxt(final String permName) { |
|
267 |
final Permissions perms = new Permissions(); |
|
268 |
perms.add(new RuntimePermission(permName)); |
|
269 |
return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) }); |
|
270 |
} |
|
271 |
||
272 |
private static final AccessControlContext NO_PERMISSIONS_ACC_CTXT = createNoPermAccCtxt(); |
|
273 |
private static final AccessControlContext CREATE_LOADER_ACC_CTXT = createPermAccCtxt("createClassLoader"); |
|
274 |
private static final AccessControlContext CREATE_GLOBAL_ACC_CTXT = createPermAccCtxt(NASHORN_CREATE_GLOBAL); |
|
16147 | 275 |
|
276 |
static { |
|
277 |
sharedLoader = AccessController.doPrivileged(new PrivilegedAction<StructureLoader>() { |
|
278 |
@Override |
|
279 |
public StructureLoader run() { |
|
19895
965b12eb322e
8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents:
19884
diff
changeset
|
280 |
return new StructureLoader(myLoader); |
16147 | 281 |
} |
19459 | 282 |
}, CREATE_LOADER_ACC_CTXT); |
16147 | 283 |
} |
284 |
||
285 |
/** |
|
286 |
* ThrowErrorManager that throws ParserException upon error conditions. |
|
287 |
*/ |
|
288 |
public static class ThrowErrorManager extends ErrorManager { |
|
289 |
@Override |
|
290 |
public void error(final String message) { |
|
291 |
throw new ParserException(message); |
|
292 |
} |
|
293 |
||
294 |
@Override |
|
295 |
public void error(final ParserException e) { |
|
296 |
throw e; |
|
297 |
} |
|
298 |
} |
|
299 |
||
300 |
/** |
|
301 |
* Constructor |
|
302 |
* |
|
303 |
* @param options options from command line or Context creator |
|
304 |
* @param errors error manger |
|
16185 | 305 |
* @param appLoader application class loader |
16147 | 306 |
*/ |
16185 | 307 |
public Context(final Options options, final ErrorManager errors, final ClassLoader appLoader) { |
308 |
this(options, errors, new PrintWriter(System.out, true), new PrintWriter(System.err, true), appLoader); |
|
16147 | 309 |
} |
310 |
||
311 |
/** |
|
312 |
* Constructor |
|
313 |
* |
|
314 |
* @param options options from command line or Context creator |
|
315 |
* @param errors error manger |
|
316 |
* @param out output writer for this Context |
|
317 |
* @param err error writer for this Context |
|
16185 | 318 |
* @param appLoader application class loader |
16147 | 319 |
*/ |
16185 | 320 |
public Context(final Options options, final ErrorManager errors, final PrintWriter out, final PrintWriter err, final ClassLoader appLoader) { |
16147 | 321 |
final SecurityManager sm = System.getSecurityManager(); |
322 |
if (sm != null) { |
|
19459 | 323 |
sm.checkPermission(new RuntimePermission(NASHORN_CREATE_CONTEXT)); |
16147 | 324 |
} |
325 |
||
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
326 |
this.env = new ScriptEnvironment(options, out, err); |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
327 |
this._strict = env._strict; |
16185 | 328 |
this.appLoader = appLoader; |
18864
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
329 |
if (env._loader_per_compile) { |
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
330 |
this.scriptLoader = null; |
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
331 |
this.uniqueScriptId = null; |
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
332 |
} else { |
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
333 |
this.scriptLoader = createNewLoader(); |
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
334 |
this.uniqueScriptId = new AtomicLong(); |
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
335 |
} |
16147 | 336 |
this.errors = errors; |
20929
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
20928
diff
changeset
|
337 |
this.uniqueEvalId = new AtomicLong(); |
16147 | 338 |
|
339 |
// if user passed -classpath option, make a class loader with that and set it as |
|
340 |
// thread context class loader so that script can access classes from that path. |
|
341 |
final String classPath = options.getString("classpath"); |
|
24719 | 342 |
if (!env._compile_only && classPath != null && !classPath.isEmpty()) { |
16147 | 343 |
// make sure that caller can create a class loader. |
344 |
if (sm != null) { |
|
345 |
sm.checkPermission(new RuntimePermission("createClassLoader")); |
|
346 |
} |
|
347 |
this.classPathLoader = NashornLoader.createClassLoader(classPath); |
|
348 |
} else { |
|
349 |
this.classPathLoader = null; |
|
350 |
} |
|
351 |
||
352 |
// print version info if asked. |
|
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
353 |
if (env._version) { |
16147 | 354 |
getErr().println("nashorn " + Version.version()); |
355 |
} |
|
356 |
||
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
357 |
if (env._fullversion) { |
16147 | 358 |
getErr().println("nashorn full version " + Version.fullVersion()); |
359 |
} |
|
360 |
} |
|
361 |
||
362 |
/** |
|
363 |
* Get the error manager for this context |
|
364 |
* @return error manger |
|
365 |
*/ |
|
16185 | 366 |
public ErrorManager getErrorManager() { |
16147 | 367 |
return errors; |
368 |
} |
|
369 |
||
370 |
/** |
|
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
371 |
* Get the script environment for this context |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
372 |
* @return script environment |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
373 |
*/ |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
374 |
public ScriptEnvironment getEnv() { |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
375 |
return env; |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
376 |
} |
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
377 |
|
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
378 |
/** |
16147 | 379 |
* Get the output stream for this context |
380 |
* @return output print writer |
|
381 |
*/ |
|
382 |
public PrintWriter getOut() { |
|
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
383 |
return env.getOut(); |
16147 | 384 |
} |
385 |
||
386 |
/** |
|
387 |
* Get the error stream for this context |
|
388 |
* @return error print writer |
|
389 |
*/ |
|
390 |
public PrintWriter getErr() { |
|
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
391 |
return env.getErr(); |
16147 | 392 |
} |
393 |
||
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16196
diff
changeset
|
394 |
/** |
16188 | 395 |
* Get the PropertyMap of the current global scope |
396 |
* @return the property map of the current global scope |
|
397 |
*/ |
|
16201
889ddb179cdf
8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents:
16196
diff
changeset
|
398 |
public static PropertyMap getGlobalMap() { |
16188 | 399 |
return Context.getGlobalTrusted().getMap(); |
400 |
} |
|
401 |
||
16147 | 402 |
/** |
403 |
* Compile a top level script. |
|
404 |
* |
|
405 |
* @param source the source |
|
406 |
* @param scope the scope |
|
407 |
* |
|
408 |
* @return top level function for script |
|
409 |
*/ |
|
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
410 |
public ScriptFunction compileScript(final Source source, final ScriptObject scope) { |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
411 |
return compileScript(source, scope, this.errors); |
16147 | 412 |
} |
413 |
||
414 |
/** |
|
415 |
* Entry point for {@code eval} |
|
416 |
* |
|
417 |
* @param initialScope The scope of this eval call |
|
418 |
* @param string Evaluated code as a String |
|
419 |
* @param callThis "this" to be passed to the evaluated code |
|
420 |
* @param location location of the eval call |
|
421 |
* @param strict is this {@code eval} call from a strict mode code? |
|
422 |
* |
|
423 |
* @return the return value of the {@code eval} |
|
424 |
*/ |
|
425 |
public Object eval(final ScriptObject initialScope, final String string, final Object callThis, final Object location, final boolean strict) { |
|
426 |
final String file = (location == UNDEFINED || location == null) ? "<eval>" : location.toString(); |
|
427 |
final Source source = new Source(file, string); |
|
428 |
final boolean directEval = location != UNDEFINED; // is this direct 'eval' call or indirectly invoked eval? |
|
16188 | 429 |
final ScriptObject global = Context.getGlobalTrusted(); |
16147 | 430 |
ScriptObject scope = initialScope; |
431 |
||
432 |
// ECMA section 10.1.1 point 2 says eval code is strict if it begins |
|
433 |
// with "use strict" directive or eval direct call itself is made |
|
434 |
// from from strict mode code. We are passed with caller's strict mode. |
|
435 |
boolean strictFlag = directEval && strict; |
|
436 |
||
437 |
Class<?> clazz = null; |
|
438 |
try { |
|
439 |
clazz = compile(source, new ThrowErrorManager(), strictFlag); |
|
440 |
} catch (final ParserException e) { |
|
441 |
e.throwAsEcmaException(global); |
|
442 |
return null; |
|
443 |
} |
|
444 |
||
445 |
if (!strictFlag) { |
|
446 |
// We need to get strict mode flag from compiled class. This is |
|
447 |
// because eval code may start with "use strict" directive. |
|
448 |
try { |
|
17233 | 449 |
strictFlag = clazz.getField(STRICT_MODE.symbolName()).getBoolean(null); |
16147 | 450 |
} catch (final NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { |
451 |
//ignored |
|
452 |
strictFlag = false; |
|
453 |
} |
|
454 |
} |
|
455 |
||
456 |
// In strict mode, eval does not instantiate variables and functions |
|
457 |
// in the caller's environment. A new environment is created! |
|
458 |
if (strictFlag) { |
|
459 |
// Create a new scope object |
|
460 |
final ScriptObject strictEvalScope = ((GlobalObject)global).newObject(); |
|
461 |
||
462 |
// bless it as a "scope" |
|
463 |
strictEvalScope.setIsScope(); |
|
464 |
||
465 |
// set given scope to be it's proto so that eval can still |
|
466 |
// access caller environment vars in the new environment. |
|
467 |
strictEvalScope.setProto(scope); |
|
468 |
scope = strictEvalScope; |
|
469 |
} |
|
470 |
||
24719 | 471 |
ScriptFunction func = getProgramFunction(clazz, scope); |
16147 | 472 |
Object evalThis; |
473 |
if (directEval) { |
|
474 |
evalThis = (callThis instanceof ScriptObject || strictFlag) ? callThis : global; |
|
475 |
} else { |
|
476 |
evalThis = global; |
|
477 |
} |
|
478 |
||
479 |
return ScriptRuntime.apply(func, evalThis); |
|
480 |
} |
|
481 |
||
17518
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17513
diff
changeset
|
482 |
private static Source loadInternal(final String srcStr, final String prefix, final String resourcePath) { |
17244 | 483 |
if (srcStr.startsWith(prefix)) { |
484 |
final String resource = resourcePath + srcStr.substring(prefix.length()); |
|
485 |
// NOTE: even sandbox scripts should be able to load scripts in nashorn: scheme |
|
486 |
// These scripts are always available and are loaded from nashorn.jar's resources. |
|
487 |
return AccessController.doPrivileged( |
|
488 |
new PrivilegedAction<Source>() { |
|
489 |
@Override |
|
490 |
public Source run() { |
|
491 |
try { |
|
492 |
final URL resURL = Context.class.getResource(resource); |
|
493 |
return (resURL != null)? new Source(srcStr, resURL) : null; |
|
494 |
} catch (final IOException exp) { |
|
495 |
return null; |
|
496 |
} |
|
497 |
} |
|
498 |
}); |
|
499 |
} |
|
500 |
||
501 |
return null; |
|
502 |
} |
|
503 |
||
16147 | 504 |
/** |
505 |
* Implementation of {@code load} Nashorn extension. Load a script file from a source |
|
506 |
* expression |
|
507 |
* |
|
508 |
* @param scope the scope |
|
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
509 |
* @param from source expression for script |
16147 | 510 |
* |
511 |
* @return return value for load call (undefined) |
|
512 |
* |
|
513 |
* @throws IOException if source cannot be found or loaded |
|
514 |
*/ |
|
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
515 |
public Object load(final ScriptObject scope, final Object from) throws IOException { |
17244 | 516 |
final Object src = (from instanceof ConsString)? from.toString() : from; |
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
517 |
Source source = null; |
16147 | 518 |
|
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
519 |
// load accepts a String (which could be a URL or a file name), a File, a URL |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
520 |
// or a ScriptObject that has "name" and "source" (string valued) properties. |
16147 | 521 |
if (src instanceof String) { |
16251
4a5d15b2f168
8008166: URL handling was broken on windows, causing "load" to malfunction
lagergren
parents:
16245
diff
changeset
|
522 |
final String srcStr = (String)src; |
20564
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
523 |
if (srcStr.startsWith(LOAD_CLASSPATH)) { |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
524 |
URL url = getResourceURL(srcStr.substring(LOAD_CLASSPATH.length())); |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
525 |
source = (url != null)? new Source(url.toString(), url) : null; |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
526 |
} else { |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
527 |
final File file = new File(srcStr); |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
528 |
if (srcStr.indexOf(':') != -1) { |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
529 |
if ((source = loadInternal(srcStr, LOAD_NASHORN, "resources/")) == null && |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
530 |
(source = loadInternal(srcStr, LOAD_FX, "resources/fx/")) == null) { |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
531 |
URL url; |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
532 |
try { |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
533 |
//check for malformed url. if malformed, it may still be a valid file |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
534 |
url = new URL(srcStr); |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
535 |
} catch (final MalformedURLException e) { |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
536 |
url = file.toURI().toURL(); |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
537 |
} |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
538 |
source = new Source(url.toString(), url); |
16254 | 539 |
} |
20564
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
540 |
} else if (file.isFile()) { |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
541 |
source = new Source(srcStr, file); |
16147 | 542 |
} |
543 |
} |
|
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
544 |
} else if (src instanceof File && ((File)src).isFile()) { |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
545 |
final File file = (File)src; |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
546 |
source = new Source(file.getName(), file); |
16147 | 547 |
} else if (src instanceof URL) { |
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
548 |
final URL url = (URL)src; |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
549 |
source = new Source(url.toString(), url); |
16147 | 550 |
} else if (src instanceof ScriptObject) { |
551 |
final ScriptObject sobj = (ScriptObject)src; |
|
552 |
if (sobj.has("script") && sobj.has("name")) { |
|
553 |
final String script = JSType.toString(sobj.get("script")); |
|
554 |
final String name = JSType.toString(sobj.get("name")); |
|
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
555 |
source = new Source(name, script); |
16147 | 556 |
} |
18334
47413e8d71b5
8016618: script mirror object access should be improved
sundar
parents:
18328
diff
changeset
|
557 |
} else if (src instanceof Map) { |
19097
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
19088
diff
changeset
|
558 |
final Map<?,?> map = (Map<?,?>)src; |
18334
47413e8d71b5
8016618: script mirror object access should be improved
sundar
parents:
18328
diff
changeset
|
559 |
if (map.containsKey("script") && map.containsKey("name")) { |
47413e8d71b5
8016618: script mirror object access should be improved
sundar
parents:
18328
diff
changeset
|
560 |
final String script = JSType.toString(map.get("script")); |
47413e8d71b5
8016618: script mirror object access should be improved
sundar
parents:
18328
diff
changeset
|
561 |
final String name = JSType.toString(map.get("name")); |
47413e8d71b5
8016618: script mirror object access should be improved
sundar
parents:
18328
diff
changeset
|
562 |
source = new Source(name, script); |
47413e8d71b5
8016618: script mirror object access should be improved
sundar
parents:
18328
diff
changeset
|
563 |
} |
16147 | 564 |
} |
565 |
||
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
566 |
if (source != null) { |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
567 |
return evaluateSource(source, scope, scope); |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
568 |
} |
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
569 |
|
16256
f2d9a0c49914
8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents:
16254
diff
changeset
|
570 |
throw typeError("cant.load.script", ScriptRuntime.safeToString(from)); |
16147 | 571 |
} |
572 |
||
573 |
/** |
|
17974
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
574 |
* Implementation of {@code loadWithNewGlobal} Nashorn extension. Load a script file from a source |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
575 |
* expression, after creating a new global scope. |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
576 |
* |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
577 |
* @param from source expression for script |
18321
b2ceadf211cb
8016239: loadWithNewGlobal should support user supplied arguments from the caller
sundar
parents:
17982
diff
changeset
|
578 |
* @param args (optional) arguments to be passed to the loaded script |
17974
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
579 |
* |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
580 |
* @return return value for load call (undefined) |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
581 |
* |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
582 |
* @throws IOException if source cannot be found or loaded |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
583 |
*/ |
18321
b2ceadf211cb
8016239: loadWithNewGlobal should support user supplied arguments from the caller
sundar
parents:
17982
diff
changeset
|
584 |
public Object loadWithNewGlobal(final Object from, final Object...args) throws IOException { |
17974
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
585 |
final ScriptObject oldGlobal = getGlobalTrusted(); |
17976
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
586 |
final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction<ScriptObject>() { |
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
587 |
@Override |
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
588 |
public ScriptObject run() { |
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
589 |
try { |
19459 | 590 |
return newGlobal(); |
17976
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
591 |
} catch (final RuntimeException e) { |
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
592 |
if (Context.DEBUG) { |
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
593 |
e.printStackTrace(); |
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
594 |
} |
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
595 |
throw e; |
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
596 |
} |
5615a31822a1
8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents:
17974
diff
changeset
|
597 |
} |
19459 | 598 |
}, CREATE_GLOBAL_ACC_CTXT); |
599 |
// initialize newly created Global instance |
|
600 |
initGlobal(newGlobal); |
|
17974
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
601 |
setGlobalTrusted(newGlobal); |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
602 |
|
18874
8ba96bd382d3
8020463: Input argument array wrapping in loadWithNewGlobal is wrong
sundar
parents:
18865
diff
changeset
|
603 |
final Object[] wrapped = args == null? ScriptRuntime.EMPTY_ARRAY : ScriptObjectMirror.wrapArray(args, oldGlobal); |
19884
1bacbaa1bfc7
8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents:
19630
diff
changeset
|
604 |
newGlobal.put("arguments", ((GlobalObject)newGlobal).wrapAsObject(wrapped), env._strict); |
18321
b2ceadf211cb
8016239: loadWithNewGlobal should support user supplied arguments from the caller
sundar
parents:
17982
diff
changeset
|
605 |
|
17974
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
606 |
try { |
18874
8ba96bd382d3
8020463: Input argument array wrapping in loadWithNewGlobal is wrong
sundar
parents:
18865
diff
changeset
|
607 |
// wrap objects from newGlobal's world as mirrors - but if result |
8ba96bd382d3
8020463: Input argument array wrapping in loadWithNewGlobal is wrong
sundar
parents:
18865
diff
changeset
|
608 |
// is from oldGlobal's world, unwrap it! |
8ba96bd382d3
8020463: Input argument array wrapping in loadWithNewGlobal is wrong
sundar
parents:
18865
diff
changeset
|
609 |
return ScriptObjectMirror.unwrap(ScriptObjectMirror.wrap(load(newGlobal, from), newGlobal), oldGlobal); |
17974
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
610 |
} finally { |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
611 |
setGlobalTrusted(oldGlobal); |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
612 |
} |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
613 |
} |
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
614 |
|
a2818f17324e
8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents:
17524
diff
changeset
|
615 |
/** |
16147 | 616 |
* Load or get a structure class. Structure class names are based on the number of parameter fields |
617 |
* and {@link AccessorProperty} fields in them. Structure classes are used to represent ScriptObjects |
|
618 |
* |
|
619 |
* @see ObjectClassGenerator |
|
620 |
* @see AccessorProperty |
|
621 |
* @see ScriptObject |
|
622 |
* |
|
16275 | 623 |
* @param fullName full name of class, e.g. jdk.nashorn.internal.objects.JO2P1 contains 2 fields and 1 parameter. |
16147 | 624 |
* |
16272 | 625 |
* @return the {@code Class<?>} for this structure |
16147 | 626 |
* |
627 |
* @throws ClassNotFoundException if structure class cannot be resolved |
|
628 |
*/ |
|
24719 | 629 |
@SuppressWarnings("unchecked") |
630 |
public static Class<? extends ScriptObject> forStructureClass(final String fullName) throws ClassNotFoundException { |
|
19895
965b12eb322e
8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents:
19884
diff
changeset
|
631 |
if (System.getSecurityManager() != null && !StructureLoader.isStructureClass(fullName)) { |
19097
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
19088
diff
changeset
|
632 |
throw new ClassNotFoundException(fullName); |
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
19088
diff
changeset
|
633 |
} |
24719 | 634 |
return (Class<? extends ScriptObject>)Class.forName(fullName, true, sharedLoader); |
16147 | 635 |
} |
636 |
||
637 |
/** |
|
20567 | 638 |
* Checks that the given Class can be accessed from no permissions context. |
18865
8844964e5fc5
8020325: static property does not work on accessible, public classes
sundar
parents:
18864
diff
changeset
|
639 |
* |
20567 | 640 |
* @param clazz Class object |
19088
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
641 |
* @throw SecurityException if not accessible |
18865
8844964e5fc5
8020325: static property does not work on accessible, public classes
sundar
parents:
18864
diff
changeset
|
642 |
*/ |
20928
3ff39d5c8c08
8026137: Fix Issues with Binary Evaluation Order
lagergren
parents:
20567
diff
changeset
|
643 |
public static void checkPackageAccess(final Class<?> clazz) { |
20567 | 644 |
final SecurityManager sm = System.getSecurityManager(); |
645 |
if (sm != null) { |
|
20928
3ff39d5c8c08
8026137: Fix Issues with Binary Evaluation Order
lagergren
parents:
20567
diff
changeset
|
646 |
Class<?> bottomClazz = clazz; |
3ff39d5c8c08
8026137: Fix Issues with Binary Evaluation Order
lagergren
parents:
20567
diff
changeset
|
647 |
while (bottomClazz.isArray()) { |
20567 | 648 |
bottomClazz = bottomClazz.getComponentType(); |
18865
8844964e5fc5
8020325: static property does not work on accessible, public classes
sundar
parents:
18864
diff
changeset
|
649 |
} |
20567 | 650 |
checkPackageAccess(sm, bottomClazz.getName()); |
18865
8844964e5fc5
8020325: static property does not work on accessible, public classes
sundar
parents:
18864
diff
changeset
|
651 |
} |
8844964e5fc5
8020325: static property does not work on accessible, public classes
sundar
parents:
18864
diff
changeset
|
652 |
} |
8844964e5fc5
8020325: static property does not work on accessible, public classes
sundar
parents:
18864
diff
changeset
|
653 |
|
8844964e5fc5
8020325: static property does not work on accessible, public classes
sundar
parents:
18864
diff
changeset
|
654 |
/** |
22669 | 655 |
* Checks that the given package name can be accessed from no permissions context. |
656 |
* |
|
657 |
* @param pkgName package name |
|
658 |
* @throw SecurityException if not accessible |
|
659 |
*/ |
|
660 |
public static void checkPackageAccess(final String pkgName) { |
|
661 |
final SecurityManager sm = System.getSecurityManager(); |
|
662 |
if (sm != null) { |
|
663 |
checkPackageAccess(sm, pkgName.endsWith(".")? pkgName : pkgName + "."); |
|
664 |
} |
|
665 |
} |
|
666 |
||
667 |
/** |
|
19097
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
19088
diff
changeset
|
668 |
* Checks that the given package can be accessed from no permissions context. |
19088
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
669 |
* |
20567 | 670 |
* @param sm current security manager instance |
19088
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
671 |
* @param fullName fully qualified package name |
20567 | 672 |
* @throw SecurityException if not accessible |
673 |
*/ |
|
674 |
private static void checkPackageAccess(final SecurityManager sm, final String fullName) { |
|
675 |
sm.getClass(); // null check |
|
676 |
final int index = fullName.lastIndexOf('.'); |
|
677 |
if (index != -1) { |
|
678 |
final String pkgName = fullName.substring(0, index); |
|
679 |
AccessController.doPrivileged(new PrivilegedAction<Void>() { |
|
680 |
@Override |
|
681 |
public Void run() { |
|
682 |
sm.checkPackageAccess(pkgName); |
|
683 |
return null; |
|
684 |
} |
|
685 |
}, NO_PERMISSIONS_ACC_CTXT); |
|
686 |
} |
|
687 |
} |
|
688 |
||
689 |
/** |
|
690 |
* Checks that the given Class can be accessed from no permissions context. |
|
691 |
* |
|
692 |
* @param clazz Class object |
|
19088
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
693 |
* @return true if package is accessible, false otherwise |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
694 |
*/ |
20928
3ff39d5c8c08
8026137: Fix Issues with Binary Evaluation Order
lagergren
parents:
20567
diff
changeset
|
695 |
private static boolean isAccessiblePackage(final Class<?> clazz) { |
19088
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
696 |
try { |
20567 | 697 |
checkPackageAccess(clazz); |
19088
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
698 |
return true; |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
699 |
} catch (final SecurityException se) { |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
700 |
return false; |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
701 |
} |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
702 |
} |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
703 |
|
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
704 |
/** |
19097
f544a2ea40ef
8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents:
19088
diff
changeset
|
705 |
* Checks that the given Class is public and it can be accessed from no permissions context. |
19088
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
706 |
* |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
707 |
* @param clazz Class object to check |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
708 |
* @return true if Class is accessible, false otherwise |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
709 |
*/ |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
710 |
public static boolean isAccessibleClass(final Class<?> clazz) { |
20567 | 711 |
return Modifier.isPublic(clazz.getModifiers()) && Context.isAccessiblePackage(clazz); |
19088
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
712 |
} |
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
713 |
|
153f268bfa72
8021122: Not all callables are handled for toString and other function valued properties
sundar
parents:
19085
diff
changeset
|
714 |
/** |
16147 | 715 |
* Lookup a Java class. This is used for JSR-223 stuff linking in from |
17524
703643aeb0d6
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents:
17519
diff
changeset
|
716 |
* {@code jdk.nashorn.internal.objects.NativeJava} and {@code jdk.nashorn.internal.runtime.NativeJavaPackage} |
16147 | 717 |
* |
718 |
* @param fullName full name of class to load |
|
719 |
* |
|
16272 | 720 |
* @return the {@code Class<?>} for the name |
16147 | 721 |
* |
722 |
* @throws ClassNotFoundException if class cannot be resolved |
|
723 |
*/ |
|
724 |
public Class<?> findClass(final String fullName) throws ClassNotFoundException { |
|
20567 | 725 |
if (fullName.indexOf('[') != -1 || fullName.indexOf('/') != -1) { |
726 |
// don't allow array class names or internal names. |
|
727 |
throw new ClassNotFoundException(fullName); |
|
728 |
} |
|
729 |
||
16147 | 730 |
// check package access as soon as possible! |
20567 | 731 |
final SecurityManager sm = System.getSecurityManager(); |
732 |
if (sm != null) { |
|
733 |
checkPackageAccess(sm, fullName); |
|
734 |
} |
|
16147 | 735 |
|
16185 | 736 |
// try the script -classpath loader, if that is set |
16147 | 737 |
if (classPathLoader != null) { |
738 |
try { |
|
739 |
return Class.forName(fullName, true, classPathLoader); |
|
16185 | 740 |
} catch (final ClassNotFoundException ignored) { |
16147 | 741 |
// ignore, continue search |
742 |
} |
|
743 |
} |
|
744 |
||
16185 | 745 |
// Try finding using the "app" loader. |
746 |
return Class.forName(fullName, true, appLoader); |
|
16147 | 747 |
} |
748 |
||
749 |
/** |
|
750 |
* Hook to print stack trace for a {@link Throwable} that occurred during |
|
751 |
* execution |
|
752 |
* |
|
753 |
* @param t throwable for which to dump stack |
|
754 |
*/ |
|
755 |
public static void printStackTrace(final Throwable t) { |
|
756 |
if (Context.DEBUG) { |
|
16185 | 757 |
t.printStackTrace(Context.getCurrentErr()); |
16147 | 758 |
} |
759 |
} |
|
760 |
||
761 |
/** |
|
762 |
* Verify generated bytecode before emission. This is called back from the |
|
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
763 |
* {@link ObjectClassGenerator} or the {@link Compiler}. If the "--verify-code" parameter |
16147 | 764 |
* hasn't been given, this is a nop |
765 |
* |
|
766 |
* Note that verification may load classes -- we don't want to do that unless |
|
767 |
* user specified verify option. We check it here even though caller |
|
768 |
* may have already checked that flag |
|
769 |
* |
|
770 |
* @param bytecode bytecode to verify |
|
771 |
*/ |
|
772 |
public void verify(final byte[] bytecode) { |
|
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
773 |
if (env._verify_code) { |
16147 | 774 |
// No verification when security manager is around as verifier |
775 |
// may load further classes - which should be avoided. |
|
776 |
if (System.getSecurityManager() == null) { |
|
19098
473dfe87bb7b
8021294: --verify-code option results in AnalyzerException
sundar
parents:
19097
diff
changeset
|
777 |
CheckClassAdapter.verify(new ClassReader(bytecode), sharedLoader, false, new PrintWriter(System.err, true)); |
16147 | 778 |
} |
779 |
} |
|
780 |
} |
|
781 |
||
782 |
/** |
|
16211 | 783 |
* Create and initialize a new global scope object. |
784 |
* |
|
785 |
* @return the initialized global scope object. |
|
786 |
*/ |
|
787 |
public ScriptObject createGlobal() { |
|
788 |
return initGlobal(newGlobal()); |
|
789 |
} |
|
790 |
||
791 |
/** |
|
792 |
* Create a new uninitialized global scope object |
|
16147 | 793 |
* @return the global script object |
794 |
*/ |
|
16211 | 795 |
public ScriptObject newGlobal() { |
19085
066c9e5afd79
8020731: Revisit checkPermission calls in Context class
sundar
parents:
18874
diff
changeset
|
796 |
return new Global(this); |
16211 | 797 |
} |
798 |
||
799 |
/** |
|
800 |
* Initialize given global scope object. |
|
801 |
* |
|
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
802 |
* @param global the global |
16211 | 803 |
* @return the initialized global scope object. |
804 |
*/ |
|
805 |
public ScriptObject initGlobal(final ScriptObject global) { |
|
24719 | 806 |
if (!(global instanceof GlobalObject)) { |
16211 | 807 |
throw new IllegalArgumentException("not a global object!"); |
808 |
} |
|
809 |
||
16147 | 810 |
// Need only minimal global object, if we are just compiling. |
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
811 |
if (!env._compile_only) { |
16188 | 812 |
final ScriptObject oldGlobal = Context.getGlobalTrusted(); |
16185 | 813 |
try { |
16188 | 814 |
Context.setGlobalTrusted(global); |
16185 | 815 |
// initialize global scope with builtin global objects |
816 |
((GlobalObject)global).initBuiltinObjects(); |
|
817 |
} finally { |
|
16188 | 818 |
Context.setGlobalTrusted(oldGlobal); |
16185 | 819 |
} |
16147 | 820 |
} |
821 |
||
822 |
return global; |
|
823 |
} |
|
824 |
||
825 |
/** |
|
16188 | 826 |
* Trusted variants - package-private |
827 |
*/ |
|
828 |
||
829 |
/** |
|
830 |
* Return the current global scope |
|
831 |
* @return current global scope |
|
832 |
*/ |
|
833 |
static ScriptObject getGlobalTrusted() { |
|
834 |
return currentGlobal.get(); |
|
835 |
} |
|
836 |
||
837 |
/** |
|
838 |
* Set the current global scope |
|
839 |
*/ |
|
840 |
static void setGlobalTrusted(ScriptObject global) { |
|
841 |
currentGlobal.set(global); |
|
842 |
} |
|
843 |
||
844 |
/** |
|
845 |
* Return the current global's context |
|
846 |
* @return current global's context |
|
16185 | 847 |
*/ |
848 |
static Context getContextTrusted() { |
|
16188 | 849 |
return Context.getGlobalTrusted().getContext(); |
16185 | 850 |
} |
851 |
||
852 |
/** |
|
16147 | 853 |
* Try to infer Context instance from the Class. If we cannot, |
854 |
* then get it from the thread local variable. |
|
855 |
* |
|
856 |
* @param clazz the class |
|
857 |
* @return context |
|
858 |
*/ |
|
859 |
static Context fromClass(final Class<?> clazz) { |
|
860 |
final ClassLoader loader = clazz.getClassLoader(); |
|
861 |
||
19895
965b12eb322e
8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents:
19884
diff
changeset
|
862 |
if (loader instanceof ScriptLoader) { |
965b12eb322e
8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents:
19884
diff
changeset
|
863 |
return ((ScriptLoader)loader).getContext(); |
16147 | 864 |
} |
865 |
||
19895
965b12eb322e
8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents:
19884
diff
changeset
|
866 |
return Context.getContextTrusted(); |
16147 | 867 |
} |
868 |
||
20928
3ff39d5c8c08
8026137: Fix Issues with Binary Evaluation Order
lagergren
parents:
20567
diff
changeset
|
869 |
private URL getResourceURL(final String resName) { |
20564
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
870 |
// try the classPathLoader if we have and then |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
871 |
// try the appLoader if non-null. |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
872 |
if (classPathLoader != null) { |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
873 |
return classPathLoader.getResource(resName); |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
874 |
} else if (appLoader != null) { |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
875 |
return appLoader.getResource(resName); |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
876 |
} |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
877 |
|
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
878 |
return null; |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
879 |
} |
f353da961684
8025629: load function should support a way to load scripts from classpath
sundar
parents:
19895
diff
changeset
|
880 |
|
16147 | 881 |
private Object evaluateSource(final Source source, final ScriptObject scope, final ScriptObject thiz) { |
882 |
ScriptFunction script = null; |
|
883 |
||
884 |
try { |
|
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
885 |
script = compileScript(source, scope, new Context.ThrowErrorManager()); |
16147 | 886 |
} catch (final ParserException e) { |
16188 | 887 |
e.throwAsEcmaException(); |
16147 | 888 |
} |
889 |
||
890 |
return ScriptRuntime.apply(script, thiz); |
|
891 |
} |
|
892 |
||
24719 | 893 |
private static ScriptFunction getProgramFunction(final Class<?> script, final ScriptObject scope) { |
16147 | 894 |
if (script == null) { |
895 |
return null; |
|
896 |
} |
|
897 |
||
898 |
try { |
|
24719 | 899 |
return (ScriptFunction)script.getMethod(CREATE_PROGRAM_FUNCTION.symbolName(), ScriptObject.class).invoke(null, scope); |
900 |
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException |
|
901 |
| SecurityException e) { |
|
902 |
throw new RuntimeException("Failed to create a program function for " + script.getName(), e); |
|
16147 | 903 |
} |
904 |
} |
|
905 |
||
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
906 |
private ScriptFunction compileScript(final Source source, final ScriptObject scope, final ErrorManager errMan) { |
24719 | 907 |
return getProgramFunction(compile(source, errMan, this._strict), scope); |
16147 | 908 |
} |
909 |
||
16230
c38c724d82e7
8008103: Source object should maintain URL of the script source as a private field
sundar
parents:
16226
diff
changeset
|
910 |
private synchronized Class<?> compile(final Source source, final ErrorManager errMan, final boolean strict) { |
16147 | 911 |
// start with no errors, no warnings. |
912 |
errMan.reset(); |
|
913 |
||
914 |
GlobalObject global = null; |
|
915 |
Class<?> script; |
|
916 |
||
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
917 |
if (env._class_cache_size > 0) { |
16188 | 918 |
global = (GlobalObject)Context.getGlobalTrusted(); |
16147 | 919 |
script = global.findCachedClass(source); |
920 |
if (script != null) { |
|
17233 | 921 |
Compiler.LOG.fine("Code cache hit for ", source, " avoiding recompile."); |
16147 | 922 |
return script; |
923 |
} |
|
924 |
} |
|
925 |
||
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
926 |
final FunctionNode functionNode = new Parser(env, source, errMan, strict).parse(); |
17233 | 927 |
if (errors.hasErrors()) { |
16147 | 928 |
return null; |
929 |
} |
|
930 |
||
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
931 |
if (env._print_ast) { |
16240
e1468b33e201
8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
16233
diff
changeset
|
932 |
getErr().println(new ASTWriter(functionNode)); |
e1468b33e201
8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
16233
diff
changeset
|
933 |
} |
e1468b33e201
8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents:
16233
diff
changeset
|
934 |
|
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
935 |
if (env._print_parse) { |
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
936 |
getErr().println(new PrintVisitor(functionNode)); |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
937 |
} |
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
938 |
|
17233 | 939 |
if (env._parse_only) { |
940 |
return null; |
|
941 |
} |
|
942 |
||
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
943 |
final URL url = source.getURL(); |
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
944 |
final ScriptLoader loader = env._loader_per_compile ? createNewLoader() : scriptLoader; |
23076
8660ebaaa2f2
8033924: Default permissions are not given for eval code
sundar
parents:
22669
diff
changeset
|
945 |
final CodeSource cs = new CodeSource(url, (CodeSigner[])null); |
16262
75513555e603
8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents:
16256
diff
changeset
|
946 |
final CodeInstaller<ScriptEnvironment> installer = new ContextCodeInstaller(this, loader, cs); |
16147 | 947 |
|
24719 | 948 |
final CompilationPhases phases = CompilationEnvironment.CompilationPhases.EAGER; |
949 |
final Compiler compiler = new Compiler( |
|
950 |
new CompilationEnvironment( |
|
951 |
phases. |
|
952 |
makeOptimistic( |
|
953 |
ScriptEnvironment.globalOptimistic()), |
|
954 |
strict), |
|
955 |
installer); |
|
16233
95d3e01c04c3
8008199: Lazy compilation and trampoline implementation
lagergren
parents:
16230
diff
changeset
|
956 |
|
24719 | 957 |
final FunctionNode newFunctionNode = compiler.compile(CompilerConstants.DEFAULT_SCRIPT_NAME.symbolName(), functionNode); |
17518
2225a4f929c0
8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents:
17513
diff
changeset
|
958 |
script = compiler.install(newFunctionNode); |
16147 | 959 |
|
960 |
if (global != null) { |
|
961 |
global.cacheClass(source, script); |
|
962 |
} |
|
963 |
||
964 |
return script; |
|
965 |
} |
|
966 |
||
967 |
private ScriptLoader createNewLoader() { |
|
968 |
return AccessController.doPrivileged( |
|
969 |
new PrivilegedAction<ScriptLoader>() { |
|
970 |
@Override |
|
971 |
public ScriptLoader run() { |
|
19895
965b12eb322e
8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents:
19884
diff
changeset
|
972 |
return new ScriptLoader(appLoader, Context.this); |
16147 | 973 |
} |
19459 | 974 |
}, CREATE_LOADER_ACC_CTXT); |
16147 | 975 |
} |
976 |
||
20929
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
20928
diff
changeset
|
977 |
private long getUniqueEvalId() { |
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
20928
diff
changeset
|
978 |
return uniqueEvalId.getAndIncrement(); |
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
20928
diff
changeset
|
979 |
} |
f2bd18181940
8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents:
20928
diff
changeset
|
980 |
|
18864
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
981 |
private long getUniqueScriptId() { |
c701b823ed9e
8020276: interface checks in Invocable.getInterface implementation
sundar
parents:
18862
diff
changeset
|
982 |
return uniqueScriptId.getAndIncrement(); |
18862
8b6a01b38cb8
8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents:
18860
diff
changeset
|
983 |
} |
16147 | 984 |
} |