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