Thu, 24 May 2018 16:39:31 +0800
Merge
1 /*
2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
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 */
26 package jdk.nashorn.internal.runtime;
28 import java.io.PrintWriter;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Locale;
32 import java.util.Map;
33 import java.util.StringTokenizer;
34 import java.util.TimeZone;
35 import java.util.logging.Level;
36 import jdk.nashorn.internal.codegen.Namespace;
37 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
38 import jdk.nashorn.internal.runtime.options.KeyValueOption;
39 import jdk.nashorn.internal.runtime.options.LoggingOption;
40 import jdk.nashorn.internal.runtime.options.LoggingOption.LoggerInfo;
41 import jdk.nashorn.internal.runtime.options.Option;
42 import jdk.nashorn.internal.runtime.options.Options;
44 /**
45 * Script environment consists of command line options, arguments, script files
46 * and output and error writers, top level Namespace etc.
47 */
48 public final class ScriptEnvironment {
49 // Primarily intended to be used in test environments so that eager compilation tests work without an
50 // error when tested with optimistic compilation.
51 private static final boolean ALLOW_EAGER_COMPILATION_SILENT_OVERRIDE = Options.getBooleanProperty(
52 "nashorn.options.allowEagerCompilationSilentOverride", false);
54 /** Output writer for this environment */
55 private final PrintWriter out;
57 /** Error writer for this environment */
58 private final PrintWriter err;
60 /** Top level namespace. */
61 private final Namespace namespace;
63 /** Current Options object. */
64 private final Options options;
66 /** Size of the per-global Class cache size */
67 public final int _class_cache_size;
69 /** Only compile script, do not run it or generate other ScriptObjects */
70 public final boolean _compile_only;
72 /** Accept "const" keyword and treat it as variable. Interim feature */
73 public final boolean _const_as_var;
75 /** Accumulated callsite flags that will be used when bootstrapping script callsites */
76 public final int _callsite_flags;
78 /** Generate line number table in class files */
79 public final boolean _debug_lines;
81 /** Directory in which source files and generated class files are dumped */
82 public final String _dest_dir;
84 /** Display stack trace upon error, default is false */
85 public final boolean _dump_on_error;
87 /** Invalid lvalue expressions should be reported as early errors */
88 public final boolean _early_lvalue_error;
90 /** Empty statements should be preserved in the AST */
91 public final boolean _empty_statements;
93 /** Show full Nashorn version */
94 public final boolean _fullversion;
96 /** Launch using as fx application */
97 public final boolean _fx;
99 /** Use single Global instance per jsr223 engine instance. */
100 public final boolean _global_per_engine;
102 /** Enable experimental ECMAScript 6 features. */
103 public final boolean _es6;
105 /** Argument passed to compile only if optimistic compilation should take place */
106 public static final String COMPILE_ONLY_OPTIMISTIC_ARG = "optimistic";
108 /**
109 * Behavior when encountering a function declaration in a lexical context where only statements are acceptable
110 * (function declarations are source elements, but not statements).
111 */
112 public enum FunctionStatementBehavior {
113 /**
114 * Accept the function declaration silently and treat it as if it were a function expression assigned to a local
115 * variable.
116 */
117 ACCEPT,
118 /**
119 * Log a parser warning, but accept the function declaration and treat it as if it were a function expression
120 * assigned to a local variable.
121 */
122 WARNING,
123 /**
124 * Raise a {@code SyntaxError}.
125 */
126 ERROR
127 }
129 /**
130 * Behavior when encountering a function declaration in a lexical context where only statements are acceptable
131 * (function declarations are source elements, but not statements).
132 */
133 public final FunctionStatementBehavior _function_statement;
135 /** Should lazy compilation take place */
136 public final boolean _lazy_compilation;
138 /** Should optimistic types be used */
139 public final boolean _optimistic_types;
141 /** Create a new class loaded for each compilation */
142 public final boolean _loader_per_compile;
144 /** Do not support Java support extensions. */
145 public final boolean _no_java;
147 /** Do not support non-standard syntax extensions. */
148 public final boolean _no_syntax_extensions;
150 /** Do not support typed arrays. */
151 public final boolean _no_typed_arrays;
153 /** Only parse the source code, do not compile */
154 public final boolean _parse_only;
156 /** Enable disk cache for compiled scripts */
157 public final boolean _persistent_cache;
159 /** Print the AST before lowering */
160 public final boolean _print_ast;
162 /** Print the AST after lowering */
163 public final boolean _print_lower_ast;
165 /** Print resulting bytecode for script */
166 public final boolean _print_code;
168 /** Directory (optional) to print files to */
169 public final String _print_code_dir;
171 /** List of functions to write to the print code dir, optional */
172 public final String _print_code_func;
174 /** Print memory usage for IR after each phase */
175 public final boolean _print_mem_usage;
177 /** Print function will no print newline characters */
178 public final boolean _print_no_newline;
180 /** Print AST in more human readable form */
181 public final boolean _print_parse;
183 /** Print AST in more human readable form after Lowering */
184 public final boolean _print_lower_parse;
186 /** print symbols and their contents for the script */
187 public final boolean _print_symbols;
189 /** is this environment in scripting mode? */
190 public final boolean _scripting;
192 /** is this environment in strict mode? */
193 public final boolean _strict;
195 /** print version info of Nashorn */
196 public final boolean _version;
198 /** should code verification be done of generated bytecode */
199 public final boolean _verify_code;
201 /** time zone for this environment */
202 public final TimeZone _timezone;
204 /** Local for error messages */
205 public final Locale _locale;
207 /** Logging */
208 public final Map<String, LoggerInfo> _loggers;
210 /** Timing */
211 public final Timing _timing;
213 /**
214 * Constructor
215 *
216 * @param options a Options object
217 * @param out output print writer
218 * @param err error print writer
219 */
220 @SuppressWarnings("unused")
221 public ScriptEnvironment(final Options options, final PrintWriter out, final PrintWriter err) {
222 this.out = out;
223 this.err = err;
224 this.namespace = new Namespace();
225 this.options = options;
227 _class_cache_size = options.getInteger("class.cache.size");
228 _compile_only = options.getBoolean("compile.only");
229 _const_as_var = options.getBoolean("const.as.var");
230 _debug_lines = options.getBoolean("debug.lines");
231 _dest_dir = options.getString("d");
232 _dump_on_error = options.getBoolean("doe");
233 _early_lvalue_error = options.getBoolean("early.lvalue.error");
234 _empty_statements = options.getBoolean("empty.statements");
235 _fullversion = options.getBoolean("fullversion");
236 if (options.getBoolean("function.statement.error")) {
237 _function_statement = FunctionStatementBehavior.ERROR;
238 } else if (options.getBoolean("function.statement.warning")) {
239 _function_statement = FunctionStatementBehavior.WARNING;
240 } else {
241 _function_statement = FunctionStatementBehavior.ACCEPT;
242 }
243 _fx = options.getBoolean("fx");
244 _global_per_engine = options.getBoolean("global.per.engine");
245 _optimistic_types = options.getBoolean("optimistic.types");
246 final boolean lazy_compilation = options.getBoolean("lazy.compilation");
247 if (!lazy_compilation && _optimistic_types) {
248 if (!ALLOW_EAGER_COMPILATION_SILENT_OVERRIDE) {
249 throw new IllegalStateException(
250 ECMAErrors.getMessage(
251 "config.error.eagerCompilationConflictsWithOptimisticTypes",
252 options.getOptionTemplateByKey("lazy.compilation").getName(),
253 options.getOptionTemplateByKey("optimistic.types").getName()));
254 }
255 _lazy_compilation = true;
256 } else {
257 _lazy_compilation = lazy_compilation;
258 }
259 _loader_per_compile = options.getBoolean("loader.per.compile");
260 _no_java = options.getBoolean("no.java");
261 _no_syntax_extensions = options.getBoolean("no.syntax.extensions");
262 _no_typed_arrays = options.getBoolean("no.typed.arrays");
263 _parse_only = options.getBoolean("parse.only");
264 _persistent_cache = options.getBoolean("persistent.code.cache");
265 _print_ast = options.getBoolean("print.ast");
266 _print_lower_ast = options.getBoolean("print.lower.ast");
267 _print_code = options.getString("print.code") != null;
268 _print_mem_usage = options.getBoolean("print.mem.usage");
269 _print_no_newline = options.getBoolean("print.no.newline");
270 _print_parse = options.getBoolean("print.parse");
271 _print_lower_parse = options.getBoolean("print.lower.parse");
272 _print_symbols = options.getBoolean("print.symbols");
273 _scripting = options.getBoolean("scripting");
274 _strict = options.getBoolean("strict");
275 _version = options.getBoolean("version");
276 _verify_code = options.getBoolean("verify.code");
278 final String language = options.getString("language");
279 if (language == null || language.equals("es5")) {
280 _es6 = false;
281 } else if (language.equals("es6")) {
282 _es6 = true;
283 } else {
284 throw new RuntimeException("Unsupported language: " + language);
285 }
287 String dir = null;
288 String func = null;
289 final String pc = options.getString("print.code");
290 if (pc != null) {
291 final StringTokenizer st = new StringTokenizer(pc, ",");
292 while (st.hasMoreTokens()) {
293 final StringTokenizer st2 = new StringTokenizer(st.nextToken(), ":");
294 while (st2.hasMoreTokens()) {
295 final String cmd = st2.nextToken();
296 if ("dir".equals(cmd)) {
297 dir = st2.nextToken();
298 } else if ("function".equals(cmd)) {
299 func = st2.nextToken();
300 }
301 }
302 }
303 }
304 _print_code_dir = dir;
305 _print_code_func = func;
307 int callSiteFlags = 0;
308 if (options.getBoolean("profile.callsites")) {
309 callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_PROFILE;
310 }
312 if (options.get("trace.callsites") instanceof KeyValueOption) {
313 callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE;
314 final KeyValueOption kv = (KeyValueOption)options.get("trace.callsites");
315 if (kv.hasValue("miss")) {
316 callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_MISSES;
317 }
318 if (kv.hasValue("enterexit") || (callSiteFlags & NashornCallSiteDescriptor.CALLSITE_TRACE_MISSES) == 0) {
319 callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_ENTEREXIT;
320 }
321 if (kv.hasValue("objects")) {
322 callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_VALUES;
323 }
324 }
325 this._callsite_flags = callSiteFlags;
327 final Option<?> timezoneOption = options.get("timezone");
328 if (timezoneOption != null) {
329 this._timezone = (TimeZone)timezoneOption.getValue();
330 } else {
331 this._timezone = TimeZone.getDefault();
332 }
334 final Option<?> localeOption = options.get("locale");
335 if (localeOption != null) {
336 this._locale = (Locale)localeOption.getValue();
337 } else {
338 this._locale = Locale.getDefault();
339 }
341 final LoggingOption loggingOption = (LoggingOption)options.get("log");
342 this._loggers = loggingOption == null ? new HashMap<String, LoggerInfo>() : loggingOption.getLoggers();
344 final LoggerInfo timeLoggerInfo = _loggers.get(Timing.getLoggerName());
345 this._timing = new Timing(timeLoggerInfo != null && timeLoggerInfo.getLevel() != Level.OFF);
346 }
348 /**
349 * Get the output stream for this environment
350 * @return output print writer
351 */
352 public PrintWriter getOut() {
353 return out;
354 }
356 /**
357 * Get the error stream for this environment
358 * @return error print writer
359 */
360 public PrintWriter getErr() {
361 return err;
362 }
364 /**
365 * Get the namespace for this environment
366 * @return namespace
367 */
368 public Namespace getNamespace() {
369 return namespace;
370 }
372 /**
373 * Return the JavaScript files passed to the program
374 *
375 * @return a list of files
376 */
377 public List<String> getFiles() {
378 return options.getFiles();
379 }
381 /**
382 * Return the user arguments to the program, i.e. those trailing "--" after
383 * the filename
384 *
385 * @return a list of user arguments
386 */
387 public List<String> getArguments() {
388 return options.getArguments();
389 }
391 /**
392 * Check if there is a logger registered for a particular name: typically
393 * the "name" attribute of a Loggable annotation on a class
394 *
395 * @param name logger name
396 * @return true, if a logger exists for that name, false otherwise
397 */
398 public boolean hasLogger(final String name) {
399 return _loggers.get(name) != null;
400 }
402 /**
403 * Check if compilation/runtime timings are enabled
404 * @return true if enabled
405 */
406 public boolean isTimingEnabled() {
407 return _timing != null ? _timing.isEnabled() : false;
408 }
410 }