8008731: Separate configuration environment (options, error/output writer etc.) from Context
authorsundar
Mon, 25 Feb 2013 16:58:31 +0530
changeset 16262 75513555e603
parent 16261 c37fd274b194
child 16263 0679aaa72927
8008731: Separate configuration environment (options, error/output writer etc.) from Context Reviewed-by: hannesw, lagergren
nashorn/src/jdk/nashorn/internal/codegen/Attr.java
nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java
nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java
nashorn/src/jdk/nashorn/internal/codegen/Compiler.java
nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java
nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java
nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java
nashorn/src/jdk/nashorn/internal/objects/Global.java
nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
nashorn/src/jdk/nashorn/internal/objects/NativeString.java
nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java
nashorn/src/jdk/nashorn/internal/parser/Parser.java
nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java
nashorn/src/jdk/nashorn/internal/runtime/Context.java
nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java
nashorn/src/jdk/nashorn/internal/runtime/OptionsObject.java
nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java
nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java
nashorn/src/jdk/nashorn/tools/Shell.java
nashorn/test/script/trusted/JDK-8006529.js
nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java
nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java
--- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java	Mon Feb 25 16:58:31 2013 +0530
@@ -101,9 +101,6 @@
  */
 
 final class Attr extends NodeOperatorVisitor {
-    /** Context compiler. */
-    private final Context context;
-
     /**
      * Local definitions in current block (to discriminate from function
      * declarations always defined in the function scope. This is for
@@ -123,11 +120,8 @@
 
     /**
      * Constructor.
-     *
-     * @param compiler the compiler
      */
-    Attr(final Context context) {
-        this.context = context;
+    Attr() {
     }
 
     @Override
@@ -258,7 +252,7 @@
         }
 
         if (functionNode.isScript()) {
-            initFromPropertyMap(context, functionNode);
+            initFromPropertyMap(functionNode);
         }
 
         // Add function name as local symbol
@@ -1271,10 +1265,9 @@
 
     /**
      * Move any properties from a global map into the scope of this method
-     * @param context      context
      * @param functionNode the function node for which to init scope vars
      */
-    private static void initFromPropertyMap(final Context context, final FunctionNode functionNode) {
+    private static void initFromPropertyMap(final FunctionNode functionNode) {
         // For a script, add scope symbols as defined in the property map
         assert functionNode.isScript();
 
--- a/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java	Mon Feb 25 16:58:31 2013 +0530
@@ -62,11 +62,10 @@
 import jdk.internal.org.objectweb.asm.ClassWriter;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
 import jdk.internal.org.objectweb.asm.util.TraceClassVisitor;
-import jdk.nashorn.internal.codegen.Emitter;
 import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.ir.FunctionNode;
-import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.Source;
 
@@ -121,8 +120,8 @@
     /** The ASM classwriter that we use for all bytecode operations */
     protected final ClassWriter cw;
 
-    /** The context */
-    protected final Context context;
+    /** The script environment */
+    protected final ScriptEnvironment env;
 
     /** Default flags for class generation - oublic class */
     private static final EnumSet<Flag> DEFAULT_METHOD_FLAGS = EnumSet.of(Flag.PUBLIC);
@@ -137,13 +136,13 @@
      * Constructor - only used internally in this class as it breaks
      * abstraction towards ASM or other code generator below
      *
-     * @param context  context
-     * @param cw       ASM classwriter
+     * @param env script environment
+     * @param cw  ASM classwriter
      */
-    private ClassEmitter(final Context context, final ClassWriter cw) {
-        assert context != null;
+    private ClassEmitter(final ScriptEnvironment env, final ClassWriter cw) {
+        assert env != null;
 
-        this.context        = context;
+        this.env            = env;
         this.cw             = cw;
         this.methodsStarted = new HashSet<>();
     }
@@ -151,13 +150,13 @@
     /**
      * Constructor
      *
-     * @param context         context
+     * @param env             script environment
      * @param className       name of class to weave
      * @param superClassName  super class name for class
      * @param interfaceNames  names of interfaces implemented by this class, or null if none
      */
-    ClassEmitter(final Context context, final String className, final String superClassName, final String... interfaceNames) {
-        this(context, new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS));
+    ClassEmitter(final ScriptEnvironment env, final String className, final String superClassName, final String... interfaceNames) {
+        this(env, new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS));
         cw.visit(V1_7, ACC_PUBLIC | ACC_SUPER, className, null, superClassName, interfaceNames);
     }
 
@@ -168,8 +167,8 @@
      * @param unitClassName Compile unit class name.
      * @param strictMode    Should we generate this method in strict mode
      */
-    ClassEmitter(final Context context, final String sourceName, final String unitClassName, final boolean strictMode) {
-        this(context,
+    ClassEmitter(final ScriptEnvironment env, final String sourceName, final String unitClassName, final boolean strictMode) {
+        this(env,
              new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) {
                 private static final String OBJECT_CLASS  = "java/lang/Object";
 
@@ -372,10 +371,10 @@
     }
 
     /**
-     * @return context used for class emission
+     * @return env used for class emission
      */
-    Context getContext() {
-        return context;
+    ScriptEnvironment getEnv() {
+        return env;
     }
 
     /**
--- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Mon Feb 25 16:58:31 2013 +0530
@@ -175,7 +175,7 @@
      */
     CodeGenerator(final Compiler compiler) {
         this.compiler      = compiler;
-        this.callSiteFlags = compiler.getContext()._callsite_flags;
+        this.callSiteFlags = compiler.getEnv()._callsite_flags;
     }
 
     /**
@@ -2968,12 +2968,12 @@
      * @param ident identifier for block or function where applicable
      */
     private void printSymbols(final Block block, final String ident) {
-        if (!compiler.getContext()._print_symbols) {
+        if (!compiler.getEnv()._print_symbols) {
             return;
         }
 
         @SuppressWarnings("resource")
-        final PrintWriter out = compiler.getContext().getErr();
+        final PrintWriter out = compiler.getEnv().getErr();
         out.println("[BLOCK in '" + ident + "']");
         if (!block.printSymbols(out)) {
             out.println("<no symbols>");
--- a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java	Mon Feb 25 16:58:31 2013 +0530
@@ -24,8 +24,8 @@
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
 import jdk.nashorn.internal.ir.debug.ASTWriter;
 import jdk.nashorn.internal.ir.debug.PrintVisitor;
-import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ECMAErrors;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.Timing;
 
 /**
@@ -153,15 +153,15 @@
     ATTRIBUTION_PHASE(EnumSet.of(INITIALIZED, CONSTANT_FOLDED, LOWERED), ATTR) {
         @Override
         void transform(final Compiler compiler, final FunctionNode fn) {
-            final Context context = compiler.getContext();
+            final ScriptEnvironment env = compiler.getEnv();
 
-            fn.accept(new Attr(context));
-            if (context._print_lower_ast) {
-                context.getErr().println(new ASTWriter(fn));
+            fn.accept(new Attr());
+            if (env._print_lower_ast) {
+                env.getErr().println(new ASTWriter(fn));
             }
 
-            if (context._print_lower_parse) {
-                context.getErr().println(new PrintVisitor(fn));
+            if (env._print_lower_parse) {
+                env.getErr().println(new PrintVisitor(fn));
            }
         }
 
@@ -232,7 +232,7 @@
     BYTECODE_GENERATION_PHASE(EnumSet.of(INITIALIZED, CONSTANT_FOLDED, LOWERED, ATTR, SPLIT, FINALIZED), EMITTED) {
         @Override
         void transform(final Compiler compiler, final FunctionNode fn) {
-            final Context context = compiler.getContext();
+            final ScriptEnvironment env = compiler.getEnv();
 
             try {
                 final CodeGenerator codegen = new CodeGenerator(compiler);
@@ -240,10 +240,10 @@
                 codegen.generateScopeCalls();
 
             } catch (final VerifyError e) {
-                if (context._verify_code || context._print_code) {
-                    context.getErr().println(e.getClass().getSimpleName() + ": " + e.getMessage());
-                    if (context._dump_on_error) {
-                        e.printStackTrace(context.getErr());
+                if (env._verify_code || env._print_code) {
+                    env.getErr().println(e.getClass().getSimpleName() + ": " + e.getMessage());
+                    if (env._dump_on_error) {
+                        e.printStackTrace(env.getErr());
                     }
                 } else {
                     throw e;
@@ -262,22 +262,22 @@
                 compiler.addClass(className, bytecode);
 
                 //should could be printed to stderr for generate class?
-                if (context._print_code) {
+                if (env._print_code) {
                     final StringBuilder sb = new StringBuilder();
                     sb.append("class: " + className).
                         append('\n').
                         append(ClassEmitter.disassemble(bytecode)).
                         append("=====");
-                    context.getErr().println(sb);
+                    env.getErr().println(sb);
                 }
 
                 //should we verify the generated code?
-                if (context._verify_code) {
-                    context.verify(bytecode);
+                if (env._verify_code) {
+                    compiler.getCodeInstaller().verify(bytecode);
                 }
 
                 //should code be dumped to disk - only valid in compile_only mode?
-                if (context._dest_dir != null && context._compile_only) {
+                if (env._dest_dir != null && env._compile_only) {
                     final String fileName = className.replace('.', File.separatorChar) + ".class";
                     final int    index    = fileName.lastIndexOf(File.separatorChar);
 
@@ -287,7 +287,7 @@
                             if (!dir.exists() && !dir.mkdirs()) {
                                 throw new IOException(dir.toString());
                             }
-                            final File file = new File(context._dest_dir, fileName);
+                            final File file = new File(env._dest_dir, fileName);
                             try (final FileOutputStream fos = new FileOutputStream(file)) {
                                 fos.write(bytecode);
                             }
--- a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java	Mon Feb 25 16:58:31 2013 +0530
@@ -51,8 +51,8 @@
 import jdk.nashorn.internal.ir.FunctionNode;
 import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
 import jdk.nashorn.internal.runtime.CodeInstaller;
-import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.DebugLogger;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.Source;
 import jdk.nashorn.internal.runtime.Timing;
 import jdk.nashorn.internal.runtime.options.Options;
@@ -83,13 +83,13 @@
 
     private final CompilationSequence sequence;
 
-    private final Context context;
+    private final ScriptEnvironment env;
 
     private final String scriptName;
 
     private boolean strict;
 
-    private CodeInstaller<Context> installer;
+    private CodeInstaller<ScriptEnvironment> installer;
 
     /** logger for compiler, trampolines, splits and related code generation events
      *  that affect classes */
@@ -190,14 +190,14 @@
     /**
      * Constructor
      *
-     * @param installer    code installer from
+     * @param installer    code installer
      * @param functionNode function node (in any available {@link CompilationState}) to compile
      * @param sequence     {@link Compiler#CompilationSequence} of {@link CompilationPhase}s to apply as this compilation
      * @param strict       should this compilation use strict mode semantics
      */
     //TODO support an array of FunctionNodes for batch lazy compilation
-    Compiler(final Context context, final CodeInstaller<Context> installer, final FunctionNode functionNode, final CompilationSequence sequence, final boolean strict) {
-        this.context       = context;
+    Compiler(final ScriptEnvironment env, final CodeInstaller<ScriptEnvironment> installer, final FunctionNode functionNode, final CompilationSequence sequence, final boolean strict) {
+        this.env           = env;
         this.functionNode  = functionNode;
         this.sequence      = sequence;
         this.installer     = installer;
@@ -222,32 +222,32 @@
     /**
      * Constructor
      *
-     * @param installer    code installer from context
+     * @param installer    code installer
      * @param functionNode function node (in any available {@link CompilationState}) to compile
      * @param strict       should this compilation use strict mode semantics
      */
-    public Compiler(final CodeInstaller<Context> installer, final FunctionNode functionNode, final boolean strict) {
+    public Compiler(final CodeInstaller<ScriptEnvironment> installer, final FunctionNode functionNode, final boolean strict) {
         this(installer.getOwner(), installer, functionNode, SEQUENCE_DEFAULT, strict);
     }
 
     /**
-     * Constructor - compilation will use the same strict semantics as context
+     * Constructor - compilation will use the same strict semantics as in script environment
      *
-     * @param installer    code installer from context
+     * @param installer    code installer
      * @param functionNode function node (in any available {@link CompilationState}) to compile
      */
-    public Compiler(final CodeInstaller<Context> installer, final FunctionNode functionNode) {
+    public Compiler(final CodeInstaller<ScriptEnvironment> installer, final FunctionNode functionNode) {
         this(installer.getOwner(), installer, functionNode, SEQUENCE_DEFAULT, installer.getOwner()._strict);
     }
 
     /**
-     * Constructor - compilation needs no installer, but uses a context
+     * Constructor - compilation needs no installer, but uses a script environment
      * Used in "compile only" scenarios
-     * @param context a context
+     * @param env a script environment
      * @param functionNode functionNode to compile
      */
-    public Compiler(final Context context, final FunctionNode functionNode) {
-        this(context, null, functionNode, SEQUENCE_DEFAULT, context._strict);
+    public Compiler(final ScriptEnvironment env, final FunctionNode functionNode) {
+        this(env, null, functionNode, SEQUENCE_DEFAULT, env._strict);
     }
 
     /**
@@ -345,7 +345,7 @@
         return constantData;
     }
 
-    CodeInstaller<Context> getCodeInstaller() {
+    CodeInstaller<ScriptEnvironment> getCodeInstaller() {
         return installer;
     }
 
@@ -357,8 +357,8 @@
         bytecode.put(name, code);
     }
 
-    Context getContext() {
-        return this.context;
+    ScriptEnvironment getEnv() {
+        return this.env;
     }
 
     private static String safeSourceName(final Source source) {
@@ -403,7 +403,7 @@
     }
 
     private CompileUnit initCompileUnit(final String unitClassName, final long initialWeight) {
-        final ClassEmitter classEmitter = new ClassEmitter(context, functionNode.getSource().getName(), unitClassName, strict);
+        final ClassEmitter classEmitter = new ClassEmitter(env, functionNode.getSource().getName(), unitClassName, strict);
         final CompileUnit  compileUnit  = new CompileUnit(unitClassName, classEmitter, initialWeight);
 
         classEmitter.begin();
--- a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java	Mon Feb 25 16:58:31 2013 +0530
@@ -84,10 +84,10 @@
 import jdk.nashorn.internal.ir.SplitNode;
 import jdk.nashorn.internal.ir.Symbol;
 import jdk.nashorn.internal.runtime.ArgumentSetter;
-import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.DebugLogger;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.Scope;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
 import jdk.nashorn.internal.runtime.options.Options;
@@ -121,8 +121,8 @@
     /** SplitNode representing the current split, or null if none exists */
     private SplitNode splitNode;
 
-    /** The context */
-    private final Context context;
+    /** The script environment */
+    private final ScriptEnvironment env;
 
     /** Threshold in chars for when string constants should be split */
     static final int LARGE_STRING_THRESHOLD = 32 * 1024;
@@ -171,7 +171,7 @@
      * @param functionNode a function node representing this method
      */
     MethodEmitter(final ClassEmitter classEmitter, final MethodVisitor method, final FunctionNode functionNode) {
-        this.context      = classEmitter.getContext();
+        this.env          = classEmitter.getEnv();
         this.classEmitter = classEmitter;
         this.method       = method;
         this.functionNode = functionNode;
@@ -2237,7 +2237,7 @@
                 sb.append(' ');
             }
 
-            if (context != null) { //early bootstrap code doesn't have inited context yet
+            if (env != null) { //early bootstrap code doesn't have inited context yet
                 LOG.info(sb.toString());
                 if (DEBUG_TRACE_LINE == linePrefix) {
                     new Throwable().printStackTrace(LOG.getOutputStream());
--- a/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java	Mon Feb 25 16:58:31 2013 +0530
@@ -53,6 +53,7 @@
 import jdk.nashorn.internal.runtime.FunctionScope;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.options.Options;
@@ -369,7 +370,7 @@
      * @return Open class emitter.
      */
     private ClassEmitter newClassEmitter(final String className, final String superName) {
-        final ClassEmitter classEmitter = new ClassEmitter(context, className, superName);
+        final ClassEmitter classEmitter = new ClassEmitter(context.getEnv(), className, superName);
         classEmitter.begin();
 
         return classEmitter;
@@ -468,12 +469,13 @@
         classEmitter.end();
 
         final byte[] code = classEmitter.toByteArray();
+        final ScriptEnvironment env = context.getEnv();
 
-        if (context != null && context._print_code) {
-            Context.getCurrentErr().println(ClassEmitter.disassemble(code));
+        if (env._print_code) {
+            env.getErr().println(ClassEmitter.disassemble(code));
         }
 
-        if (context != null && context._verify_code) {
+        if (env._verify_code) {
             context.verify(code);
         }
 
--- a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java	Mon Feb 25 16:58:31 2013 +0530
@@ -68,6 +68,7 @@
 import jdk.nashorn.internal.parser.TokenType;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ParserException;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.Source;
 
 /**
@@ -77,14 +78,14 @@
     /**
      * Returns AST as JSON compatible string.
      *
-     * @param context nashorn context to use
+     * @param env  script environment to use
      * @param code code to be parsed
      * @param name name of the code source (used for location)
      * @param includeLoc tells whether to include location information for nodes or not
      * @return JSON string representation of AST of the supplied code
      */
-    public static String parse(final Context context, final String code, final String name, final boolean includeLoc) {
-        final Parser       parser     = new Parser(context, new Source(name, code), new Context.ThrowErrorManager(), context._strict);
+    public static String parse(final ScriptEnvironment env, final String code, final String name, final boolean includeLoc) {
+        final Parser       parser     = new Parser(env, new Source(name, code), new Context.ThrowErrorManager(), env._strict);
         final JSONWriter   jsonWriter = new JSONWriter(includeLoc);
         try {
             final FunctionNode functionNode = parser.parse(CompilerConstants.RUN_SCRIPT.tag());
--- a/nashorn/src/jdk/nashorn/internal/objects/Global.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java	Mon Feb 25 16:58:31 2013 +0530
@@ -48,7 +48,7 @@
 import jdk.nashorn.internal.runtime.GlobalObject;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.NativeJavaPackage;
-import jdk.nashorn.internal.runtime.OptionsObject;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.PropertyDescriptor;
 import jdk.nashorn.internal.runtime.regexp.RegExpResult;
 import jdk.nashorn.internal.runtime.Scope;
@@ -364,7 +364,7 @@
          */
         this.setMap(getMap().duplicate());
 
-        final int cacheSize = context._class_cache_size;
+        final int cacheSize = context.getEnv()._class_cache_size;
         if (cacheSize > 0) {
             classCache = new ClassCache(cacheSize);
         }
@@ -384,6 +384,15 @@
     }
 
     /**
+     * Script access to {@link ScriptEnvironment}
+     *
+     * @return the script environment
+     */
+    static ScriptEnvironment getEnv() {
+        return instance().context.getEnv();
+    }
+
+    /**
      * Script access to {@link Context}
      *
      * @return the context
@@ -398,7 +407,7 @@
      * @return true if strict mode enabled in {@link Global#getThisContext()}
      */
     static boolean isStrict() {
-        return getThisContext()._strict;
+        return getEnv()._strict;
     }
 
     // GlobalObject interface implementation
@@ -578,7 +587,7 @@
     public PropertyDescriptor newAccessorDescriptor(final Object get, final Object set, final boolean configurable, final boolean enumerable) {
         final AccessorPropertyDescriptor desc = new AccessorPropertyDescriptor(configurable, enumerable, get == null ? UNDEFINED : get, set == null ? UNDEFINED : set);
 
-        final boolean strict = context._strict;
+        final boolean strict = context.getEnv()._strict;
 
         if (get == null) {
             desc.delete(PropertyDescriptor.GET, strict);
@@ -1333,6 +1342,7 @@
     private void init() {
         assert Context.getGlobal() == this : "this global is not set as current";
 
+        final ScriptEnvironment env = context.getEnv();
         // initialize Function and Object constructor
         initFunctionAndObject();
 
@@ -1352,7 +1362,7 @@
         this.decodeURIComponent = ScriptFunctionImpl.makeFunction("decodeURIComponent", GlobalFunctions.DECODE_URICOMPONENT);
         this.escape             = ScriptFunctionImpl.makeFunction("escape",     GlobalFunctions.ESCAPE);
         this.unescape           = ScriptFunctionImpl.makeFunction("unescape",   GlobalFunctions.UNESCAPE);
-        this.print              = ScriptFunctionImpl.makeFunction("print",      context._print_no_newline ? PRINT : PRINTLN);
+        this.print              = ScriptFunctionImpl.makeFunction("print",      env._print_no_newline ? PRINT : PRINTLN);
         this.load               = ScriptFunctionImpl.makeFunction("load",       LOAD);
         this.exit               = ScriptFunctionImpl.makeFunction("exit",       EXIT);
         this.quit               = ScriptFunctionImpl.makeFunction("quit",       EXIT);
@@ -1395,7 +1405,7 @@
 
         initTypedArray();
 
-        if (context._scripting) {
+        if (env._scripting) {
             initScripting();
         }
 
@@ -1411,11 +1421,11 @@
         this.__LINE__ = 0.0;
 
         // expose script (command line) arguments as "arguments" property of global
-        final List<String> arguments = context.getOptions().getArguments();
+        final List<String> arguments = env.getArguments();
         final Object argsObj = wrapAsObject(arguments.toArray());
 
         addOwnProperty("arguments", Attribute.NOT_ENUMERABLE, argsObj);
-        if (context._scripting) {
+        if (env._scripting) {
             // synonym for "arguments" in scripting mode
             addOwnProperty("$ARG", Attribute.NOT_ENUMERABLE, argsObj);
         }
@@ -1493,7 +1503,7 @@
         addOwnProperty("echo", Attribute.NOT_ENUMERABLE, value);
 
         // Nashorn extension: global.$OPTIONS (scripting-mode-only)
-        value = new OptionsObject(context);
+        value = context.getEnv();
         addOwnProperty("$OPTIONS", Attribute.NOT_ENUMERABLE, value);
 
         // Nashorn extension: global.$ENV (scripting-mode-only)
@@ -1568,7 +1578,7 @@
 
     @SuppressWarnings("resource")
     private static Object printImpl(final boolean newLine, final Object... objects) {
-        final PrintWriter out = Global.getThisContext().getOut();
+        final PrintWriter out = Global.getEnv().getOut();
 
         boolean first = true;
         for (final Object object : objects) {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java	Mon Feb 25 16:58:31 2013 +0530
@@ -40,8 +40,8 @@
 import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
 import jdk.nashorn.internal.objects.annotations.Where;
 import jdk.nashorn.internal.runtime.ConsString;
-import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
@@ -104,10 +104,10 @@
     }
 
     NativeDate(final double time) {
-        final Context context = Global.getThisContext();
+        final ScriptEnvironment env = Global.getEnv();
 
         this.time = time;
-        this.timezone = context.getTimeZone();
+        this.timezone = env._timezone;
         this.setProto(Global.instance().getDatePrototype());
     }
 
@@ -886,7 +886,7 @@
             if (fields[DateParser.TIMEZONE] != null) {
                 d -= fields[DateParser.TIMEZONE] * 60000;
             } else {
-                d = utc(d, Global.getThisContext().getTimeZone());
+                d = utc(d, Global.getEnv()._timezone);
             }
             d = timeClip(d);
             return d;
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java	Mon Feb 25 16:58:31 2013 +0530
@@ -641,7 +641,7 @@
     public static Object localeCompare(final Object self, final Object that) {
 
         final String   str      = checkObjectToString(self);
-        final Collator collator = Collator.getInstance(Global.getThisContext().getLocale());
+        final Collator collator = Collator.getInstance(Global.getEnv()._locale);
 
         collator.setStrength(Collator.IDENTICAL);
         collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
@@ -996,7 +996,7 @@
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
     public static Object toLocaleLowerCase(final Object self) {
-        return checkObjectToString(self).toLowerCase(Global.getThisContext().getLocale());
+        return checkObjectToString(self).toLowerCase(Global.getEnv()._locale);
     }
 
     /**
@@ -1016,7 +1016,7 @@
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
     public static Object toLocaleUpperCase(final Object self) {
-        return checkObjectToString(self).toUpperCase(Global.getThisContext().getLocale());
+        return checkObjectToString(self).toUpperCase(Global.getEnv()._locale);
     }
 
     /**
--- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java	Mon Feb 25 16:58:31 2013 +0530
@@ -12,6 +12,7 @@
 import jdk.nashorn.internal.ir.FunctionNode;
 import jdk.nashorn.internal.runtime.CodeInstaller;
 import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptFunctionData;
 import jdk.nashorn.internal.runtime.ScriptObject;
@@ -23,7 +24,7 @@
  */
 public final class ScriptFunctionTrampolineImpl extends ScriptFunctionImpl {
 
-    private CodeInstaller<Context> installer;
+    private CodeInstaller<ScriptEnvironment> installer;
 
     /** Function node to lazily recompile when trampoline is hit */
     private FunctionNode functionNode;
@@ -37,7 +38,7 @@
      * @param scope        scope
      * @param allocator    allocator
      */
-    public ScriptFunctionTrampolineImpl(final CodeInstaller<Context> installer, final FunctionNode functionNode, final ScriptFunctionData data, final ScriptObject scope, final MethodHandle allocator) {
+    public ScriptFunctionTrampolineImpl(final CodeInstaller<ScriptEnvironment> installer, final FunctionNode functionNode, final ScriptFunctionData data, final ScriptObject scope, final MethodHandle allocator) {
         super(null, data, scope, allocator);
 
         this.installer    = installer;
--- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java	Mon Feb 25 16:58:31 2013 +0530
@@ -101,6 +101,7 @@
 import jdk.nashorn.internal.runtime.ErrorManager;
 import jdk.nashorn.internal.runtime.JSErrorType;
 import jdk.nashorn.internal.runtime.ParserException;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.ScriptingFunctions;
 import jdk.nashorn.internal.runtime.Source;
 import jdk.nashorn.internal.runtime.Timing;
@@ -109,8 +110,8 @@
  * Builds the IR.
  */
 public class Parser extends AbstractParser {
-    /** Current context. */
-    private final Context context;
+    /** Current script environment. */
+    private final ScriptEnvironment env;
 
     /** Is scripting mode. */
     private final boolean scripting;
@@ -132,27 +133,27 @@
     /**
      * Constructor
      *
-     * @param context parser context
+     * @param env     script environment
      * @param source  source to parse
      * @param errors  error manager
      */
-    public Parser(final Context context, final Source source, final ErrorManager errors) {
-        this(context, source, errors, context._strict);
+    public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors) {
+        this(env, source, errors, env._strict);
     }
 
     /**
      * Construct a parser.
      *
-     * @param context parser context
+     * @param env     script environment
      * @param source  source to parse
      * @param errors  error manager
      * @param strict  parser created with strict mode enabled.
      */
-    public Parser(final Context context, final Source source, final ErrorManager errors, final boolean strict) {
+    public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict) {
         super(source, errors, strict);
-        this.context   = context;
-        this.namespace = new Namespace(context.getNamespace());
-        this.scripting = context._scripting;
+        this.env   = env;
+        this.namespace = new Namespace(env.getNamespace());
+        this.scripting = env._scripting;
     }
 
     /**
@@ -184,7 +185,7 @@
 
         try {
             stream = new TokenStream();
-            lexer  = new Lexer(source, stream, scripting && !context._no_syntax_extensions);
+            lexer  = new Lexer(source, stream, scripting && !env._no_syntax_extensions);
 
             // Set up first token (skips opening EOL.)
             k = -1;
@@ -209,8 +210,8 @@
                 errors.error(message);
             }
 
-            if (context._dump_on_error) {
-                e.printStackTrace(context.getErr());
+            if (env._dump_on_error) {
+                e.printStackTrace(env.getErr());
             }
 
             return null;
@@ -246,8 +247,8 @@
                 errors.error(message);
             }
 
-            if (context._dump_on_error) {
-                e.printStackTrace(context.getErr());
+            if (env._dump_on_error) {
+                e.printStackTrace(env.getErr());
             }
         }
 
@@ -430,7 +431,7 @@
             if (!(lhs instanceof AccessNode ||
                   lhs instanceof IndexNode ||
                   lhs instanceof IdentNode)) {
-                if (context._early_lvalue_error) {
+                if (env._early_lvalue_error) {
                     error(JSErrorType.REFERENCE_ERROR, AbstractParser.message("invalid.lvalue"), lhs.getToken());
                 }
                 return referenceError(lhs, rhs);
@@ -1018,7 +1019,7 @@
      * Parse an empty statement.
      */
     private void emptyStatement() {
-        if (context._empty_statements) {
+        if (env._empty_statements) {
             block.addStatement(new EmptyNode(source, token,
                     Token.descPosition(token) + Token.descLength(token)));
         }
@@ -1126,7 +1127,7 @@
 
             // Nashorn extension: for each expression.
             // iterate property values rather than property names.
-            if (!context._no_syntax_extensions && type == IDENT && "each".equals(getValue())) {
+            if (!env._no_syntax_extensions && type == IDENT && "each".equals(getValue())) {
                 forNode.setIsForEach();
                 next();
             }
@@ -2416,7 +2417,7 @@
         // The object literal following the "new Constructor()" expresssion
         // is passed as an additional (last) argument to the constructor.
 
-        if (!context._no_syntax_extensions && type == LBRACE) {
+        if (!env._no_syntax_extensions && type == LBRACE) {
             arguments.add(objectLiteral());
         }
 
@@ -2572,7 +2573,7 @@
             verifyStrictIdent(name, "function name");
         } else if (isStatement) {
             // Nashorn extension: anonymous function statements
-            if (context._no_syntax_extensions || !context._anon_functions) {
+            if (env._no_syntax_extensions || !env._anon_functions) {
                 expect(IDENT);
             }
         }
@@ -2710,7 +2711,7 @@
             functionNode.setFirstToken(firstToken);
 
             // Nashorn extension: expression closures
-            if (!context._no_syntax_extensions && type != LBRACE) {
+            if (!env._no_syntax_extensions && type != LBRACE) {
                 /*
                  * Example:
                  *
@@ -3072,7 +3073,7 @@
      * Add a line number node at current position
      */
     private LineNumberNode lineNumber() {
-        if (context._debug_lines) {
+        if (env._debug_lines) {
             return new LineNumberNode(source, token, line);
         }
         return null;
--- a/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java	Mon Feb 25 16:58:31 2013 +0530
@@ -51,4 +51,13 @@
      * @return the installed class
      */
     public Class<?> install(final String className, final byte[] bytecode);
+
+    /*
+     * Verify generated bytecode before emission. This is called back from the
+     * {@link ClassEmitter} or the {@link Compiler}. If the "--verify-code" parameter
+     * hasn't been given, this is a nop
+     *
+     * @param bytecode bytecode to verify
+     */
+    public void verify(final byte[] code);
 }
--- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java	Mon Feb 25 16:58:31 2013 +0530
@@ -43,22 +43,15 @@
 import java.security.CodeSigner;
 import java.security.CodeSource;
 import java.security.PrivilegedAction;
-import java.util.Locale;
-import java.util.TimeZone;
 import jdk.internal.org.objectweb.asm.ClassReader;
 import jdk.internal.org.objectweb.asm.util.CheckClassAdapter;
-import jdk.nashorn.internal.codegen.ClassEmitter;
 import jdk.nashorn.internal.codegen.Compiler;
-import jdk.nashorn.internal.codegen.Namespace;
 import jdk.nashorn.internal.codegen.ObjectClassGenerator;
 import jdk.nashorn.internal.ir.FunctionNode;
 import jdk.nashorn.internal.ir.debug.ASTWriter;
 import jdk.nashorn.internal.ir.debug.PrintVisitor;
 import jdk.nashorn.internal.parser.Parser;
 import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
-import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
-import jdk.nashorn.internal.runtime.options.KeyValueOption;
-import jdk.nashorn.internal.runtime.options.Option;
 import jdk.nashorn.internal.runtime.options.Options;
 import sun.reflect.Reflection;
 
@@ -71,7 +64,7 @@
      * ContextCodeInstaller that has the privilege of installing classes in the Context.
      * Can only be instantiated from inside the context and is opaque to other classes
      */
-    public static class ContextCodeInstaller implements CodeInstaller<Context> {
+    public static class ContextCodeInstaller implements CodeInstaller<ScriptEnvironment> {
         private final Context      context;
         private final ScriptLoader loader;
         private final CodeSource   codeSource;
@@ -87,14 +80,19 @@
          * @return context
          */
         @Override
-        public Context getOwner() {
-            return context;
+        public ScriptEnvironment getOwner() {
+            return context.env;
         }
 
         @Override
         public Class<?> install(final String className, final byte[] bytecode) {
             return loader.installClass(className, bytecode, codeSource);
         }
+
+        @Override
+        public void verify(final byte[] code) {
+            context.verify(code);
+        }
     }
 
     /** Is Context global debug mode enabled ? */
@@ -198,6 +196,12 @@
         }
     }
 
+    /** Current environment. */
+    private final ScriptEnvironment env;
+
+    /** is this context in strict mode? Cached from env. as this is used heavily. */
+    public final boolean _strict;
+
     /** class loader to resolve classes from script. */
     private final ClassLoader  appLoader;
 
@@ -207,108 +211,12 @@
     /** Class loader to load classes compiled from scripts. */
     private final ScriptLoader scriptLoader;
 
-    /** Top level namespace. */
-    private final Namespace namespace;
-
-    /** Current options. */
-    private final Options options;
-
     /** Current error manager. */
     private final ErrorManager errors;
 
-    /** Output writer for this context */
-    private final PrintWriter out;
-
-    /** Error writer for this context */
-    private final PrintWriter err;
-
-    /** Local for error messages */
-    private final Locale locale;
-
     /** Empty map used for seed map for JO$ objects */
     final PropertyMap emptyMap = PropertyMap.newEmptyMap(this);
 
-    // cache fields for "well known" options.
-    // see jdk.nashorn.internal.runtime.Resources
-
-    /** Always allow functions as statements */
-    public final boolean _anon_functions;
-
-    /** Size of the per-global Class cache size */
-    public final int     _class_cache_size;
-
-    /** Only compile script, do not run it or generate other ScriptObjects */
-    public final boolean _compile_only;
-
-    /** Accumulated callsite flags that will be used when boostrapping script callsites */
-    public final int     _callsite_flags;
-
-    /** Genereate line number table in class files */
-    public final boolean _debug_lines;
-
-    /** Package to which generated class files are added */
-    public final String  _dest_dir;
-
-    /** Display stack trace upon error, default is false */
-    public final boolean _dump_on_error;
-
-    /** Invalid lvalue expressions should be reported as early errors */
-    public final boolean _early_lvalue_error;
-
-    /** Empty statements should be preserved in the AST */
-    public final boolean _empty_statements;
-
-    /** Show full Nashorn version */
-    public final boolean _fullversion;
-
-    /** Create a new class loaded for each compilation */
-    public final boolean _loader_per_compile;
-
-    /** Do not support non-standard syntax extensions. */
-    public final boolean _no_syntax_extensions;
-
-    /** Package to which generated class files are added */
-    public final String  _package;
-
-    /** Only parse the source code, do not compile */
-    public final boolean _parse_only;
-
-    /** Print the AST before lowering */
-    public final boolean _print_ast;
-
-    /** Print the AST after lowering */
-    public final boolean _print_lower_ast;
-
-    /** Print resulting bytecode for script */
-    public final boolean _print_code;
-
-    /** Print function will no print newline characters */
-    public final boolean _print_no_newline;
-
-    /** Print AST in more human readable form */
-    public final boolean _print_parse;
-
-    /** Print AST in more human readable form after Lowering */
-    public final boolean _print_lower_parse;
-
-    /** print symbols and their contents for the script */
-    public final boolean _print_symbols;
-
-    /** is this context in scripting mode? */
-    public final boolean _scripting;
-
-    /** is this context in strict mode? */
-    public final boolean _strict;
-
-    /** print version info of Nashorn */
-    public final boolean _version;
-
-    /** should code verification be done of generated bytecode */
-    public final boolean _verify_code;
-
-    /** time zone for this context */
-    public final TimeZone _timezone;
-
     private static final ClassLoader myLoader = Context.class.getClassLoader();
     private static final StructureLoader sharedLoader;
 
@@ -362,6 +270,8 @@
             sm.checkPermission(new RuntimePermission("createNashornContext"));
         }
 
+        this.env       = new ScriptEnvironment(options, out, err);
+        this._strict   = env._strict;
         this.appLoader = appLoader;
         this.scriptLoader = (ScriptLoader)AccessController.doPrivileged(
              new PrivilegedAction<ClassLoader>() {
@@ -371,73 +281,12 @@
                     return new ScriptLoader(structureLoader, Context.this);
                 }
              });
-
-        this.namespace = new Namespace();
-        this.options   = options;
         this.errors    = errors;
-        this.locale    = Locale.getDefault();
-        this.out       = out;
-        this.err       = err;
-
-        _anon_functions       = options.getBoolean("anon.functions");
-        _class_cache_size     = options.getInteger("class.cache.size");
-        _compile_only         = options.getBoolean("compile.only");
-        _debug_lines          = options.getBoolean("debug.lines");
-        _dest_dir             = options.getString("d");
-        _dump_on_error        = options.getBoolean("doe");
-        _early_lvalue_error   = options.getBoolean("early.lvalue.error");
-        _empty_statements     = options.getBoolean("empty.statements");
-        _fullversion          = options.getBoolean("fullversion");
-        _loader_per_compile   = options.getBoolean("loader.per.compile");
-        _no_syntax_extensions = options.getBoolean("no.syntax.extensions");
-        _package              = options.getString("package");
-        _parse_only           = options.getBoolean("parse.only");
-        _print_ast            = options.getBoolean("print.ast");
-        _print_lower_ast      = options.getBoolean("print.lower.ast");
-        _print_code           = options.getBoolean("print.code");
-        _print_no_newline     = options.getBoolean("print.no.newline");
-        _print_parse          = options.getBoolean("print.parse");
-        _print_lower_parse    = options.getBoolean("print.lower.parse");
-        _print_symbols        = options.getBoolean("print.symbols");
-        _scripting            = options.getBoolean("scripting");
-        _strict               = options.getBoolean("strict");
-        _version              = options.getBoolean("version");
-        _verify_code          = options.getBoolean("verify.code");
-
-        int callSiteFlags = 0;
-        if (options.getBoolean("profile.callsites")) {
-            callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_PROFILE;
-        }
-
-        if (options.get("trace.callsites") instanceof KeyValueOption) {
-            callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE;
-            final KeyValueOption kv = (KeyValueOption)options.get("trace.callsites");
-            if (kv.hasValue("miss")) {
-                callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_MISSES;
-            }
-            if (kv.hasValue("enterexit") || (callSiteFlags & NashornCallSiteDescriptor.CALLSITE_TRACE_MISSES) == 0) {
-                callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_ENTEREXIT;
-            }
-            if (kv.hasValue("objects")) {
-                callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_VALUES;
-            }
-            if (kv.hasValue("scope")) {
-                callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_SCOPE;
-            }
-        }
-        this._callsite_flags = callSiteFlags;
-
-        final Option<?> option = options.get("timezone");
-        if (option != null) {
-            this._timezone = (TimeZone)option.getValue();
-        } else {
-            this._timezone  = TimeZone.getDefault();
-        }
 
         // if user passed -classpath option, make a class loader with that and set it as
         // thread context class loader so that script can access classes from that path.
         final String classPath = options.getString("classpath");
-        if (! _compile_only && classPath != null && !classPath.isEmpty()) {
+        if (! env._compile_only && classPath != null && !classPath.isEmpty()) {
             // make sure that caller can create a class loader.
             if (sm != null) {
                 sm.checkPermission(new RuntimePermission("createClassLoader"));
@@ -448,11 +297,11 @@
         }
 
         // print version info if asked.
-        if (_version) {
+        if (env._version) {
             getErr().println("nashorn " + Version.version());
         }
 
-        if (_fullversion) {
+        if (env._fullversion) {
             getErr().println("nashorn full version " + Version.fullVersion());
         }
     }
@@ -466,11 +315,19 @@
     }
 
     /**
+     * Get the script environment for this context
+     * @return script environment
+     */
+    public ScriptEnvironment getEnv() {
+        return env;
+    }
+
+    /**
      * Get the output stream for this context
      * @return output print writer
      */
     public PrintWriter getOut() {
-        return out;
+        return env.getOut();
     }
 
     /**
@@ -478,39 +335,7 @@
      * @return error print writer
      */
     public PrintWriter getErr() {
-        return err;
-    }
-
-    /**
-     * Get the namespace for this context
-     * @return namespace
-     */
-    public Namespace getNamespace() {
-        return namespace;
-    }
-
-    /**
-     * Get the options given to this context
-     * @return options
-     */
-    public Options getOptions() {
-        return options;
-    }
-
-    /**
-     * Get the locale for this context
-     * @return locale
-     */
-    public Locale getLocale() {
-        return locale;
-    }
-
-    /**
-     * Get the time zone for this context
-     * @return time zone
-     */
-    public TimeZone getTimeZone() {
-        return _timezone;
+        return env.getErr();
     }
 
     /**
@@ -739,7 +564,7 @@
 
     /**
      * Verify generated bytecode before emission. This is called back from the
-     * {@link ClassEmitter} or the {@link Compiler}. If the "--verify-code" parameter
+     * {@link ObjectClassGenerator} or the {@link Compiler}. If the "--verify-code" parameter
      * hasn't been given, this is a nop
      *
      * Note that verification may load classes -- we don't want to do that unless
@@ -749,7 +574,7 @@
      * @param bytecode bytecode to verify
      */
     public void verify(final byte[] bytecode) {
-        if (_verify_code) {
+        if (env._verify_code) {
             // No verification when security manager is around as verifier
             // may load further classes - which should be avoided.
             if (System.getSecurityManager() == null) {
@@ -792,7 +617,7 @@
         }
 
         // Need only minimal global object, if we are just compiling.
-        if (!_compile_only) {
+        if (!env._compile_only) {
             final ScriptObject oldGlobal = Context.getGlobalTrusted();
             try {
                 Context.setGlobalTrusted(global);
@@ -902,7 +727,7 @@
         GlobalObject global = null;
         Class<?> script;
 
-        if (_class_cache_size > 0) {
+        if (env._class_cache_size > 0) {
             global = (GlobalObject)Context.getGlobalTrusted();
             script = global.findCachedClass(source);
             if (script != null) {
@@ -910,23 +735,23 @@
             }
         }
 
-        final FunctionNode functionNode = new Parser(this, source, errMan, strict).parse();
-        if (errors.hasErrors() || _parse_only) {
+        final FunctionNode functionNode = new Parser(env, source, errMan, strict).parse();
+        if (errors.hasErrors() || env._parse_only) {
             return null;
         }
 
-        if (_print_ast) {
+        if (env._print_ast) {
             getErr().println(new ASTWriter(functionNode));
         }
 
-        if (_print_parse) {
+        if (env._print_parse) {
             getErr().println(new PrintVisitor(functionNode));
         }
 
         final URL          url    = source.getURL();
-        final ScriptLoader loader = _loader_per_compile ? createNewLoader() : scriptLoader;
+        final ScriptLoader loader = env._loader_per_compile ? createNewLoader() : scriptLoader;
         final CodeSource   cs     = url == null ? null : new CodeSource(url, (CodeSigner[])null);
-        final CodeInstaller<Context> installer = new ContextCodeInstaller(this, loader, cs);
+        final CodeInstaller<ScriptEnvironment> installer = new ContextCodeInstaller(this, loader, cs);
 
         final Compiler compiler = new Compiler(installer, functionNode, strict);
 
--- a/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java	Mon Feb 25 16:58:31 2013 +0530
@@ -71,7 +71,7 @@
                 new Source("<json>", str),
                 new Context.ThrowErrorManager(),
                 (context != null) ?
-                    context._strict :
+                    context.getEnv()._strict :
                     false);
 
         Node node;
--- a/nashorn/src/jdk/nashorn/internal/runtime/OptionsObject.java	Fri Feb 22 23:33:46 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.nashorn.internal.runtime;
-
-import java.util.TimeZone;
-
-/**
- * A convenience object to expose only command line options from a Context.
- */
-public final class OptionsObject {
-    /** Always allow functions as statements */
-    public final boolean _anon_functions;
-
-    /** Size of the per-global Class cache size */
-    public final int     _class_cache_size;
-
-    /** Only compile script, do not run it or generate other ScriptObjects */
-    public final boolean _compile_only;
-
-    /** Accumulated callsite flags that will be used when bootstrapping script callsites */
-    public final int     _callsite_flags;
-
-    /** Generate line number table in class files */
-    public final boolean _debug_lines;
-
-    /** Package to which generated class files are added */
-    public final String  _dest_dir;
-
-    /** Display stack trace upon error, default is false */
-    public final boolean _dump_on_error;
-
-    /** Invalid lvalue expressions should be reported as early errors */
-    public final boolean _early_lvalue_error;
-
-    /** Empty statements should be preserved in the AST */
-    public final boolean _empty_statements;
-
-    /** Show full Nashorn version */
-    public final boolean _fullversion;
-
-    /** Create a new class loaded for each compilation */
-    public final boolean _loader_per_compile;
-
-    /** Package to which generated class files are added */
-    public final String  _package;
-
-    /** Only parse the source code, do not compile */
-    public final boolean _parse_only;
-
-    /** Print the AST before lowering */
-    public final boolean _print_ast;
-
-    /** Print the AST after lowering */
-    public final boolean _print_lower_ast;
-
-    /** Print resulting bytecode for script */
-    public final boolean _print_code;
-
-    /** Print function will no print newline characters */
-    public final boolean _print_no_newline;
-
-    /** Print AST in more human readable form */
-    public final boolean _print_parse;
-
-    /** Print AST in more human readable form after Lowering */
-    public final boolean _print_lower_parse;
-
-    /** print symbols and their contents for the script */
-    public final boolean _print_symbols;
-
-    /** is this context in scripting mode? */
-    public final boolean _scripting;
-
-    /** is this context in strict mode? */
-    public final boolean _strict;
-
-    /** print version info of Nashorn */
-    public final boolean _version;
-
-    /** should code verification be done of generated bytecode */
-    public final boolean _verify_code;
-
-    /** time zone for this context */
-    public final TimeZone _timezone;
-
-    /**
-     * Constructor
-     *
-     * @param context a context
-     */
-    public OptionsObject(final Context context) {
-        this._anon_functions = context._anon_functions;
-        this._callsite_flags = context._callsite_flags;
-        this._class_cache_size = context._class_cache_size;
-        this._compile_only = context._compile_only;
-        this._debug_lines = context._debug_lines;
-        this._dest_dir = context._dest_dir;
-        this._dump_on_error = context._dump_on_error;
-        this._early_lvalue_error = context._early_lvalue_error;
-        this._empty_statements = context._empty_statements;
-        this._fullversion = context._fullversion;
-        this._loader_per_compile = context._loader_per_compile;
-        this._package = context._package;
-        this._parse_only = context._parse_only;
-        this._print_ast = context._print_ast;
-        this._print_code = context._print_code;
-        this._print_lower_ast = context._print_lower_ast;
-        this._print_lower_parse = context._print_lower_parse;
-        this._print_no_newline = context._print_no_newline;
-        this._print_parse = context._print_parse;
-        this._print_symbols = context._print_symbols;
-        this._scripting = context._scripting;
-        this._strict = context._strict;
-        this._timezone = context._timezone;
-        this._verify_code = context._verify_code;
-        this._version = context._version;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java	Mon Feb 25 16:58:31 2013 +0530
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.internal.runtime;
+
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
+import jdk.nashorn.internal.codegen.Namespace;
+import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
+import jdk.nashorn.internal.runtime.options.KeyValueOption;
+import jdk.nashorn.internal.runtime.options.Option;
+import jdk.nashorn.internal.runtime.options.Options;
+
+/**
+ * Script environment consists of command line options, arguments, script files
+ * and output and error writers, top level Namespace etc.
+ */
+public final class ScriptEnvironment {
+    /** Output writer for this environment */
+    private final PrintWriter out;
+
+    /** Error writer for this environment */
+    private final PrintWriter err;
+
+    /** Top level namespace. */
+    private final Namespace namespace;
+
+    /** Current Options object. */
+    private Options options;
+
+    /** Always allow functions as statements */
+    public final boolean _anon_functions;
+
+    /** Size of the per-global Class cache size */
+    public final int     _class_cache_size;
+
+    /** Only compile script, do not run it or generate other ScriptObjects */
+    public final boolean _compile_only;
+
+    /** Accumulated callsite flags that will be used when bootstrapping script callsites */
+    public final int     _callsite_flags;
+
+    /** Generate line number table in class files */
+    public final boolean _debug_lines;
+
+    /** Package to which generated class files are added */
+    public final String  _dest_dir;
+
+    /** Display stack trace upon error, default is false */
+    public final boolean _dump_on_error;
+
+    /** Invalid lvalue expressions should be reported as early errors */
+    public final boolean _early_lvalue_error;
+
+    /** Empty statements should be preserved in the AST */
+    public final boolean _empty_statements;
+
+    /** Show full Nashorn version */
+    public final boolean _fullversion;
+
+    /** Create a new class loaded for each compilation */
+    public final boolean _loader_per_compile;
+
+    /** Do not support non-standard syntax extensions. */
+    public final boolean _no_syntax_extensions;
+
+    /** Package to which generated class files are added */
+    public final String  _package;
+
+    /** Only parse the source code, do not compile */
+    public final boolean _parse_only;
+
+    /** Print the AST before lowering */
+    public final boolean _print_ast;
+
+    /** Print the AST after lowering */
+    public final boolean _print_lower_ast;
+
+    /** Print resulting bytecode for script */
+    public final boolean _print_code;
+
+    /** Print function will no print newline characters */
+    public final boolean _print_no_newline;
+
+    /** Print AST in more human readable form */
+    public final boolean _print_parse;
+
+    /** Print AST in more human readable form after Lowering */
+    public final boolean _print_lower_parse;
+
+    /** print symbols and their contents for the script */
+    public final boolean _print_symbols;
+
+    /** is this environment in scripting mode? */
+    public final boolean _scripting;
+
+    /** is this environment in strict mode? */
+    public final boolean _strict;
+
+    /** print version info of Nashorn */
+    public final boolean _version;
+
+    /** should code verification be done of generated bytecode */
+    public final boolean _verify_code;
+
+    /** time zone for this environment */
+    public final TimeZone _timezone;
+
+    /** Local for error messages */
+    public final Locale _locale;
+
+    /**
+     * Constructor
+     *
+     * @param options a Options object
+     * @param out output print writer
+     * @param err error print writer
+     */
+    ScriptEnvironment(final Options options, final PrintWriter out, final PrintWriter err) {
+        this.out = out;
+        this.err = err;
+        this.namespace = new Namespace();
+        this.options = options;
+
+        _anon_functions       = options.getBoolean("anon.functions");
+        _class_cache_size     = options.getInteger("class.cache.size");
+        _compile_only         = options.getBoolean("compile.only");
+        _debug_lines          = options.getBoolean("debug.lines");
+        _dest_dir             = options.getString("d");
+        _dump_on_error        = options.getBoolean("doe");
+        _early_lvalue_error   = options.getBoolean("early.lvalue.error");
+        _empty_statements     = options.getBoolean("empty.statements");
+        _fullversion          = options.getBoolean("fullversion");
+        _loader_per_compile   = options.getBoolean("loader.per.compile");
+        _no_syntax_extensions = options.getBoolean("no.syntax.extensions");
+        _package              = options.getString("package");
+        _parse_only           = options.getBoolean("parse.only");
+        _print_ast            = options.getBoolean("print.ast");
+        _print_lower_ast      = options.getBoolean("print.lower.ast");
+        _print_code           = options.getBoolean("print.code");
+        _print_no_newline     = options.getBoolean("print.no.newline");
+        _print_parse          = options.getBoolean("print.parse");
+        _print_lower_parse    = options.getBoolean("print.lower.parse");
+        _print_symbols        = options.getBoolean("print.symbols");
+        _scripting            = options.getBoolean("scripting");
+        _strict               = options.getBoolean("strict");
+        _version              = options.getBoolean("version");
+        _verify_code          = options.getBoolean("verify.code");
+
+        int callSiteFlags = 0;
+        if (options.getBoolean("profile.callsites")) {
+            callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_PROFILE;
+        }
+
+        if (options.get("trace.callsites") instanceof KeyValueOption) {
+            callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE;
+            final KeyValueOption kv = (KeyValueOption)options.get("trace.callsites");
+            if (kv.hasValue("miss")) {
+                callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_MISSES;
+            }
+            if (kv.hasValue("enterexit") || (callSiteFlags & NashornCallSiteDescriptor.CALLSITE_TRACE_MISSES) == 0) {
+                callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_ENTEREXIT;
+            }
+            if (kv.hasValue("objects")) {
+                callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_VALUES;
+            }
+            if (kv.hasValue("scope")) {
+                callSiteFlags |= NashornCallSiteDescriptor.CALLSITE_TRACE_SCOPE;
+            }
+        }
+        this._callsite_flags = callSiteFlags;
+
+        final Option<?> option = options.get("timezone");
+        if (option != null) {
+            this._timezone = (TimeZone)option.getValue();
+        } else {
+            this._timezone  = TimeZone.getDefault();
+        }
+
+        this._locale = Locale.getDefault();
+    }
+
+    /**
+     * Get the output stream for this environment
+     * @return output print writer
+     */
+    public PrintWriter getOut() {
+        return out;
+    }
+
+    /**
+     * Get the error stream for this environment
+     * @return error print writer
+     */
+    public PrintWriter getErr() {
+        return err;
+    }
+
+    /**
+     * Get the namespace for this environment
+     * @return namespace
+     */
+    public Namespace getNamespace() {
+        return namespace;
+    }
+
+    /**
+     * Return the JavaScript files passed to the program
+     *
+     * @return a list of files
+     */
+    public List<String> getFiles() {
+        return options.getFiles();
+    }
+
+    /**
+     * Return the user arguments to the program, i.e. those trailing "--" after
+     * the filename
+     *
+     * @return a list of user arguments
+     */
+    public List<String> getArguments() {
+        return options.getArguments();
+    }
+}
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java	Mon Feb 25 16:58:31 2013 +0530
@@ -403,7 +403,7 @@
      * @return JSON string representation of AST of the supplied code
      */
     public static String parse(final String code, final String name, final boolean includeLoc) {
-        return JSONWriter.parse(Context.getContextTrusted(), code, name, includeLoc);
+        return JSONWriter.parse(Context.getContextTrusted().getEnv(), code, name, includeLoc);
     }
 
     /**
--- a/nashorn/src/jdk/nashorn/tools/Shell.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/src/jdk/nashorn/tools/Shell.java	Mon Feb 25 16:58:31 2013 +0530
@@ -45,6 +45,7 @@
 import jdk.nashorn.internal.parser.Parser;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ErrorManager;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
@@ -157,12 +158,13 @@
         }
 
         final ScriptObject global = context.createGlobal();
-        final List<String> files = context.getOptions().getFiles();
+        final ScriptEnvironment env = context.getEnv();
+        final List<String> files = env.getFiles();
         if (files.isEmpty()) {
             return readEvalPrint(context, global);
         }
 
-        if (context._compile_only) {
+        if (env._compile_only) {
             return compileScripts(context, global, files);
         }
 
@@ -237,6 +239,7 @@
     private static int compileScripts(final Context context, final ScriptObject global, final List<String> files) throws IOException {
         final ScriptObject oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
+        final ScriptEnvironment env = context.getEnv();
         try {
             if (globalChanged) {
                 Context.setGlobal(global);
@@ -245,18 +248,18 @@
 
             // For each file on the command line.
             for (final String fileName : files) {
-                final FunctionNode functionNode = new Parser(context, new Source(fileName, new File(fileName)), errors).parse();
+                final FunctionNode functionNode = new Parser(env, new Source(fileName, new File(fileName)), errors).parse();
 
                 if (errors.getNumberOfErrors() != 0) {
                     return COMPILATION_ERROR;
                 }
 
                 //null - pass no code installer - this is compile only
-                new Compiler(context, functionNode).compile();
+                new Compiler(env, functionNode).compile();
             }
         } finally {
-            context.getOut().flush();
-            context.getErr().flush();
+            env.getOut().flush();
+            env.getErr().flush();
             if (globalChanged) {
                 Context.setGlobal(oldGlobal);
             }
@@ -296,7 +299,7 @@
                     apply(script, global);
                 } catch (final NashornException e) {
                     errors.error(e.toString());
-                    if (context._dump_on_error) {
+                    if (context.getEnv()._dump_on_error) {
                         e.printStackTrace(context.getErr());
                     }
 
@@ -341,6 +344,7 @@
         final PrintWriter err = context.getErr();
         final ScriptObject oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
+        final ScriptEnvironment env = context.getEnv();
 
         try {
             if (globalChanged) {
@@ -353,7 +357,7 @@
                 context.eval(global, source.getString(), global, "<shell.js>", false);
             } catch (final Exception e) {
                 err.println(e);
-                if (context._dump_on_error) {
+                if (env._dump_on_error) {
                     e.printStackTrace(err);
                 }
 
@@ -377,10 +381,10 @@
 
                 Object res;
                 try {
-                    res = context.eval(global, source, global, "<shell>", context._strict);
+                    res = context.eval(global, source, global, "<shell>", env._strict);
                 } catch (final Exception e) {
                     err.println(e);
-                    if (context._dump_on_error) {
+                    if (env._dump_on_error) {
                         e.printStackTrace(err);
                     }
                     continue;
--- a/nashorn/test/script/trusted/JDK-8006529.js	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/test/script/trusted/JDK-8006529.js	Mon Feb 25 16:58:31 2013 +0530
@@ -42,6 +42,7 @@
 var Parser         = Java.type("jdk.nashorn.internal.parser.Parser")
 var Compiler       = Java.type("jdk.nashorn.internal.codegen.Compiler")
 var Context        = Java.type("jdk.nashorn.internal.runtime.Context")
+var ScriptEnvironment = Java.type("jdk.nashorn.internal.runtime.ScriptEnvironment")
 var Source         = Java.type("jdk.nashorn.internal.runtime.Source")
 var FunctionNode   = Java.type("jdk.nashorn.internal.ir.FunctionNode")
 
@@ -89,9 +90,9 @@
 // representing it.
 function compile(source) {
     var source   = new Source("<no name>", source);
-    var parser   = new Parser(Context.getContext(), source, null);
+    var parser   = new Parser(Context.getContext().getEnv(), source, null);
     var func     = parseMethod.invoke(parser);
-    var compiler = new Compiler(Context.getContext(), func);
+    var compiler = new Compiler(Context.getContext().getEnv(), func);
 
     compileMethod.invoke(compiler);
 
--- a/nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java	Mon Feb 25 16:58:31 2013 +0530
@@ -154,7 +154,7 @@
                 Context.setGlobal(global);
             }
             final Source   source   = new Source(file.getAbsolutePath(), buffer);
-            new Parser(context, source, errors).parse();
+            new Parser(context.getEnv(), source, errors).parse();
             if (errors.getNumberOfErrors() > 0) {
                 log("Parse failed: " + file.getAbsolutePath());
                 failed++;
--- a/nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java	Fri Feb 22 23:33:46 2013 -0400
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java	Mon Feb 25 16:58:31 2013 +0530
@@ -135,7 +135,7 @@
                     ScriptRuntime.apply(script, global);
                 } catch (final NashornException e) {
                     errors.error(e.toString());
-                    if (context._dump_on_error) {
+                    if (context.getEnv()._dump_on_error) {
                         e.printStackTrace(context.getErr());
                     }