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 26 package jdk.nashorn.internal.runtime; 27 28 import java.io.PrintWriter; 29 import java.util.HashSet; 30 import java.util.List; 31 import java.util.Locale; 32 import java.util.Set; 33 import java.util.StringTokenizer; 34 import java.util.TimeZone; 35 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.Option; 40 import jdk.nashorn.internal.runtime.options.Options; 41 42 /** 43 * Script environment consists of command line options, arguments, script files 44 * and output and error writers, top level Namespace etc. 45 */ 46 public final class ScriptEnvironment { 47 /** Output writer for this environment */ 48 private final PrintWriter out; 49 50 /** Error writer for this environment */ 51 private final PrintWriter err; 52 53 /** Top level namespace. */ 54 private final Namespace namespace; 55 56 /** Current Options object. */ 57 private final Options options; 58 59 /** Size of the per-global Class cache size */ 60 public final int _class_cache_size; 61 62 /** Only compile script, do not run it or generate other ScriptObjects */ 63 public final boolean _compile_only; 64 65 /** Accumulated callsite flags that will be used when bootstrapping script callsites */ 66 public final int _callsite_flags; 67 68 /** Generate line number table in class files */ 69 public final boolean _debug_lines; 70 71 /** Package to which generated class files are added */ 72 public final String _dest_dir; 73 74 /** Display stack trace upon error, default is false */ 75 public final boolean _dump_on_error; 76 77 /** Invalid lvalue expressions should be reported as early errors */ 78 public final boolean _early_lvalue_error; 79 80 /** Empty statements should be preserved in the AST */ 81 public final boolean _empty_statements; 82 83 /** Show full Nashorn version */ 84 public final boolean _fullversion; 85 86 /** Launch using as fx application */ 87 public final boolean _fx; 88 89 /** Use single Global instance per jsr223 engine instance. */ 90 public final boolean _global_per_engine; 91 92 /** 93 * Behavior when encountering a function declaration in a lexical context where only statements are acceptable 94 * (function declarations are source elements, but not statements). 95 */ 96 public enum FunctionStatementBehavior { 97 /** 98 * Accept the function declaration silently and treat it as if it were a function expression assigned to a local 99 * variable. 100 */ 101 ACCEPT, 102 /** 103 * Log a parser warning, but accept the function declaration and treat it as if it were a function expression 104 * assigned to a local variable. 105 */ 106 WARNING, 107 /** 108 * Raise a {@code SyntaxError}. 109 */ 110 ERROR 111 } 112 113 /** 114 * Behavior when encountering a function declaration in a lexical context where only statements are acceptable 115 * (function declarations are source elements, but not statements). 116 */ 117 public final FunctionStatementBehavior _function_statement; 118 119 /** Should lazy compilation take place */ 120 public final boolean _lazy_compilation; 121 122 /** Create a new class loaded for each compilation */ 123 public final boolean _loader_per_compile; 124 125 /** Do not support Java support extensions. */ 126 public final boolean _no_java; 127 128 /** Do not support non-standard syntax extensions. */ 129 public final boolean _no_syntax_extensions; 130 131 /** Do not support typed arrays. */ 132 public final boolean _no_typed_arrays; 133 134 /** Only parse the source code, do not compile */ 135 public final boolean _parse_only; 136 137 /** Print the AST before lowering */ 138 public final boolean _print_ast; 139 140 /** Print the AST after lowering */ 141 public final boolean _print_lower_ast; 142 143 /** Print resulting bytecode for script */ 144 public final boolean _print_code; 145 146 /** Print memory usage for IR after each phase */ 147 public final boolean _print_mem_usage; 148 149 /** Print function will no print newline characters */ 150 public final boolean _print_no_newline; 151 152 /** Print AST in more human readable form */ 153 public final boolean _print_parse; 154 155 /** Print AST in more human readable form after Lowering */ 156 public final boolean _print_lower_parse; 157 158 /** print symbols and their contents for the script */ 159 public final boolean _print_symbols; 160 161 /** range analysis for known types */ 162 public final boolean _range_analysis; 163 164 /** is this environment in scripting mode? */ 165 public final boolean _scripting; 166 167 /** is the JIT allowed to specializ calls based on callsite types? */ 168 public final Set<String> _specialize_calls; 169 170 /** is this environment in strict mode? */ 171 public final boolean _strict; 172 173 /** print version info of Nashorn */ 174 public final boolean _version; 175 176 /** should code verification be done of generated bytecode */ 177 public final boolean _verify_code; 178 179 /** time zone for this environment */ 180 public final TimeZone _timezone; 181 182 /** Local for error messages */ 183 public final Locale _locale; 184 185 /** 186 * Constructor 187 * 188 * @param options a Options object 189 * @param out output print writer 190 * @param err error print writer 191 */ 192 public ScriptEnvironment(final Options options, final PrintWriter out, final PrintWriter err) { 193 this.out = out; 194 this.err = err; 195 this.namespace = new Namespace(); 196 this.options = options; 197 198 _class_cache_size = options.getInteger("class.cache.size"); 199 _compile_only = options.getBoolean("compile.only"); 200 _debug_lines = options.getBoolean("debug.lines"); 201 _dest_dir = options.getString("d"); 202 _dump_on_error = options.getBoolean("doe"); 203 _early_lvalue_error = options.getBoolean("early.lvalue.error"); 204 _empty_statements = options.getBoolean("empty.statements"); 205 _fullversion = options.getBoolean("fullversion"); 206 if(options.getBoolean("function.statement.error")) { 207 _function_statement = FunctionStatementBehavior.ERROR; 208 } else if(options.getBoolean("function.statement.warning")) { 209 _function_statement = FunctionStatementBehavior.WARNING; 210 } else { 211 _function_statement = FunctionStatementBehavior.ACCEPT; 212 } 213 _fx = options.getBoolean("fx"); 214 _global_per_engine = options.getBoolean("global.per.engine"); 215 _lazy_compilation = options.getBoolean("lazy.compilation"); 216 _loader_per_compile = options.getBoolean("loader.per.compile"); 217 _no_java = options.getBoolean("no.java"); 218 _no_syntax_extensions = options.getBoolean("no.syntax.extensions"); 219 _no_typed_arrays = options.getBoolean("no.typed.arrays"); 220 _parse_only = options.getBoolean("parse.only"); 221 _print_ast = options.getBoolean("print.ast"); 222 _print_lower_ast = options.getBoolean("print.lower.ast"); 223 _print_code = options.getBoolean("print.code"); 224 _print_mem_usage = options.getBoolean("print.mem.usage"); 225 _print_no_newline = options.getBoolean("print.no.newline"); 226 _print_parse = options.getBoolean("print.parse"); 227 _print_lower_parse = options.getBoolean("print.lower.parse"); 228 _print_symbols = options.getBoolean("print.symbols"); 229 _range_analysis = options.getBoolean("range.analysis"); 230 _scripting = options.getBoolean("scripting"); 231 _strict = options.getBoolean("strict"); 232 _version = options.getBoolean("version"); 233 _verify_code = options.getBoolean("verify.code"); 234 235 final String specialize = options.getString("specialize.calls"); 236 if (specialize == null) { 237 _specialize_calls = null; 238 } else { 239 _specialize_calls = new HashSet<>(); 240 final StringTokenizer st = new StringTokenizer(specialize, ","); 241 while (st.hasMoreElements()) { 242 _specialize_calls.add(st.nextToken()); 243 } 244 } 245 246 int callSiteFlags = 0; 247 if (options.getBoolean("profile.callsites")) { 248 callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_PROFILE; 249 } 250 251 if (options.get("trace.callsites") instanceof KeyValueOption) { 252 callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE; 253 final KeyValueOption kv = (KeyValueOption)options.get("trace.callsites"); 254 if (kv.hasValue("miss")) { 255 callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_MISSES; 256 } 257 if (kv.hasValue("enterexit") || (callSiteFlags & NashornCallSiteDescriptor.CALLSITE_TRACE_MISSES) == 0) { 258 callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_ENTEREXIT; 259 } 260 if (kv.hasValue("objects")) { 261 callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_VALUES; 262 } 263 if (kv.hasValue("scope")) { 264 callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_SCOPE; 265 } 266 } 267 this._callsite_flags = callSiteFlags; 268 269 final Option<?> timezoneOption = options.get("timezone"); 270 if (timezoneOption != null) { 271 this._timezone = (TimeZone)timezoneOption.getValue(); 272 } else { 273 this._timezone = TimeZone.getDefault(); 274 } 275 276 final Option<?> localeOption = options.get("locale"); 277 if (localeOption != null) { 278 this._locale = (Locale)localeOption.getValue(); 279 } else { 280 this._locale = Locale.getDefault(); 281 } 282 } 283 284 /** 285 * Can we specialize a particular method name? 286 * @param functionName method name 287 * @return true if we are allowed to generate versions of this method 288 */ 289 public boolean canSpecialize(final String functionName) { 290 if (_specialize_calls == null) { 291 return false; 292 } 293 return _specialize_calls.isEmpty() || _specialize_calls.contains(functionName); 294 } 295 296 /** 297 * Get the output stream for this environment 298 * @return output print writer 299 */ 300 public PrintWriter getOut() { 301 return out; 302 } 303 304 /** 305 * Get the error stream for this environment 306 * @return error print writer 307 */ 308 public PrintWriter getErr() { 309 return err; 310 } 311 312 /** 313 * Get the namespace for this environment 314 * @return namespace 315 */ 316 public Namespace getNamespace() { 317 return namespace; 318 } 319 320 /** 321 * Return the JavaScript files passed to the program 322 * 323 * @return a list of files 324 */ 325 public List<String> getFiles() { 326 return options.getFiles(); 327 } 328 329 /** 330 * Return the user arguments to the program, i.e. those trailing "--" after 331 * the filename 332 * 333 * @return a list of user arguments 334 */ 335 public List<String> getArguments() { 336 return options.getArguments(); 337 } 338 }