rev 1336 : 8080090: -d option should dump script source as well
Reviewed-by: hannesw, lagergren

   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.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;
  43 
  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     /** 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     /** Directory in which source files and generated class files are dumped */
  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 }
--- EOF ---