ScriptEnvironment.java revision 1387:864aaf4e6441
161981Sbrian/* 261981Sbrian * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 361981Sbrian * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 461981Sbrian * 561981Sbrian * This code is free software; you can redistribute it and/or modify it 661981Sbrian * under the terms of the GNU General Public License version 2 only, as 761981Sbrian * published by the Free Software Foundation. Oracle designates this 861981Sbrian * particular file as subject to the "Classpath" exception as provided 961981Sbrian * by Oracle in the LICENSE file that accompanied this code. 1061981Sbrian * 1161981Sbrian * This code is distributed in the hope that it will be useful, but WITHOUT 1261981Sbrian * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1361981Sbrian * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1461981Sbrian * version 2 for more details (a copy is included in the LICENSE file that 1561981Sbrian * accompanied this code). 1661981Sbrian * 1761981Sbrian * You should have received a copy of the GNU General Public License version 1861981Sbrian * 2 along with this work; if not, write to the Free Software Foundation, 1961981Sbrian * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2061981Sbrian * 2161981Sbrian * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2261981Sbrian * or visit www.oracle.com if you need additional information or have any 2361981Sbrian * questions. 2461981Sbrian */ 2565843Sbrian 2665843Sbrianpackage jdk.nashorn.internal.runtime; 2765843Sbrian 2865843Sbrianimport java.io.PrintWriter; 2965843Sbrianimport java.util.HashMap; 3065843Sbrianimport java.util.List; 3165843Sbrianimport java.util.Locale; 3265843Sbrianimport java.util.Map; 3365843Sbrianimport java.util.StringTokenizer; 3465843Sbrianimport java.util.TimeZone; 3561981Sbrianimport java.util.logging.Level; 3661981Sbrianimport jdk.nashorn.internal.codegen.Namespace; 3761981Sbrianimport jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; 3861981Sbrianimport jdk.nashorn.internal.runtime.options.KeyValueOption; 3961981Sbrianimport jdk.nashorn.internal.runtime.options.LoggingOption; 4061981Sbrianimport jdk.nashorn.internal.runtime.options.LoggingOption.LoggerInfo; 4161981Sbrianimport jdk.nashorn.internal.runtime.options.Option; 4261981Sbrianimport jdk.nashorn.internal.runtime.options.Options; 4361981Sbrian 4461981Sbrian/** 4561981Sbrian * Script environment consists of command line options, arguments, script files 4661981Sbrian * and output and error writers, top level Namespace etc. 4761981Sbrian */ 4861981Sbrianpublic final class ScriptEnvironment { 4961981Sbrian // Primarily intended to be used in test environments so that eager compilation tests work without an 5061981Sbrian // error when tested with optimistic compilation. 5161981Sbrian private static final boolean ALLOW_EAGER_COMPILATION_SILENT_OVERRIDE = Options.getBooleanProperty( 5261981Sbrian "nashorn.options.allowEagerCompilationSilentOverride", false); 5361981Sbrian 5461981Sbrian /** Output writer for this environment */ 5561981Sbrian private final PrintWriter out; 5661981Sbrian 5761981Sbrian /** Error writer for this environment */ 5861981Sbrian private final PrintWriter err; 5961981Sbrian 6061981Sbrian /** Top level namespace. */ 6161981Sbrian private final Namespace namespace; 6261981Sbrian 63108959Swollman /** Current Options object. */ 64108959Swollman private final Options options; 6561981Sbrian 6661981Sbrian /** Size of the per-global Class cache size */ 6761981Sbrian public final int _class_cache_size; 6861981Sbrian 6961981Sbrian /** -classpath value. */ 7061981Sbrian public final String _classpath; 7161981Sbrian 7261981Sbrian /** Only compile script, do not run it or generate other ScriptObjects */ 7361981Sbrian public final boolean _compile_only; 7461981Sbrian 7561981Sbrian /** Accept "const" keyword and treat it as variable. Interim feature */ 7661981Sbrian public final boolean _const_as_var; 7762054Sbrian 7877496Sbrian /** Accumulated callsite flags that will be used when bootstrapping script callsites */ 7977492Sbrian public final int _callsite_flags; 8061981Sbrian 8161981Sbrian /** Generate line number table in class files */ 8261981Sbrian public final boolean _debug_lines; 8361981Sbrian 8461981Sbrian /** Directory in which source files and generated class files are dumped */ 8561981Sbrian public final String _dest_dir; 8662644Ssheldonh 8761981Sbrian /** Display stack trace upon error, default is false */ 88121620Sjesper public final boolean _dump_on_error; 89123498Sjesper 90121620Sjesper /** Invalid lvalue expressions should be reported as early errors */ 9161981Sbrian public final boolean _early_lvalue_error; 9261981Sbrian 9361981Sbrian /** Empty statements should be preserved in the AST */ 9461981Sbrian public final boolean _empty_statements; 9561981Sbrian 9661981Sbrian /** Show full Nashorn version */ 9761981Sbrian public final boolean _fullversion; 9861981Sbrian 9961981Sbrian /** Launch using as fx application */ 10061981Sbrian public final boolean _fx; 10194342Sgshapiro 10261981Sbrian /** Use single Global instance per jsr223 engine instance. */ 10361981Sbrian public final boolean _global_per_engine; 10461981Sbrian 10587514Scjc /** Enable experimental ECMAScript 6 features. */ 10661981Sbrian public final boolean _es6; 10761981Sbrian 10861981Sbrian /** Argument passed to compile only if optimistic compilation should take place */ 10962274Sbrian public static final String COMPILE_ONLY_OPTIMISTIC_ARG = "optimistic"; 11061981Sbrian 11175809Sdirk /** 11275809Sdirk * Behavior when encountering a function declaration in a lexical context where only statements are acceptable 11375809Sdirk * (function declarations are source elements, but not statements). 11475809Sdirk */ 11572677Speter public enum FunctionStatementBehavior { 11672677Speter /** 11794342Sgshapiro * Accept the function declaration silently and treat it as if it were a function expression assigned to a local 11872677Speter * variable. 11961981Sbrian */ 12061981Sbrian ACCEPT, 12161981Sbrian /** 12261981Sbrian * Log a parser warning, but accept the function declaration and treat it as if it were a function expression 12387514Scjc * assigned to a local variable. 12487514Scjc */ 125101607Sfanf WARNING, 12687514Scjc /** 12787514Scjc * Raise a {@code SyntaxError}. 12887514Scjc */ 12987514Scjc ERROR 13087514Scjc } 131135591Sjkoshy 13287514Scjc /** 13387514Scjc * Behavior when encountering a function declaration in a lexical context where only statements are acceptable 13487514Scjc * (function declarations are source elements, but not statements). 13587514Scjc */ 13687514Scjc public final FunctionStatementBehavior _function_statement; 13787514Scjc 13887514Scjc /** Should lazy compilation take place */ 13987514Scjc public final boolean _lazy_compilation; 14087514Scjc 14187514Scjc /** Should optimistic types be used */ 14287514Scjc public final boolean _optimistic_types; 14387514Scjc 14487514Scjc /** Create a new class loaded for each compilation */ 14587514Scjc public final boolean _loader_per_compile; 14687514Scjc 14787514Scjc /** Do not support Java support extensions. */ 14887514Scjc public final boolean _no_java; 14987514Scjc 150105937Sthomas /** Do not support non-standard syntax extensions. */ 151105937Sthomas public final boolean _no_syntax_extensions; 152105937Sthomas 153138061Smlaier /** Do not support typed arrays. */ 154138061Smlaier public final boolean _no_typed_arrays; 155138061Smlaier 15687514Scjc /** Only parse the source code, do not compile */ 15787514Scjc public final boolean _parse_only; 15887514Scjc 15987514Scjc /** Enable disk cache for compiled scripts */ 16087514Scjc public final boolean _persistent_cache; 16187514Scjc 162128473Sdarrenr /** Print the AST before lowering */ 163128473Sdarrenr public final boolean _print_ast; 164128473Sdarrenr 16587514Scjc /** Print the AST after lowering */ 16687514Scjc public final boolean _print_lower_ast; 16787514Scjc 16887514Scjc /** Print resulting bytecode for script */ 16987514Scjc public final boolean _print_code; 17087514Scjc 17187514Scjc /** Directory (optional) to print files to */ 17287514Scjc public final String _print_code_dir; 17387514Scjc 17487514Scjc /** List of functions to write to the print code dir, optional */ 17587514Scjc public final String _print_code_func; 17687514Scjc 17787514Scjc /** Print memory usage for IR after each phase */ 17861981Sbrian public final boolean _print_mem_usage; 17961981Sbrian 18065843Sbrian /** Print function will no print newline characters */ 18165843Sbrian public final boolean _print_no_newline; 18265843Sbrian 18365843Sbrian /** Print AST in more human readable form */ 18465843Sbrian public final boolean _print_parse; 18565843Sbrian 18665843Sbrian /** Print AST in more human readable form after Lowering */ 18765843Sbrian public final boolean _print_lower_parse; 18865843Sbrian 18965843Sbrian /** print symbols and their contents for the script */ 19061981Sbrian public final boolean _print_symbols; 19161981Sbrian 19261981Sbrian /** is this environment in scripting mode? */ 19361981Sbrian public final boolean _scripting; 19461981Sbrian 19561981Sbrian /** is this environment in strict mode? */ 19661981Sbrian public final boolean _strict; 19761981Sbrian 19861981Sbrian /** print version info of Nashorn */ 19961981Sbrian public final boolean _version; 20061981Sbrian 20161981Sbrian /** should code verification be done of generated bytecode */ 20261981Sbrian public final boolean _verify_code; 20361981Sbrian 20461981Sbrian /** time zone for this environment */ 20561981Sbrian public final TimeZone _timezone; 20661981Sbrian 20761981Sbrian /** Local for error messages */ 20862206Sbrian public final Locale _locale; 20962155Sbrian 210103948Sbrian /** Logging */ 211129424Sjoe public final Map<String, LoggerInfo> _loggers; 21262155Sbrian 21361981Sbrian /** Timing */ 21461981Sbrian public final Timing _timing; 21561981Sbrian 21661981Sbrian /** 21761981Sbrian * Constructor 21861981Sbrian * 21965843Sbrian * @param options a Options object 22065843Sbrian * @param out output print writer 22165843Sbrian * @param err error print writer 22265843Sbrian */ 22365843Sbrian @SuppressWarnings("unused") 22465843Sbrian public ScriptEnvironment(final Options options, final PrintWriter out, final PrintWriter err) { 22565843Sbrian this.out = out; 22665843Sbrian this.err = err; 22765843Sbrian this.namespace = new Namespace(); 22865843Sbrian this.options = options; 22961981Sbrian 23061981Sbrian _class_cache_size = options.getInteger("class.cache.size"); 23161981Sbrian _classpath = options.getString("classpath"); 23261981Sbrian _compile_only = options.getBoolean("compile.only"); 23361981Sbrian _const_as_var = options.getBoolean("const.as.var"); 23461981Sbrian _debug_lines = options.getBoolean("debug.lines"); 23561981Sbrian _dest_dir = options.getString("d"); 23661981Sbrian _dump_on_error = options.getBoolean("doe"); 23761981Sbrian _early_lvalue_error = options.getBoolean("early.lvalue.error"); 23861981Sbrian _empty_statements = options.getBoolean("empty.statements"); 23961981Sbrian _fullversion = options.getBoolean("fullversion"); 24061981Sbrian if (options.getBoolean("function.statement.error")) { 24161981Sbrian _function_statement = FunctionStatementBehavior.ERROR; 24261981Sbrian } else if (options.getBoolean("function.statement.warning")) { 24361981Sbrian _function_statement = FunctionStatementBehavior.WARNING; 24461981Sbrian } else { 24561981Sbrian _function_statement = FunctionStatementBehavior.ACCEPT; 24661981Sbrian } 24761981Sbrian _fx = options.getBoolean("fx"); 24861981Sbrian _global_per_engine = options.getBoolean("global.per.engine"); 24961981Sbrian _optimistic_types = options.getBoolean("optimistic.types"); 25061981Sbrian final boolean lazy_compilation = options.getBoolean("lazy.compilation"); 25161981Sbrian if (!lazy_compilation && _optimistic_types) { 25261981Sbrian if (!ALLOW_EAGER_COMPILATION_SILENT_OVERRIDE) { 25361981Sbrian throw new IllegalStateException( 25461981Sbrian ECMAErrors.getMessage( 25561981Sbrian "config.error.eagerCompilationConflictsWithOptimisticTypes", 256 options.getOptionTemplateByKey("lazy.compilation").getName(), 257 options.getOptionTemplateByKey("optimistic.types").getName())); 258 } 259 _lazy_compilation = true; 260 } else { 261 _lazy_compilation = lazy_compilation; 262 } 263 _loader_per_compile = options.getBoolean("loader.per.compile"); 264 _no_java = options.getBoolean("no.java"); 265 _no_syntax_extensions = options.getBoolean("no.syntax.extensions"); 266 _no_typed_arrays = options.getBoolean("no.typed.arrays"); 267 _parse_only = options.getBoolean("parse.only"); 268 _persistent_cache = options.getBoolean("persistent.code.cache"); 269 _print_ast = options.getBoolean("print.ast"); 270 _print_lower_ast = options.getBoolean("print.lower.ast"); 271 _print_code = options.getString("print.code") != null; 272 _print_mem_usage = options.getBoolean("print.mem.usage"); 273 _print_no_newline = options.getBoolean("print.no.newline"); 274 _print_parse = options.getBoolean("print.parse"); 275 _print_lower_parse = options.getBoolean("print.lower.parse"); 276 _print_symbols = options.getBoolean("print.symbols"); 277 _scripting = options.getBoolean("scripting"); 278 _strict = options.getBoolean("strict"); 279 _version = options.getBoolean("version"); 280 _verify_code = options.getBoolean("verify.code"); 281 282 final String language = options.getString("language"); 283 if (language == null || language.equals("es5")) { 284 _es6 = false; 285 } else if (language.equals("es6")) { 286 _es6 = true; 287 } else { 288 throw new RuntimeException("Unsupported language: " + language); 289 } 290 291 String dir = null; 292 String func = null; 293 final String pc = options.getString("print.code"); 294 if (pc != null) { 295 final StringTokenizer st = new StringTokenizer(pc, ","); 296 while (st.hasMoreTokens()) { 297 final StringTokenizer st2 = new StringTokenizer(st.nextToken(), ":"); 298 while (st2.hasMoreTokens()) { 299 final String cmd = st2.nextToken(); 300 if ("dir".equals(cmd)) { 301 dir = st2.nextToken(); 302 } else if ("function".equals(cmd)) { 303 func = st2.nextToken(); 304 } 305 } 306 } 307 } 308 _print_code_dir = dir; 309 _print_code_func = func; 310 311 int callSiteFlags = 0; 312 if (options.getBoolean("profile.callsites")) { 313 callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_PROFILE; 314 } 315 316 if (options.get("trace.callsites") instanceof KeyValueOption) { 317 callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE; 318 final KeyValueOption kv = (KeyValueOption)options.get("trace.callsites"); 319 if (kv.hasValue("miss")) { 320 callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_MISSES; 321 } 322 if (kv.hasValue("enterexit") || (callSiteFlags & NashornCallSiteDescriptor.CALLSITE_TRACE_MISSES) == 0) { 323 callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_ENTEREXIT; 324 } 325 if (kv.hasValue("objects")) { 326 callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_VALUES; 327 } 328 } 329 this._callsite_flags = callSiteFlags; 330 331 final Option<?> timezoneOption = options.get("timezone"); 332 if (timezoneOption != null) { 333 this._timezone = (TimeZone)timezoneOption.getValue(); 334 } else { 335 this._timezone = TimeZone.getDefault(); 336 } 337 338 final Option<?> localeOption = options.get("locale"); 339 if (localeOption != null) { 340 this._locale = (Locale)localeOption.getValue(); 341 } else { 342 this._locale = Locale.getDefault(); 343 } 344 345 final LoggingOption loggingOption = (LoggingOption)options.get("log"); 346 this._loggers = loggingOption == null ? new HashMap<String, LoggerInfo>() : loggingOption.getLoggers(); 347 348 final LoggerInfo timeLoggerInfo = _loggers.get(Timing.getLoggerName()); 349 this._timing = new Timing(timeLoggerInfo != null && timeLoggerInfo.getLevel() != Level.OFF); 350 } 351 352 /** 353 * Get the output stream for this environment 354 * @return output print writer 355 */ 356 public PrintWriter getOut() { 357 return out; 358 } 359 360 /** 361 * Get the error stream for this environment 362 * @return error print writer 363 */ 364 public PrintWriter getErr() { 365 return err; 366 } 367 368 /** 369 * Get the namespace for this environment 370 * @return namespace 371 */ 372 public Namespace getNamespace() { 373 return namespace; 374 } 375 376 /** 377 * Return the JavaScript files passed to the program 378 * 379 * @return a list of files 380 */ 381 public List<String> getFiles() { 382 return options.getFiles(); 383 } 384 385 /** 386 * Return the user arguments to the program, i.e. those trailing "--" after 387 * the filename 388 * 389 * @return a list of user arguments 390 */ 391 public List<String> getArguments() { 392 return options.getArguments(); 393 } 394 395 /** 396 * Check if there is a logger registered for a particular name: typically 397 * the "name" attribute of a Loggable annotation on a class 398 * 399 * @param name logger name 400 * @return true, if a logger exists for that name, false otherwise 401 */ 402 public boolean hasLogger(final String name) { 403 return _loggers.get(name) != null; 404 } 405 406 /** 407 * Check if compilation/runtime timings are enabled 408 * @return true if enabled 409 */ 410 public boolean isTimingEnabled() { 411 return _timing != null ? _timing.isEnabled() : false; 412 } 413 414} 415