changeset 772:2633cfbd3979

Merge
author lana
date Mon, 24 Mar 2014 13:51:59 -0700
parents 7e89db817ed0 (current diff) c1f528e1d2f2 (diff)
children b6d77b47cf7f
files src/jdk/nashorn/internal/runtime/GlobalObject.java src/jdk/nashorn/internal/runtime/PropertyListener.java src/jdk/nashorn/internal/runtime/PropertyListenerManager.java
diffstat 156 files changed, 5645 insertions(+), 1861 deletions(-) [+]
line wrap: on
line diff
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java	Mon Mar 24 13:51:59 2014 -0700
@@ -50,8 +50,6 @@
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_EMPTY_LIST;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_SETISSHARED;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_SETISSHARED_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE;
@@ -191,8 +189,6 @@
         // stack: Collection
         // pmap = PropertyMap.newMap(Collection<Property>);
         mi.invokeStatic(PROPERTYMAP_TYPE, PROPERTYMAP_NEWMAP, PROPERTYMAP_NEWMAP_DESC);
-        // pmap.setIsShared();
-        mi.invokeVirtual(PROPERTYMAP_TYPE, PROPERTYMAP_SETISSHARED, PROPERTYMAP_SETISSHARED_DESC);
         // $nasgenmap$ = pmap;
         mi.putStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC);
         mi.returnVoid();
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java	Mon Mar 24 13:51:59 2014 -0700
@@ -33,10 +33,7 @@
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC;
@@ -171,9 +168,6 @@
     private void loadMap(final MethodGenerator mi) {
         if (memberCount > 0) {
             mi.getStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC);
-            // make sure we use duplicated PropertyMap so that original map
-            // stays intact and so can be used for many globals.
-            mi.invokeVirtual(PROPERTYMAP_TYPE, PROPERTYMAP_DUPLICATE, PROPERTYMAP_DUPLICATE_DESC);
         }
     }
 
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java	Mon Mar 24 13:51:59 2014 -0700
@@ -279,10 +279,6 @@
                 }
             }
         } else if (kind == Kind.FUNCTION) {
-            final Type returnType = Type.getReturnType(javaDesc);
-            if (! returnType.toString().equals(OBJECT_DESC)) {
-                error("return value should be of Object type, found" + returnType);
-            }
             final Type[] argTypes = Type.getArgumentTypes(javaDesc);
             if (argTypes.length < 1) {
                 error("function methods should have at least 1 arg");
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java	Mon Mar 24 13:51:59 2014 -0700
@@ -349,19 +349,19 @@
 
     // invokes, field get/sets
     void invokeInterface(final String owner, final String method, final String desc) {
-        super.visitMethodInsn(INVOKEINTERFACE, owner, method, desc);
+        super.visitMethodInsn(INVOKEINTERFACE, owner, method, desc, true);
     }
 
     void invokeVirtual(final String owner, final String method, final String desc) {
-        super.visitMethodInsn(INVOKEVIRTUAL, owner, method, desc);
+        super.visitMethodInsn(INVOKEVIRTUAL, owner, method, desc, false);
     }
 
     void invokeSpecial(final String owner, final String method, final String desc) {
-        super.visitMethodInsn(INVOKESPECIAL, owner, method, desc);
+        super.visitMethodInsn(INVOKESPECIAL, owner, method, desc, false);
     }
 
     void invokeStatic(final String owner, final String method, final String desc) {
-        super.visitMethodInsn(INVOKESTATIC, owner, method, desc);
+        super.visitMethodInsn(INVOKESTATIC, owner, method, desc, false);
     }
 
     void putStatic(final String owner, final String field, final String desc) {
@@ -413,7 +413,7 @@
         super.visitMethodInsn(INVOKEVIRTUAL,
                     "java/io/PrintStream",
                     "println",
-                    "(Ljava/lang/String;)V");
+                    "(Ljava/lang/String;)V", false);
     }
 
     // print the object on the top of the stack
@@ -426,6 +426,6 @@
         super.visitMethodInsn(INVOKEVIRTUAL,
                     "java/io/PrintStream",
                     "println",
-                    "(Ljava/lang/Object;)V");
+                    "(Ljava/lang/Object;)V", false);
     }
 }
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java	Mon Mar 24 13:51:59 2014 -0700
@@ -32,10 +32,7 @@
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPE_SUFFIX;
@@ -129,7 +126,6 @@
             mi.getStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC);
             // make sure we use duplicated PropertyMap so that original map
             // stays intact and so can be used for many global.
-            mi.invokeVirtual(PROPERTYMAP_TYPE, PROPERTYMAP_DUPLICATE, PROPERTYMAP_DUPLICATE_DESC);
             mi.invokeSpecial(PROTOTYPEOBJECT_TYPE, INIT, SCRIPTOBJECT_INIT_DESC);
             // initialize Function type fields
             initFunctionFields(mi);
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java	Mon Mar 24 13:51:59 2014 -0700
@@ -146,16 +146,16 @@
                 // call $clinit$ just before return from <clinit>
                 if (isStaticInit && opcode == RETURN) {
                     super.visitMethodInsn(INVOKESTATIC, scriptClassInfo.getJavaName(),
-                            $CLINIT$, DEFAULT_INIT_DESC);
+                            $CLINIT$, DEFAULT_INIT_DESC, false);
                 }
                 super.visitInsn(opcode);
             }
 
             @Override
-            public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) {
+            public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc, final boolean itf) {
                 if (isConstructor && opcode == INVOKESPECIAL &&
                         INIT.equals(name) && SCRIPTOBJECT_TYPE.equals(owner)) {
-                    super.visitMethodInsn(opcode, owner, name, desc);
+                    super.visitMethodInsn(opcode, owner, name, desc, false);
 
                     if (memberCount > 0) {
                         // initialize @Property fields if needed
@@ -166,7 +166,7 @@
                                 super.visitTypeInsn(NEW, clazz);
                                 super.visitInsn(DUP);
                                 super.visitMethodInsn(INVOKESPECIAL, clazz,
-                                    INIT, DEFAULT_INIT_DESC);
+                                    INIT, DEFAULT_INIT_DESC, false);
                                 super.visitFieldInsn(PUTFIELD, scriptClassInfo.getJavaName(),
                                     memInfo.getJavaName(), memInfo.getJavaDesc());
                             }
@@ -180,7 +180,7 @@
                         }
                     }
                 } else {
-                    super.visitMethodInsn(opcode, owner, name, desc);
+                    super.visitMethodInsn(opcode, owner, name, desc, itf);
                 }
             }
 
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java	Mon Mar 24 13:51:59 2014 -0700
@@ -45,11 +45,9 @@
 @SuppressWarnings("javadoc")
 public interface StringConstants {
     // standard jdk types, methods
-    static final Type TYPE_METHOD             = Type.getType(Method.class);
     static final Type TYPE_METHODHANDLE       = Type.getType(MethodHandle.class);
     static final Type TYPE_METHODHANDLE_ARRAY = Type.getType(MethodHandle[].class);
     static final Type TYPE_OBJECT             = Type.getType(Object.class);
-    static final Type TYPE_CLASS              = Type.getType(Class.class);
     static final Type TYPE_STRING             = Type.getType(String.class);
     static final Type TYPE_COLLECTION         = Type.getType(Collection.class);
     static final Type TYPE_COLLECTIONS        = Type.getType(Collections.class);
@@ -104,10 +102,6 @@
     static final String PROPERTYMAP_DESC = TYPE_PROPERTYMAP.getDescriptor();
     static final String PROPERTYMAP_NEWMAP = "newMap";
     static final String PROPERTYMAP_NEWMAP_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP, TYPE_COLLECTION);
-    static final String PROPERTYMAP_DUPLICATE = "duplicate";
-    static final String PROPERTYMAP_DUPLICATE_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP);
-    static final String PROPERTYMAP_SETISSHARED = "setIsShared";
-    static final String PROPERTYMAP_SETISSHARED_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP);
 
     // PrototypeObject
     static final String PROTOTYPEOBJECT_TYPE = TYPE_PROTOTYPEOBJECT.getInternalName();
--- a/make/BuildNashorn.gmk	Mon Mar 24 13:16:11 2014 -0700
+++ b/make/BuildNashorn.gmk	Mon Mar 24 13:51:59 2014 -0700
@@ -77,7 +77,7 @@
 	$(RM) -rf $(@D)/jdk $(@D)/netscape
 	$(CP) -R -p $(NASHORN_OUTPUTDIR)/nashorn_classes/* $(@D)/
 	$(FIXPATH) $(JAVA) \
-	    -cp "$(NASHORN_OUTPUTDIR)/nasgen_classes$(PATH_SEP)$(NASHORN_OUTPUTDIR)/nashorn_classes" \
+	    -Xbootclasspath/p:"$(NASHORN_OUTPUTDIR)/nasgen_classes$(PATH_SEP)$(NASHORN_OUTPUTDIR)/nashorn_classes" \
 	    jdk.nashorn.internal.tools.nasgen.Main $(@D) jdk.nashorn.internal.objects $(@D)
 	$(TOUCH) $@
 
--- a/make/build.xml	Mon Mar 24 13:16:11 2014 -0700
+++ b/make/build.xml	Mon Mar 24 13:51:59 2014 -0700
@@ -122,6 +122,7 @@
       <compilerarg value="-Xlint:unchecked"/>
       <compilerarg value="-Xlint:deprecation"/>
       <compilerarg value="-XDignore.symbol.file"/>
+      <compilerarg value="-Xdiags:verbose"/>
     </javac>
     <copy todir="${build.classes.dir}/META-INF/services">
        <fileset dir="${meta.inf.dir}/services/"/>
@@ -240,6 +241,7 @@
         <compilerarg value="-J-Djava.ext.dirs="/>
         <compilerarg value="-Xlint:unchecked"/>
         <compilerarg value="-Xlint:deprecation"/>
+        <compilerarg value="-Xdiags:verbose"/>
     </javac>
 
     <copy todir="${build.test.classes.dir}/META-INF/services">
@@ -250,6 +252,10 @@
        <fileset dir="${test.src.dir}/jdk/nashorn/internal/runtime/resources"/>
     </copy>
 
+    <copy todir="${build.test.classes.dir}/jdk/nashorn/api/scripting/resources">
+       <fileset dir="${test.src.dir}/jdk/nashorn/api/scripting/resources"/>
+    </copy>
+
     <!-- tests that check nashorn internals and internal API -->
     <jar jarfile="${nashorn.internal.tests.jar}">
       <fileset dir="${build.test.classes.dir}" excludes="**/api/**"/>
@@ -279,6 +285,11 @@
     permission java.security.AllPermission;
 };
 
+grant codeBase "file:/${basedir}/test/script/maptests/*" {
+    permission java.io.FilePermission "${basedir}/test/script/maptests/*","read";
+    permission java.lang.RuntimePermission "nashorn.debugMode";
+};
+
 grant codeBase "file:/${basedir}/test/script/basic/*" {
     permission java.io.FilePermission "${basedir}/test/script/-", "read";
     permission java.io.FilePermission "$${user.dir}", "read";
--- a/make/project.properties	Mon Mar 24 13:16:11 2014 -0700
+++ b/make/project.properties	Mon Mar 24 13:51:59 2014 -0700
@@ -112,6 +112,7 @@
 test.dir=test
 test.script.dir=test/script
 test.basic.dir=test/script/basic
+test.maptests.dir=test/script/maptests
 test.error.dir=test/script/error
 test.sandbox.dir=test/script/sandbox
 test.trusted.dir=test/script/trusted
@@ -121,7 +122,7 @@
 testjfx.dir=${test.script.dir}/jfx
 
 test-sys-prop.test.dir=${test.dir}
-test-sys-prop.test.js.roots=${test.basic.dir} ${test.error.dir} ${test.sandbox.dir} ${test.trusted.dir}
+test-sys-prop.test.js.roots=${test.basic.dir} ${test.maptests.dir} ${test.error.dir} ${test.sandbox.dir} ${test.trusted.dir}
 test-sys-prop.test262.suite.dir=${test262.suite.dir}
 test-sys-prop.es5conform.testcases.dir=${test.external.dir}/ES5Conform/TestCases
 test-sys-prop.test.basic.dir=${test.basic.dir}
@@ -201,7 +202,7 @@
 
 # test262 test frameworks
 test262-test-sys-prop.test.js.framework=\
-    --class-cache-size=0 \
+    --class-cache-size=10 \
     --no-java \
     --no-typed-arrays \
     -timezone=PST \
@@ -264,7 +265,7 @@
 run.test.jvmsecurityargs=-Xverify:all -Djava.security.manager -Djava.security.policy=${basedir}/build/nashorn.policy
 
 # VM options for script tests with @fork option
-test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs}
+test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} -cp ${run.test.classpath}
 
 # path of rhino.jar for benchmarks
 rhino.jar=
--- a/src/jdk/nashorn/api/scripting/NashornException.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/api/scripting/NashornException.java	Mon Mar 24 13:51:59 2014 -0700
@@ -29,6 +29,7 @@
 import java.util.List;
 import jdk.nashorn.internal.codegen.CompilerConstants;
 import jdk.nashorn.internal.runtime.ECMAErrors;
+import jdk.nashorn.internal.runtime.ScriptObject;
 
 /**
  * This is base exception for all Nashorn exceptions. These originate from
@@ -44,11 +45,13 @@
 @SuppressWarnings("serial")
 public abstract class NashornException extends RuntimeException {
     // script file name
-    private final String fileName;
+    private String fileName;
     // script line number
-    private final int line;
+    private int line;
     // script column number
-    private final int column;
+    private int column;
+    // underlying ECMA error object - lazily initialized
+    private Object ecmaError;
 
     /** script source name used for "engine.js" */
     public static final String ENGINE_SCRIPT_SOURCE_NAME = "nashorn:engine/resources/engine.js";
@@ -122,6 +125,15 @@
     }
 
     /**
+     * Set the source file name for this {@code NashornException}
+     *
+     * @param fileName the file name
+     */
+    public final void setFileName(final String fileName) {
+        this.fileName = fileName;
+    }
+
+    /**
      * Get the line number for this {@code NashornException}
      *
      * @return the line number
@@ -131,15 +143,33 @@
     }
 
     /**
+     * Set the line number for this {@code NashornException}
+     *
+     * @param line the line number
+     */
+    public final void setLineNumber(final int line) {
+        this.line = line;
+    }
+
+    /**
      * Get the column for this {@code NashornException}
      *
-     * @return the column
+     * @return the column number
      */
     public final int getColumnNumber() {
         return column;
     }
 
     /**
+     * Set the column for this {@code NashornException}
+     *
+     * @param column the column number
+     */
+    public final void setColumnNumber(final int column) {
+        this.column = column;
+    }
+
+    /**
      * Returns array javascript stack frames from the given exception object.
      *
      * @param exception exception from which stack frames are retrieved and filtered
@@ -155,6 +185,11 @@
                 if (methodName.equals(CompilerConstants.RUN_SCRIPT.symbolName())) {
                     methodName = "<program>";
                 }
+
+                if (methodName.contains(CompilerConstants.ANON_FUNCTION_PREFIX.symbolName())) {
+                    methodName = "<anonymous>";
+                }
+
                 filtered.add(new StackTraceElement(className, methodName,
                         st.getFileName(), st.getLineNumber()));
             }
@@ -188,4 +223,43 @@
         }
         return buf.toString();
     }
+
+    protected Object getThrown() {
+        return null;
+    }
+
+    protected NashornException initEcmaError(final ScriptObject global) {
+        if (ecmaError != null) {
+            return this; // initialized already!
+        }
+
+        final Object thrown = getThrown();
+        if (thrown instanceof ScriptObject) {
+            setEcmaError(ScriptObjectMirror.wrap(thrown, global));
+        } else {
+            setEcmaError(thrown);
+        }
+
+        return this;
+    }
+
+    /**
+     * Return the underlying ECMA error object, if available.
+     *
+     * @return underlying ECMA Error object's mirror or whatever was thrown
+     *         from script such as a String, Number or a Boolean.
+     */
+    public Object getEcmaError() {
+        return ecmaError;
+    }
+
+    /**
+     * Return the underlying ECMA error object, if available.
+     *
+     * @param ecmaError underlying ECMA Error object's mirror or whatever was thrown
+     *         from script such as a String, Number or a Boolean.
+     */
+    public void setEcmaError(final Object ecmaError) {
+        this.ecmaError = ecmaError;
+    }
 }
--- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java	Mon Mar 24 13:51:59 2014 -0700
@@ -57,9 +57,9 @@
 import javax.script.ScriptEngineFactory;
 import javax.script.ScriptException;
 import javax.script.SimpleBindings;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ErrorManager;
-import jdk.nashorn.internal.runtime.GlobalObject;
 import jdk.nashorn.internal.runtime.Property;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
@@ -99,7 +99,7 @@
     private final boolean             _global_per_engine;
     // This is the initial default Nashorn global object.
     // This is used as "shared" global if above option is true.
-    private final ScriptObject        global;
+    private final Global              global;
     // initialized bit late to be made 'final'.
     // Property object for "context" property of global object.
     private volatile Property         contextProperty;
@@ -264,7 +264,7 @@
     public Object __noSuchProperty__(final Object self, final ScriptContext ctxt, final String name) {
         if (ctxt != null) {
             final int scope = ctxt.getAttributesScope(name);
-            final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt);
+            final Global ctxtGlobal = getNashornGlobalFrom(ctxt);
             if (scope != -1) {
                 return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), ctxtGlobal);
             }
@@ -317,7 +317,7 @@
         }
 
         ScriptObject realSelf = null;
-        ScriptObject realGlobal = null;
+        Global realGlobal = null;
         if(thiz == null) {
             // making interface out of global functions
             realSelf = realGlobal = getNashornGlobalFrom(context);
@@ -346,7 +346,7 @@
         }
 
         try {
-            final ScriptObject oldGlobal = Context.getGlobal();
+            final Global oldGlobal = Context.getGlobal();
             final boolean globalChanged = (oldGlobal != realGlobal);
             try {
                 if (globalChanged) {
@@ -371,7 +371,7 @@
     }
 
     // Retrieve nashorn Global object for a given ScriptContext object
-    private ScriptObject getNashornGlobalFrom(final ScriptContext ctxt) {
+    private Global getNashornGlobalFrom(final ScriptContext ctxt) {
         if (_global_per_engine) {
             // shared single global object for all ENGINE_SCOPE Bindings
             return global;
@@ -380,18 +380,18 @@
         final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE);
         // is this Nashorn's own Bindings implementation?
         if (bindings instanceof ScriptObjectMirror) {
-            final ScriptObject sobj = globalFromMirror((ScriptObjectMirror)bindings);
-            if (sobj != null) {
-                return sobj;
+            final Global glob = globalFromMirror((ScriptObjectMirror)bindings);
+            if (glob != null) {
+                return glob;
             }
         }
 
         // Arbitrary user Bindings implementation. Look for NASHORN_GLOBAL in it!
         Object scope = bindings.get(NASHORN_GLOBAL);
         if (scope instanceof ScriptObjectMirror) {
-            final ScriptObject sobj = globalFromMirror((ScriptObjectMirror)scope);
-            if (sobj != null) {
-                return sobj;
+            final Global glob = globalFromMirror((ScriptObjectMirror)scope);
+            if (glob != null) {
+                return glob;
             }
         }
 
@@ -399,14 +399,14 @@
         // Create new global instance mirror and associate with the Bindings.
         final ScriptObjectMirror mirror = createGlobalMirror(ctxt);
         bindings.put(NASHORN_GLOBAL, mirror);
-        return mirror.getScriptObject();
+        return mirror.getHomeGlobal();
     }
 
     // Retrieve nashorn Global object from a given ScriptObjectMirror
-    private ScriptObject globalFromMirror(final ScriptObjectMirror mirror) {
+    private Global globalFromMirror(final ScriptObjectMirror mirror) {
         ScriptObject sobj = mirror.getScriptObject();
-        if (sobj instanceof GlobalObject && isOfContext(sobj, nashornContext)) {
-            return sobj;
+        if (sobj instanceof Global && isOfContext((Global)sobj, nashornContext)) {
+            return (Global)sobj;
         }
 
         return null;
@@ -414,15 +414,15 @@
 
     // Create a new ScriptObjectMirror wrapping a newly created Nashorn Global object
     private ScriptObjectMirror createGlobalMirror(final ScriptContext ctxt) {
-        final ScriptObject newGlobal = createNashornGlobal(ctxt);
+        final Global newGlobal = createNashornGlobal(ctxt);
         return new ScriptObjectMirror(newGlobal, newGlobal);
     }
 
     // Create a new Nashorn Global object
-    private ScriptObject createNashornGlobal(final ScriptContext ctxt) {
-        final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction<ScriptObject>() {
+    private Global createNashornGlobal(final ScriptContext ctxt) {
+        final Global newGlobal = AccessController.doPrivileged(new PrivilegedAction<Global>() {
             @Override
-            public ScriptObject run() {
+            public Global run() {
                 try {
                     return nashornContext.newGlobal();
                 } catch (final RuntimeException e) {
@@ -460,7 +460,7 @@
     }
 
     // scripts should see "context" and "engine" as variables in the given global object
-    private void setContextVariables(final ScriptObject ctxtGlobal, final ScriptContext ctxt) {
+    private void setContextVariables(final Global ctxtGlobal, final ScriptContext ctxt) {
         // set "context" global variable via contextProperty - because this
         // property is non-writable
         contextProperty.setObjectValue(ctxtGlobal, ctxtGlobal, ctxt, false);
@@ -470,7 +470,7 @@
         }
         // if no arguments passed, expose it
         if (! (args instanceof ScriptObject)) {
-            args = ((GlobalObject)ctxtGlobal).wrapAsObject(args);
+            args = ctxtGlobal.wrapAsObject(args);
             ctxtGlobal.set("arguments", args, false);
         }
     }
@@ -478,16 +478,19 @@
     private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
         name.getClass(); // null check
 
+        Global invokeGlobal = null;
         ScriptObjectMirror selfMirror = null;
         if (selfObject instanceof ScriptObjectMirror) {
             selfMirror = (ScriptObjectMirror)selfObject;
             if (! isOfContext(selfMirror.getHomeGlobal(), nashornContext)) {
                 throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
             }
+            invokeGlobal = selfMirror.getHomeGlobal();
         } else if (selfObject instanceof ScriptObject) {
             // invokeMethod called from script code - in which case we may get 'naked' ScriptObject
             // Wrap it with oldGlobal to make a ScriptObjectMirror for the same.
-            final ScriptObject oldGlobal = Context.getGlobal();
+            final Global oldGlobal = Context.getGlobal();
+            invokeGlobal = oldGlobal;
             if (oldGlobal == null) {
                 throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
             }
@@ -499,7 +502,8 @@
             selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(selfObject, oldGlobal);
         } else if (selfObject == null) {
             // selfObject is null => global function call
-            final ScriptObject ctxtGlobal = getNashornGlobalFrom(context);
+            final Global ctxtGlobal = getNashornGlobalFrom(context);
+            invokeGlobal = ctxtGlobal;
             selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(ctxtGlobal, ctxtGlobal);
         }
 
@@ -511,7 +515,7 @@
                 if (cause instanceof NoSuchMethodException) {
                     throw (NoSuchMethodException)cause;
                 }
-                throwAsScriptException(e);
+                throwAsScriptException(e, invokeGlobal);
                 throw new AssertionError("should not reach here");
             }
         }
@@ -528,11 +532,11 @@
         return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt));
     }
 
-    private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final ScriptObject ctxtGlobal) throws ScriptException {
+    private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
         if (script == null) {
             return null;
         }
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != ctxtGlobal);
         try {
             if (globalChanged) {
@@ -545,7 +549,7 @@
             }
             return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal));
         } catch (final Exception e) {
-            throwAsScriptException(e);
+            throwAsScriptException(e, ctxtGlobal);
             throw new AssertionError("should not reach here");
         } finally {
             if (globalChanged) {
@@ -554,7 +558,7 @@
         }
     }
 
-    private static void throwAsScriptException(final Exception e) throws ScriptException {
+    private static void throwAsScriptException(final Exception e, final Global global) throws ScriptException {
         if (e instanceof ScriptException) {
             throw (ScriptException)e;
         } else if (e instanceof NashornException) {
@@ -562,6 +566,7 @@
             final ScriptException se = new ScriptException(
                 ne.getMessage(), ne.getFileName(),
                 ne.getLineNumber(), ne.getColumnNumber());
+            ne.initEcmaError(global);
             se.initCause(e);
             throw se;
         } else if (e instanceof RuntimeException) {
@@ -577,7 +582,7 @@
         return new CompiledScript() {
             @Override
             public Object eval(final ScriptContext ctxt) throws ScriptException {
-                final ScriptObject globalObject = getNashornGlobalFrom(ctxt);
+                final Global globalObject = getNashornGlobalFrom(ctxt);
                 // Are we running the script in the correct global?
                 if (func.getScope() == globalObject) {
                     return evalImpl(func, ctxt, globalObject);
@@ -597,8 +602,8 @@
         return compileImpl(source, getNashornGlobalFrom(ctxt));
     }
 
-    private ScriptFunction compileImpl(final Source source, final ScriptObject newGlobal) throws ScriptException {
-        final ScriptObject oldGlobal = Context.getGlobal();
+    private ScriptFunction compileImpl(final Source source, final Global newGlobal) throws ScriptException {
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != newGlobal);
         try {
             if (globalChanged) {
@@ -607,7 +612,7 @@
 
             return nashornContext.compileScript(source, newGlobal);
         } catch (final Exception e) {
-            throwAsScriptException(e);
+            throwAsScriptException(e, newGlobal);
             throw new AssertionError("should not reach here");
         } finally {
             if (globalChanged) {
@@ -623,6 +628,11 @@
                 continue;
             }
 
+            // skip check for default methods - non-abstract, interface methods
+            if (! Modifier.isAbstract(method.getModifiers())) {
+                continue;
+            }
+
             Object obj = sobj.get(method.getName());
             if (! (obj instanceof ScriptFunction)) {
                 return false;
@@ -631,8 +641,7 @@
         return true;
     }
 
-    private static boolean isOfContext(final ScriptObject global, final Context context) {
-        assert global instanceof GlobalObject: "Not a Global object";
-        return ((GlobalObject)global).isOfContext(context);
+    private static boolean isOfContext(final Global global, final Context context) {
+        return global.isOfContext(context);
     }
 }
--- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java	Mon Mar 24 13:51:59 2014 -0700
@@ -25,6 +25,7 @@
 
 package jdk.nashorn.api.scripting;
 
+import java.nio.ByteBuffer;
 import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.Permissions;
@@ -41,9 +42,10 @@
 import java.util.Set;
 import java.util.concurrent.Callable;
 import javax.script.Bindings;
+import jdk.nashorn.internal.objects.Global;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
 import jdk.nashorn.internal.runtime.ConsString;
 import jdk.nashorn.internal.runtime.Context;
-import jdk.nashorn.internal.runtime.GlobalObject;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
@@ -62,7 +64,7 @@
     private static final AccessControlContext GET_CONTEXT_ACC_CTXT = getContextAccCtxt();
 
     private final ScriptObject sobj;
-    private final ScriptObject global;
+    private final Global  global;
     private final boolean strict;
 
     @Override
@@ -93,7 +95,7 @@
 
     @Override
     public Object call(final Object thiz, final Object... args) {
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
 
         try {
@@ -108,6 +110,8 @@
             }
 
             throw new RuntimeException("not a function: " + toString());
+        } catch (final NashornException ne) {
+            throw ne.initEcmaError(global);
         } catch (final RuntimeException | Error e) {
             throw e;
         } catch (final Throwable t) {
@@ -121,7 +125,7 @@
 
     @Override
     public Object newObject(final Object... args) {
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
 
         try {
@@ -135,6 +139,8 @@
             }
 
             throw new RuntimeException("not a constructor: " + toString());
+        } catch (final NashornException ne) {
+            throw ne.initEcmaError(global);
         } catch (final RuntimeException | Error e) {
             throw e;
         } catch (final Throwable t) {
@@ -165,7 +171,7 @@
 
     public Object callMember(final String functionName, final Object... args) {
         functionName.getClass(); // null check
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
 
         try {
@@ -182,6 +188,8 @@
             }
 
             throw new NoSuchMethodException("No such function " + functionName);
+        } catch (final NashornException ne) {
+            throw ne.initEcmaError(global);
         } catch (final RuntimeException | Error e) {
             throw e;
         } catch (final Throwable t) {
@@ -253,6 +261,22 @@
         });
     }
 
+    /**
+     * Nashorn extension: setIndexedPropertiesToExternalArrayData.
+     * set indexed properties be exposed from a given nio ByteBuffer.
+     *
+     * @param buf external buffer - should be a nio ByteBuffer
+     */
+    public void setIndexedPropertiesToExternalArrayData(final ByteBuffer buf) {
+        inGlobal(new Callable<Void>() {
+            @Override public Void call() {
+                sobj.setArray(ArrayData.allocate(buf));
+                return null;
+            }
+        });
+    }
+
+
     @Override
     public boolean isInstance(final Object obj) {
         if (! (obj instanceof ScriptObjectMirror)) {
@@ -618,7 +642,7 @@
      */
     public static Object wrap(final Object obj, final Object homeGlobal) {
         if(obj instanceof ScriptObject) {
-            return homeGlobal instanceof ScriptObject ? new ScriptObjectMirror((ScriptObject)obj, (ScriptObject)homeGlobal) : obj;
+            return homeGlobal instanceof Global ? new ScriptObjectMirror((ScriptObject)obj, (Global)homeGlobal) : obj;
         }
         if(obj instanceof ConsString) {
             return obj.toString();
@@ -686,13 +710,13 @@
 
     // package-privates below this.
 
-    ScriptObjectMirror(final ScriptObject sobj, final ScriptObject global) {
+    ScriptObjectMirror(final ScriptObject sobj, final Global global) {
         assert sobj != null : "ScriptObjectMirror on null!";
-        assert global instanceof GlobalObject : "global is not a GlobalObject";
+        assert global != null : "home Global is null";
 
         this.sobj = sobj;
         this.global = global;
-        this.strict = ((GlobalObject)global).isStrictContext();
+        this.strict = global.isStrictContext();
     }
 
     // accessors for script engine
@@ -700,7 +724,7 @@
         return sobj;
     }
 
-    ScriptObject getHomeGlobal() {
+    Global getHomeGlobal() {
         return global;
     }
 
@@ -710,13 +734,15 @@
 
     // internals only below this.
     private <V> V inGlobal(final Callable<V> callable) {
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
         if (globalChanged) {
             Context.setGlobal(global);
         }
         try {
             return callable.call();
+        } catch (final NashornException ne) {
+            throw ne.initEcmaError(global);
         } catch (final RuntimeException e) {
             throw e;
         } catch (final Exception e) {
--- a/src/jdk/nashorn/internal/codegen/Attr.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/codegen/Attr.java	Mon Mar 24 13:51:59 2014 -0700
@@ -375,10 +375,11 @@
      * @return Symbol for given name or null for redefinition.
      */
     private Symbol defineSymbol(final Block block, final String name, final int symbolFlags) {
-        int    flags  = symbolFlags;
-        Symbol symbol = findSymbol(block, name); // Locate symbol.
+        int     flags    = symbolFlags;
+        Symbol  symbol   = findSymbol(block, name); // Locate symbol.
+        boolean isGlobal = (flags & KINDMASK) == IS_GLOBAL;
 
-        if ((flags & KINDMASK) == IS_GLOBAL) {
+        if (isGlobal) {
             flags |= IS_SCOPE;
         }
 
@@ -414,6 +415,8 @@
             // Determine where to create it.
             if ((flags & Symbol.KINDMASK) == IS_VAR && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) {
                 symbolBlock = block; //internal vars are always defined in the block closest to them
+            } else if (isGlobal) {
+                symbolBlock = lc.getOutermostFunction().getBody();
             } else {
                 symbolBlock = lc.getFunctionBody(function);
             }
--- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Mon Mar 24 13:51:59 2014 -0700
@@ -685,7 +685,7 @@
             private void scopeCall(final IdentNode node, final int flags) {
                 load(node, Type.OBJECT); // Type.OBJECT as foo() makes no sense if foo == 3
                 // ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
-                method.loadNull(); //the 'this'
+                method.loadUndefined(Type.OBJECT); //the 'this' object
                 method.dynamicCall(callNodeType, 2 + loadArgs(args), flags);
             }
 
@@ -818,7 +818,7 @@
             protected boolean enterDefault(final Node node) {
                 // Load up function.
                 load(function, Type.OBJECT); //TODO, e.g. booleans can be used as functions
-                method.loadNull(); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE
+                method.loadUndefined(Type.OBJECT); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE
                 method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags() | CALLSITE_SCOPE);
 
                 return false;
@@ -2023,8 +2023,6 @@
             return false;
         }
 
-        method._new(ECMAException.class).dup();
-
         final Source source     = lc.getCurrentFunction().getSource();
 
         final Expression expression = throwNode.getExpression();
@@ -2037,7 +2035,7 @@
         method.load(source.getName());
         method.load(line);
         method.load(column);
-        method.invoke(ECMAException.THROW_INIT);
+        method.invoke(ECMAException.CREATE);
 
         method.athrow();
 
--- a/src/jdk/nashorn/internal/codegen/CodeGeneratorLexicalContext.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/codegen/CodeGeneratorLexicalContext.java	Mon Mar 24 13:51:59 2014 -0700
@@ -158,7 +158,7 @@
         if (scopeCalls.containsKey(scopeCall)) {
             return scopeCalls.get(scopeCall);
         }
-        scopeCall.setClassAndName(unit, getCurrentFunction().uniqueName("scopeCall"));
+        scopeCall.setClassAndName(unit, getCurrentFunction().uniqueName(":scopeCall"));
         scopeCalls.put(scopeCall, scopeCall);
         return scopeCall;
     }
@@ -177,7 +177,7 @@
         if (scopeCalls.containsKey(scopeCall)) {
             return scopeCalls.get(scopeCall);
         }
-        scopeCall.setClassAndName(unit, getCurrentFunction().uniqueName("scopeCall"));
+        scopeCall.setClassAndName(unit, getCurrentFunction().uniqueName(":scopeCall"));
         scopeCalls.put(scopeCall, scopeCall);
         return scopeCall;
     }
--- a/src/jdk/nashorn/internal/codegen/Compiler.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/codegen/Compiler.java	Mon Mar 24 13:51:59 2014 -0700
@@ -85,6 +85,8 @@
 
     private Source source;
 
+    private String sourceName;
+
     private final Map<String, byte[]> bytecode;
 
     private final Set<CompileUnit> compileUnits;
@@ -267,6 +269,7 @@
                 append('$').
                 append(safeSourceName(functionNode.getSource()));
         this.source = functionNode.getSource();
+        this.sourceName = functionNode.getSourceName();
         this.scriptName = sb.toString();
     }
 
@@ -573,7 +576,7 @@
     }
 
     private CompileUnit initCompileUnit(final String unitClassName, final long initialWeight) {
-        final ClassEmitter classEmitter = new ClassEmitter(env, source.getName(), unitClassName, strict);
+        final ClassEmitter classEmitter = new ClassEmitter(env, sourceName, unitClassName, strict);
         final CompileUnit  compileUnit  = new CompileUnit(unitClassName, classEmitter, initialWeight);
 
         classEmitter.begin();
--- a/src/jdk/nashorn/internal/codegen/CompilerConstants.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/codegen/CompilerConstants.java	Mon Mar 24 13:51:59 2014 -0700
@@ -41,6 +41,7 @@
  */
 
 public enum CompilerConstants {
+
     /** the __FILE__ variable */
     __FILE__,
 
@@ -75,7 +76,7 @@
     DEFAULT_SCRIPT_NAME("Script"),
 
     /** function prefix for anonymous functions */
-    FUNCTION_PREFIX("function$"),
+    ANON_FUNCTION_PREFIX("L:"),
 
     /** method name for Java method that is script entry point */
     RUN_SCRIPT("runScript"),
@@ -149,26 +150,31 @@
     ALLOCATE("allocate"),
 
     /** prefix for split methods, @see Splitter */
-    SPLIT_PREFIX("$split"),
+    SPLIT_PREFIX(":split"),
 
     /** prefix for split array method and slot */
-    SPLIT_ARRAY_ARG("split_array", 3),
+    SPLIT_ARRAY_ARG(":split_array", 3),
 
     /** get string from constant pool */
-    GET_STRING("$getString"),
+    GET_STRING(":getString"),
 
     /** get map */
-    GET_MAP("$getMap"),
+    GET_MAP(":getMap"),
 
     /** get map */
-    SET_MAP("$setMap"),
+    SET_MAP(":setMap"),
 
     /** get array prefix */
-    GET_ARRAY_PREFIX("$get"),
+    GET_ARRAY_PREFIX(":get"),
 
     /** get array suffix */
     GET_ARRAY_SUFFIX("$array");
 
+    /**
+     * Prefix used for internal methods generated in script clases.
+     */
+    public static final String INTERNAL_METHOD_PREFIX = ":";
+
     private final String symbolName;
     private final Class<?> type;
     private final int slot;
--- a/src/jdk/nashorn/internal/codegen/ConstantData.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/codegen/ConstantData.java	Mon Mar 24 13:51:59 2014 -0700
@@ -25,6 +25,9 @@
 
 package jdk.nashorn.internal.codegen;
 
+import jdk.nashorn.internal.runtime.Property;
+import jdk.nashorn.internal.runtime.PropertyMap;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -110,6 +113,43 @@
     }
 
     /**
+     * {@link PropertyMap} wrapper class that provides implementations for the {@code hashCode} and {@code equals}
+     * methods that are based on the map layout. {@code PropertyMap} itself inherits the identity based implementations
+     * from {@code java.lang.Object}.
+     */
+    private static class PropertyMapWrapper {
+        private final PropertyMap propertyMap;
+        private final int hashCode;
+
+        public PropertyMapWrapper(final PropertyMap map) {
+            int hash = 0;
+            for (final Property property : map.getProperties()) {
+                hash = hash << 7 ^ hash >> 7;
+                hash ^= property.hashCode();
+            }
+            this.hashCode = hash;
+            this.propertyMap = map;
+        }
+
+        @Override
+        public int hashCode() {
+            return hashCode;
+        }
+
+        @Override
+        public boolean equals(final Object other) {
+            if (!(other instanceof PropertyMapWrapper)) {
+                return false;
+            }
+
+            final Property[] ownProperties = propertyMap.getProperties();
+            final Property[] otherProperties = ((PropertyMapWrapper) other).propertyMap.getProperties();
+
+            return Arrays.equals(ownProperties, otherProperties);
+        }
+    }
+
+    /**
      * Constructor
      */
     ConstantData() {
@@ -145,7 +185,14 @@
      * @return the index in the constant pool that the object was given
      */
     public int add(final Object object) {
-        final Object  entry = object.getClass().isArray() ? new ArrayWrapper(object) : object;
+        final Object  entry;
+        if (object.getClass().isArray()) {
+            entry = new ArrayWrapper(object);
+        } else if (object instanceof PropertyMap) {
+            entry = new PropertyMapWrapper((PropertyMap) object);
+        } else {
+            entry = object;
+        }
         final Integer value = objectMap.get(entry);
 
         if (value != null) {
--- a/src/jdk/nashorn/internal/codegen/MethodEmitter.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/codegen/MethodEmitter.java	Mon Mar 24 13:51:59 2014 -0700
@@ -1130,7 +1130,11 @@
             popType(Type.OBJECT);
         }
 
-        method.visitMethodInsn(opcode, className, methodName, methodDescriptor);
+        if (opcode == INVOKEINTERFACE) {
+            method.visitMethodInsn(opcode, className, methodName, methodDescriptor, true);
+        } else {
+            method.visitMethodInsn(opcode, className, methodName, methodDescriptor, false);
+        }
 
         if (returnType != null) {
             pushType(returnType);
--- a/src/jdk/nashorn/internal/codegen/SharedScopeCall.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/codegen/SharedScopeCall.java	Mon Mar 24 13:51:59 2014 -0700
@@ -156,7 +156,7 @@
         if (isCall) {
             method.convert(Type.OBJECT);
             // ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
-            method.loadNull();
+            method.loadUndefined(Type.OBJECT);
             int slot = 2;
             for (final Type type : paramTypes) {
                 method.load(type, slot++);
--- a/src/jdk/nashorn/internal/codegen/types/Type.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/codegen/types/Type.java	Mon Mar 24 13:51:59 2014 -0700
@@ -261,7 +261,7 @@
     }
 
     static void invokeStatic(final MethodVisitor method, final Call call) {
-        method.visitMethodInsn(INVOKESTATIC, call.className(), call.name(), call.descriptor());
+        method.visitMethodInsn(INVOKESTATIC, call.className(), call.name(), call.descriptor(), false);
     }
 
     /**
--- a/src/jdk/nashorn/internal/ir/FunctionNode.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/ir/FunctionNode.java	Mon Mar 24 13:51:59 2014 -0700
@@ -29,6 +29,7 @@
 import java.util.EnumSet;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 import jdk.nashorn.internal.codegen.CompileUnit;
 import jdk.nashorn.internal.codegen.Compiler;
@@ -138,6 +139,9 @@
     /** Function flags. */
     private final int flags;
 
+    /** //@ sourceURL or //# sourceURL for program function nodes */
+    private final String sourceURL;
+
     private final int lineNumber;
 
     /** Is anonymous function flag. */
@@ -160,11 +164,11 @@
     public static final int HAS_EVAL                    = 1 << 5;
 
     /** Does a nested function contain eval? If it does, then all variables in this function might be get/set by it. */
-    public static final int HAS_NESTED_EVAL = 1 << 6;
+    public static final int HAS_NESTED_EVAL             = 1 << 6;
 
     /** Does this function have any blocks that create a scope? This is used to determine if the function needs to
      * have a local variable slot for the scope symbol. */
-    public static final int HAS_SCOPE_BLOCK = 1 << 7;
+    public static final int HAS_SCOPE_BLOCK             = 1 << 7;
 
     /**
      * Flag this function as one that defines the identifier "arguments" as a function parameter or nested function
@@ -193,6 +197,9 @@
     /** Can this function be specialized? */
     public static final int CAN_SPECIALIZE              = 1 << 14;
 
+    /** Does this function use the "this" keyword? */
+    public static final int USES_THIS                   = 1 << 15;
+
     /** Does this function or any nested functions contain an eval? */
     private static final int HAS_DEEP_EVAL = HAS_EVAL | HAS_NESTED_EVAL;
 
@@ -223,6 +230,7 @@
      * @param parameters parameter list
      * @param kind       kind of function as in {@link FunctionNode.Kind}
      * @param flags      initial flags
+     * @param sourceURL  sourceURL specified in script (optional)
      */
     public FunctionNode(
         final Source source,
@@ -235,7 +243,8 @@
         final String name,
         final List<IdentNode> parameters,
         final FunctionNode.Kind kind,
-        final int flags) {
+        final int flags,
+        final String sourceURL) {
         super(token, finish);
 
         this.source           = source;
@@ -250,6 +259,7 @@
         this.compilationState = EnumSet.of(CompilationState.INITIALIZED);
         this.declaredSymbols  = new HashSet<>();
         this.flags            = flags;
+        this.sourceURL        = sourceURL;
         this.compileUnit      = null;
         this.body             = null;
         this.snapshot         = null;
@@ -260,6 +270,7 @@
         final FunctionNode functionNode,
         final long lastToken,
         final int flags,
+        final String sourceURL,
         final String name,
         final Type returnType,
         final CompileUnit compileUnit,
@@ -271,6 +282,7 @@
         super(functionNode);
         this.lineNumber       = functionNode.lineNumber;
         this.flags            = flags;
+        this.sourceURL        = sourceURL;
         this.name             = name;
         this.returnType       = returnType;
         this.compileUnit      = compileUnit;
@@ -308,6 +320,38 @@
     }
 
     /**
+     * get source name - sourceURL or name derived from Source.
+     *
+     * @return name for the script source
+     */
+    public String getSourceName() {
+        return (sourceURL != null)? sourceURL : source.getName();
+    }
+
+    /**
+     * get the sourceURL
+     * @return the sourceURL
+     */
+    public String getSourceURL() {
+        return sourceURL;
+    }
+
+    /**
+     * Set the sourceURL
+     *
+     * @param lc lexical context
+     * @param newSourceURL source url string to set
+     * @return function node or a new one if state was changed
+     */
+    public FunctionNode setSourceURL(final LexicalContext lc, final String newSourceURL) {
+        if (Objects.equals(sourceURL, newSourceURL)) {
+            return this;
+        }
+
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, newSourceURL, name, returnType, compileUnit, compilationState, body, parameters, null, hints));
+    }
+
+    /**
      * Returns the line number.
      * @return the line number.
      */
@@ -335,7 +379,7 @@
         if (this.snapshot == null) {
             return this;
         }
-        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, null, hints));
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, null, hints));
     }
 
     /**
@@ -351,7 +395,7 @@
         if (isProgram() || parameters.isEmpty()) {
             return this; //never specialize anything that won't be recompiled
         }
-        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, this, hints));
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, this, hints));
     }
 
     /**
@@ -409,7 +453,7 @@
         }
         final EnumSet<CompilationState> newState = EnumSet.copyOf(this.compilationState);
         newState.add(state);
-        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, newState, body, parameters, snapshot, hints));
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, newState, body, parameters, snapshot, hints));
     }
 
     /**
@@ -430,7 +474,7 @@
         if (this.hints == hints) {
             return this;
         }
-        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
     }
 
     /**
@@ -483,7 +527,7 @@
         if (this.flags == flags) {
             return this;
         }
-        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
     }
 
     @Override
@@ -550,6 +594,15 @@
     }
 
     /**
+     * Return {@code true} if this function makes use of the {@code this} object.
+     *
+     * @return true if function uses {@code this} object
+     */
+    public boolean usesThis() {
+        return getFlag(USES_THIS);
+    }
+
+    /**
      * Get the identifier for this function, this is its symbol.
      * @return the identifier as an IdentityNode
      */
@@ -593,7 +646,7 @@
         if(this.body == body) {
             return this;
         }
-        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags | (body.needsScope() ? FunctionNode.HAS_SCOPE_BLOCK : 0), name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags | (body.needsScope() ? FunctionNode.HAS_SCOPE_BLOCK : 0), sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
     }
 
     /**
@@ -688,7 +741,7 @@
         if (this.lastToken == lastToken) {
             return this;
         }
-        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
     }
 
     /**
@@ -710,7 +763,7 @@
         if (this.name.equals(name)) {
             return this;
         }
-        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
     }
 
     /**
@@ -760,7 +813,7 @@
         if (this.parameters == parameters) {
             return this;
         }
-        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
     }
 
     /**
@@ -825,6 +878,7 @@
                 this,
                 lastToken,
                 flags,
+                sourceURL,
                 name,
                 type,
                 compileUnit,
@@ -863,7 +917,7 @@
         if (this.compileUnit == compileUnit) {
             return this;
         }
-        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
+        return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
     }
 
     /**
--- a/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java	Mon Mar 24 13:51:59 2014 -0700
@@ -67,12 +67,8 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     AccessorPropertyDescriptor(final boolean configurable, final boolean enumerable, final Object get, final Object set, final Global global) {
-        super(global.getObjectPrototype(), global.getAccessorPropertyDescriptorMap());
+        super(global.getObjectPrototype(), $nasgenmap$);
         this.configurable = configurable;
         this.enumerable   = enumerable;
         this.get          = get;
@@ -185,6 +181,18 @@
     }
 
     @Override
+    public boolean hasAndEquals(final PropertyDescriptor otherDesc) {
+        if (! (otherDesc instanceof AccessorPropertyDescriptor)) {
+            return false;
+        }
+        final AccessorPropertyDescriptor other = (AccessorPropertyDescriptor)otherDesc;
+        return (!has(CONFIGURABLE) || sameValue(configurable, other.configurable)) &&
+               (!has(ENUMERABLE) || sameValue(enumerable, other.enumerable)) &&
+               (!has(GET) || sameValue(get, other.get)) &&
+               (!has(SET) || sameValue(set, other.set));
+    }
+
+    @Override
     public boolean equals(final Object obj) {
         if (this == obj) {
             return true;
--- a/src/jdk/nashorn/internal/objects/ArrayBufferView.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/ArrayBufferView.java	Mon Mar 24 13:51:59 2014 -0700
@@ -42,12 +42,8 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     private ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength, final Global global) {
-        super(global.getArrayBufferViewMap());
+        super($nasgenmap$);
         checkConstructorArgs(buffer, byteOffset, elementLength);
         this.setProto(getPrototype(global));
         this.setArray(factory().createArrayData(buffer, byteOffset, elementLength));
--- a/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java	Mon Mar 24 13:51:59 2014 -0700
@@ -64,12 +64,8 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     DataPropertyDescriptor(final boolean configurable, final boolean enumerable, final boolean writable, final Object value, final Global global) {
-        super(global.getObjectPrototype(), global.getDataPropertyDescriptorMap());
+        super(global.getObjectPrototype(), $nasgenmap$);
         this.configurable = configurable;
         this.enumerable   = enumerable;
         this.writable     = writable;
@@ -172,6 +168,19 @@
     }
 
     @Override
+    public boolean hasAndEquals(final PropertyDescriptor otherDesc) {
+        if (! (otherDesc instanceof DataPropertyDescriptor)) {
+            return false;
+        }
+
+        final DataPropertyDescriptor other = (DataPropertyDescriptor)otherDesc;
+        return (!has(CONFIGURABLE) || sameValue(configurable, other.configurable)) &&
+               (!has(ENUMERABLE) || sameValue(enumerable, other.enumerable)) &&
+               (!has(WRITABLE) || sameValue(writable, other.writable)) &&
+               (!has(VALUE) || sameValue(value, other.value));
+    }
+
+    @Override
     public boolean equals(final Object obj) {
         if (this == obj) {
             return true;
--- a/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java	Mon Mar 24 13:51:59 2014 -0700
@@ -55,12 +55,8 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     GenericPropertyDescriptor(final boolean configurable, final boolean enumerable, final Global global) {
-        super(global.getObjectPrototype(), global.getGenericPropertyDescriptorMap());
+        super(global.getObjectPrototype(), $nasgenmap$);
         this.configurable = configurable;
         this.enumerable   = enumerable;
     }
@@ -149,6 +145,23 @@
     }
 
     @Override
+    public boolean hasAndEquals(final PropertyDescriptor other) {
+        if (has(CONFIGURABLE) && other.has(CONFIGURABLE)) {
+            if (isConfigurable() != other.isConfigurable()) {
+                return false;
+            }
+        }
+
+        if (has(ENUMERABLE) && other.has(ENUMERABLE)) {
+            if (isEnumerable() != other.isEnumerable()) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @Override
     public boolean equals(final Object obj) {
         if (this == obj) {
             return true;
--- a/src/jdk/nashorn/internal/objects/Global.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/Global.java	Mon Mar 24 13:51:59 2014 -0700
@@ -33,11 +33,8 @@
 import java.io.PrintWriter;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.SoftReference;
 import java.lang.reflect.Field;
 import java.util.Arrays;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
@@ -51,7 +48,6 @@
 import jdk.nashorn.internal.runtime.ConsString;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.GlobalFunctions;
-import jdk.nashorn.internal.runtime.GlobalObject;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.NativeJavaPackage;
 import jdk.nashorn.internal.runtime.PropertyDescriptor;
@@ -59,10 +55,10 @@
 import jdk.nashorn.internal.runtime.Scope;
 import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptFunctionData;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.ScriptingFunctions;
-import jdk.nashorn.internal.runtime.Source;
 import jdk.nashorn.internal.runtime.arrays.ArrayData;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
 import jdk.nashorn.internal.runtime.linker.InvokeByName;
@@ -73,7 +69,7 @@
  * Representation of global scope.
  */
 @ScriptClass("Global")
-public final class Global extends ScriptObject implements GlobalObject, Scope {
+public final class Global extends ScriptObject implements Scope {
     private final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
     private final InvokeByName VALUE_OF  = new InvokeByName("valueOf",  ScriptObject.class);
 
@@ -229,6 +225,10 @@
     @Property(name = "ArrayBuffer", attributes = Attribute.NOT_ENUMERABLE)
     public volatile Object arrayBuffer;
 
+    /** DataView object */
+    @Property(name = "DataView", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object dataView;
+
     /** TypedArray (int8) */
     @Property(name = "Int8Array", attributes = Attribute.NOT_ENUMERABLE)
     public volatile Object int8Array;
@@ -355,6 +355,7 @@
     private ScriptObject   builtinJavaImporter;
     private ScriptObject   builtinJavaApi;
     private ScriptObject   builtinArrayBuffer;
+    private ScriptObject   builtinDataView;
     private ScriptObject   builtinInt8Array;
     private ScriptObject   builtinUint8Array;
     private ScriptObject   builtinUint8ClampedArray;
@@ -370,42 +371,9 @@
      */
     private ScriptFunction typeErrorThrower;
 
-    private PropertyMap    accessorPropertyDescriptorMap;
-    private PropertyMap    arrayBufferViewMap;
-    private PropertyMap    dataPropertyDescriptorMap;
-    private PropertyMap    genericPropertyDescriptorMap;
-    private PropertyMap    nativeArgumentsMap;
-    private PropertyMap    nativeArrayMap;
-    private PropertyMap    nativeArrayBufferMap;
-    private PropertyMap    nativeBooleanMap;
-    private PropertyMap    nativeDateMap;
-    private PropertyMap    nativeErrorMap;
-    private PropertyMap    nativeEvalErrorMap;
-    private PropertyMap    nativeJSAdapterMap;
-    private PropertyMap    nativeJavaImporterMap;
-    private PropertyMap    nativeNumberMap;
-    private PropertyMap    nativeRangeErrorMap;
-    private PropertyMap    nativeReferenceErrorMap;
-    private PropertyMap    nativeRegExpMap;
-    private PropertyMap    nativeRegExpExecResultMap;
-    private PropertyMap    nativeStrictArgumentsMap;
-    private PropertyMap    nativeStringMap;
-    private PropertyMap    nativeSyntaxErrorMap;
-    private PropertyMap    nativeTypeErrorMap;
-    private PropertyMap    nativeURIErrorMap;
-    private PropertyMap    prototypeObjectMap;
-    private PropertyMap    objectMap;
-    private PropertyMap    functionMap;
-    private PropertyMap    anonymousFunctionMap;
-    private PropertyMap    strictFunctionMap;
-    private PropertyMap    boundFunctionMap;
-
     // Flag to indicate that a split method issued a return statement
     private int splitState = -1;
 
-    // class cache
-    private ClassCache classCache;
-
     // Used to store the last RegExp result to support deprecated RegExp constructor properties
     private RegExpResult lastRegExpResult;
 
@@ -456,11 +424,6 @@
         super(checkAndGetMap(context));
         this.context = context;
         this.setIsScope();
-
-        final int cacheSize = context.getEnv()._class_cache_size;
-        if (cacheSize > 0) {
-            classCache = new ClassCache(cacheSize);
-        }
     }
 
     /**
@@ -469,11 +432,9 @@
      * @return the global singleton
      */
     public static Global instance() {
-        ScriptObject global = Context.getGlobal();
-        if (! (global instanceof Global)) {
-            throw new IllegalStateException("no current global instance");
-        }
-        return (Global)global;
+        Global global = Context.getGlobal();
+        global.getClass(); // null check
+        return global;
     }
 
     /**
@@ -494,19 +455,30 @@
         return instance().getContext();
     }
 
-    // GlobalObject interface implementation
+    // Runtime interface to Global
 
-    @Override
+    /**
+     * Is this global of the given Context?
+     * @param ctxt the context
+     * @return true if this global belongs to the given Context
+     */
     public boolean isOfContext(final Context ctxt) {
         return this.context == ctxt;
     }
 
-    @Override
+    /**
+     * Does this global belong to a strict Context?
+     * @return true if this global belongs to a strict Context
+     */
     public boolean isStrictContext() {
         return context.getEnv()._strict;
     }
 
-    @Override
+    /**
+     * Initialize standard builtin objects like "Object", "Array", "Function" etc.
+     * as well as our extension builtin objects like "Java", "JSAdapter" as properties
+     * of the global scope object.
+     */
     public void initBuiltinObjects() {
         if (this.builtinObject != null) {
             // already initialized, just return
@@ -516,12 +488,26 @@
         init();
     }
 
-    @Override
+    /**
+     * Create a new ScriptFunction object
+     *
+     * @param name   function name
+     * @param handle invocation handle for function
+     * @param scope  the scope
+     * @param strict are we in strict mode
+     *
+     * @return new script function
+     */
     public ScriptFunction newScriptFunction(final String name, final MethodHandle handle, final ScriptObject scope, final boolean strict) {
-        return new ScriptFunctionImpl(name, handle, scope, null, strict, false, true);
+        return new ScriptFunctionImpl(name, handle, scope, null, strict ? ScriptFunctionData.IS_STRICT_CONSTRUCTOR : ScriptFunctionData.IS_CONSTRUCTOR);
     }
 
-    @Override
+    /**
+     * Wrap a Java object as corresponding script object
+     *
+     * @param obj object to wrap
+     * @return    wrapped object
+     */
     public Object wrapAsObject(final Object obj) {
         if (obj instanceof Boolean) {
             return new NativeBoolean((Boolean)obj, this);
@@ -543,7 +529,14 @@
         }
     }
 
-    @Override
+    /**
+     * Lookup helper for JS primitive types
+     *
+     * @param request the link request for the dynamic call site.
+     * @param self     self reference
+     *
+     * @return guarded invocation
+     */
     public GuardedInvocation primitiveLookup(final LinkRequest request, final Object self) {
         if (self instanceof String || self instanceof ConsString) {
             return NativeString.lookupPrimitive(request, self);
@@ -555,12 +548,23 @@
         throw new IllegalArgumentException("Unsupported primitive: " + self);
     }
 
-    @Override
+    /**
+     * Create a new empty script object
+     *
+     * @return the new ScriptObject
+     */
     public ScriptObject newObject() {
-        return new JO(getObjectPrototype(), getObjectMap());
+        return new JO(getObjectPrototype(), JO.getInitialMap());
     }
 
-    @Override
+    /**
+     * Default value of given type
+     *
+     * @param sobj     script object
+     * @param typeHint type hint
+     *
+     * @return default value
+     */
     public Object getDefaultValue(final ScriptObject sobj, final Class<?> typeHint) {
         // When the [[DefaultValue]] internal method of O is called with no hint,
         // then it behaves as if the hint were Number, unless O is a Date object
@@ -620,7 +624,12 @@
         return UNDEFINED;
     }
 
-    @Override
+    /**
+     * Is the given ScriptObject an ECMAScript Error object?
+     *
+     * @param sobj the object being checked
+     * @return true if sobj is an Error object
+     */
     public boolean isError(final ScriptObject sobj) {
         final ScriptObject errorProto = getErrorPrototype();
         ScriptObject proto = sobj.getProto();
@@ -633,52 +642,108 @@
         return false;
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript Error object.
+     *
+     * @param msg error message
+     * @return newly created Error object
+     */
     public ScriptObject newError(final String msg) {
         return new NativeError(msg, this);
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript EvalError object.
+     *
+     * @param msg error message
+     * @return newly created EvalError object
+     */
     public ScriptObject newEvalError(final String msg) {
         return new NativeEvalError(msg, this);
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript RangeError object.
+     *
+     * @param msg error message
+     * @return newly created RangeError object
+     */
     public ScriptObject newRangeError(final String msg) {
         return new NativeRangeError(msg, this);
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript ReferenceError object.
+     *
+     * @param msg error message
+     * @return newly created ReferenceError object
+     */
     public ScriptObject newReferenceError(final String msg) {
         return new NativeReferenceError(msg, this);
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript SyntaxError object.
+     *
+     * @param msg error message
+     * @return newly created SyntaxError object
+     */
     public ScriptObject newSyntaxError(final String msg) {
         return new NativeSyntaxError(msg, this);
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript TypeError object.
+     *
+     * @param msg error message
+     * @return newly created TypeError object
+     */
     public ScriptObject newTypeError(final String msg) {
         return new NativeTypeError(msg, this);
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript URIError object.
+     *
+     * @param msg error message
+     * @return newly created URIError object
+     */
     public ScriptObject newURIError(final String msg) {
         return new NativeURIError(msg, this);
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript GenericDescriptor object.
+     *
+     * @param configurable is the property configurable?
+     * @param enumerable is the property enumerable?
+     * @return newly created GenericDescriptor object
+     */
     public PropertyDescriptor newGenericDescriptor(final boolean configurable, final boolean enumerable) {
         return new GenericPropertyDescriptor(configurable, enumerable, this);
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript DatePropertyDescriptor object.
+     *
+     * @param value of the data property
+     * @param configurable is the property configurable?
+     * @param enumerable is the property enumerable?
+     * @return newly created DataPropertyDescriptor object
+     */
     public PropertyDescriptor newDataDescriptor(final Object value, final boolean configurable, final boolean enumerable, final boolean writable) {
         return new DataPropertyDescriptor(configurable, enumerable, writable, value, this);
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript AccessorPropertyDescriptor object.
+     *
+     * @param get getter function of the user accessor property
+     * @param set setter function of the user accessor property
+     * @param configurable is the property configurable?
+     * @param enumerable is the property enumerable?
+     * @return newly created AccessorPropertyDescriptor object
+     */
     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, this);
 
@@ -694,62 +759,6 @@
     }
 
 
-    /**
-     * Cache for compiled script classes.
-     */
-    @SuppressWarnings("serial")
-    private static class ClassCache extends LinkedHashMap<Source, ClassReference> {
-        private final int size;
-        private final ReferenceQueue<Class<?>> queue;
-
-        ClassCache(int size) {
-            super(size, 0.75f, true);
-            this.size = size;
-            this.queue = new ReferenceQueue<>();
-        }
-
-        void cache(final Source source, final Class<?> clazz) {
-            put(source, new ClassReference(clazz, queue, source));
-        }
-
-        @Override
-        protected boolean removeEldestEntry(final Map.Entry<Source, ClassReference> eldest) {
-            return size() > size;
-        }
-
-        @Override
-        public ClassReference get(Object key) {
-            for (ClassReference ref; (ref = (ClassReference)queue.poll()) != null; ) {
-                remove(ref.source);
-            }
-            return super.get(key);
-        }
-
-    }
-
-    private static class ClassReference extends SoftReference<Class<?>> {
-        private final Source source;
-
-        ClassReference(final Class<?> clazz, final ReferenceQueue<Class<?>> queue, final Source source) {
-            super(clazz, queue);
-            this.source = source;
-        }
-    }
-
-    // Class cache management
-    @Override
-    public Class<?> findCachedClass(final Source source) {
-        assert classCache != null : "Class cache used without being initialized";
-        ClassReference ref = classCache.get(source);
-        return ref != null ? ref.get() : null;
-    }
-
-    @Override
-    public void cacheClass(final Source source, final Class<?> clazz) {
-        assert classCache != null : "Class cache used without being initialized";
-        classCache.cache(source, clazz);
-    }
-
     private static <T> T getLazilyCreatedValue(final Object key, final Callable<T> creator, final Map<Object, T> map) {
         final T obj = map.get(key);
         if (obj != null) {
@@ -767,14 +776,25 @@
 
     private final Map<Object, InvokeByName> namedInvokers = new ConcurrentHashMap<>();
 
-    @Override
+
+    /**
+     * Get cached InvokeByName object for the given key
+     * @param key key to be associated with InvokeByName object
+     * @param creator if InvokeByName is absent 'creator' is called to make one (lazy init)
+     * @return InvokeByName object associated with the key.
+     */
     public InvokeByName getInvokeByName(final Object key, final Callable<InvokeByName> creator) {
         return getLazilyCreatedValue(key, creator, namedInvokers);
     }
 
     private final Map<Object, MethodHandle> dynamicInvokers = new ConcurrentHashMap<>();
 
-    @Override
+    /**
+     * Get cached dynamic method handle for the given key
+     * @param key key to be associated with dynamic method handle
+     * @param creator if method handle is absent 'creator' is called to make one (lazy init)
+     * @return dynamic method handle associated with the key.
+     */
     public MethodHandle getDynamicInvoker(final Object key, final Callable<MethodHandle> creator) {
         return getLazilyCreatedValue(key, creator, dynamicInvokers);
     }
@@ -963,6 +983,10 @@
         return ScriptFunction.getPrototype(builtinArrayBuffer);
     }
 
+    ScriptObject getDataViewPrototype() {
+        return ScriptFunction.getPrototype(builtinDataView);
+    }
+
     ScriptObject getInt8ArrayPrototype() {
         return ScriptFunction.getPrototype(builtinInt8Array);
     }
@@ -999,123 +1023,6 @@
         return ScriptFunction.getPrototype(builtinFloat64Array);
     }
 
-    // Builtin PropertyMap accessors
-    PropertyMap getAccessorPropertyDescriptorMap() {
-        return accessorPropertyDescriptorMap;
-    }
-
-    PropertyMap getArrayBufferViewMap() {
-        return arrayBufferViewMap;
-    }
-
-    PropertyMap getDataPropertyDescriptorMap() {
-        return dataPropertyDescriptorMap;
-    }
-
-    PropertyMap getGenericPropertyDescriptorMap() {
-        return genericPropertyDescriptorMap;
-    }
-
-    PropertyMap getArgumentsMap() {
-        return nativeArgumentsMap;
-    }
-
-    PropertyMap getArrayMap() {
-        return nativeArrayMap;
-    }
-
-    PropertyMap getArrayBufferMap() {
-        return nativeArrayBufferMap;
-    }
-
-    PropertyMap getBooleanMap() {
-        return nativeBooleanMap;
-    }
-
-    PropertyMap getDateMap() {
-        return nativeDateMap;
-    }
-
-    PropertyMap getErrorMap() {
-        return nativeErrorMap;
-    }
-
-    PropertyMap getEvalErrorMap() {
-        return nativeEvalErrorMap;
-    }
-
-    PropertyMap getJSAdapterMap() {
-        return nativeJSAdapterMap;
-    }
-
-    PropertyMap getJavaImporterMap() {
-        return nativeJavaImporterMap;
-    }
-
-    PropertyMap getNumberMap() {
-        return nativeNumberMap;
-    }
-
-    PropertyMap getRangeErrorMap() {
-        return nativeRangeErrorMap;
-    }
-
-    PropertyMap getReferenceErrorMap() {
-        return nativeReferenceErrorMap;
-    }
-
-    PropertyMap getRegExpMap() {
-        return nativeRegExpMap;
-    }
-
-    PropertyMap getRegExpExecResultMap() {
-        return nativeRegExpExecResultMap;
-    }
-
-    PropertyMap getStrictArgumentsMap() {
-        return nativeStrictArgumentsMap;
-    }
-
-    PropertyMap getStringMap() {
-        return nativeStringMap;
-    }
-
-    PropertyMap getSyntaxErrorMap() {
-        return nativeSyntaxErrorMap;
-    }
-
-    PropertyMap getTypeErrorMap() {
-        return nativeTypeErrorMap;
-    }
-
-    PropertyMap getURIErrorMap() {
-        return nativeURIErrorMap;
-    }
-
-    PropertyMap getPrototypeObjectMap() {
-        return prototypeObjectMap;
-    }
-
-    PropertyMap getObjectMap() {
-        return objectMap;
-    }
-
-    PropertyMap getFunctionMap() {
-        return functionMap;
-    }
-
-    PropertyMap getAnonymousFunctionMap() {
-        return anonymousFunctionMap;
-    }
-
-    PropertyMap getStrictFunctionMap() {
-        return strictFunctionMap;
-    }
-
-    PropertyMap getBoundFunctionMap() {
-        return boundFunctionMap;
-    }
-
     private ScriptFunction getBuiltinArray() {
         return builtinArray;
     }
@@ -1631,14 +1538,11 @@
 
         final ScriptEnvironment env = getContext().getEnv();
 
-        // duplicate PropertyMaps of Native* classes
-        copyInitialMaps(env);
-
         // initialize Function and Object constructor
         initFunctionAndObject();
 
         // Now fix Global's own proto.
-        this.setProto(getObjectPrototype());
+        this.setInitialProto(getObjectPrototype());
 
         // initialize global function properties
         this.eval = this.builtinEval = ScriptFunctionImpl.makeFunction("eval", EVAL);
@@ -1705,8 +1609,25 @@
             initScripting(env);
         }
 
-        if (Context.DEBUG && System.getSecurityManager() == null) {
-            initDebug();
+        if (Context.DEBUG) {
+            boolean debugOkay;
+            final SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                try {
+                    sm.checkPermission(new RuntimePermission(Context.NASHORN_DEBUG_MODE));
+                    debugOkay = true;
+                } catch (final SecurityException ignored) {
+                    // if no permission, don't initialize Debug object
+                    debugOkay = false;
+                }
+
+            } else {
+                debugOkay = true;
+            }
+
+            if (debugOkay) {
+                initDebug();
+            }
         }
 
         copyBuiltins();
@@ -1766,7 +1687,7 @@
         final ScriptObject prototype = ScriptFunction.getPrototype(cons);
         prototype.set(NativeError.NAME, name, false);
         prototype.set(NativeError.MESSAGE, "", false);
-        prototype.setProto(errorProto);
+        prototype.setInitialProto(errorProto);
         return (ScriptFunction)cons;
     }
 
@@ -1834,6 +1755,7 @@
 
     private void initTypedArray() {
         this.builtinArrayBuffer       = initConstructor("ArrayBuffer");
+        this.builtinDataView          = initConstructor("DataView");
         this.builtinInt8Array         = initConstructor("Int8Array");
         this.builtinUint8Array        = initConstructor("Uint8Array");
         this.builtinUint8ClampedArray = initConstructor("Uint8ClampedArray");
@@ -1874,6 +1796,7 @@
         this.typeError         = this.builtinTypeError;
         this.uriError          = this.builtinURIError;
         this.arrayBuffer       = this.builtinArrayBuffer;
+        this.dataView          = this.builtinDataView;
         this.int8Array         = this.builtinInt8Array;
         this.uint8Array        = this.builtinUint8Array;
         this.uint8ClampedArray = this.builtinUint8ClampedArray;
@@ -1938,7 +1861,7 @@
             }
 
             if (res.getProto() == null) {
-                res.setProto(getObjectPrototype());
+                res.setInitialProto(getObjectPrototype());
             }
 
             return res;
@@ -1948,46 +1871,6 @@
         }
     }
 
-    private void copyInitialMaps(final ScriptEnvironment env) {
-        this.accessorPropertyDescriptorMap = AccessorPropertyDescriptor.getInitialMap().duplicate();
-        this.dataPropertyDescriptorMap = DataPropertyDescriptor.getInitialMap().duplicate();
-        this.genericPropertyDescriptorMap = GenericPropertyDescriptor.getInitialMap().duplicate();
-        this.nativeArgumentsMap = NativeArguments.getInitialMap().duplicate();
-        this.nativeArrayMap = NativeArray.getInitialMap().duplicate();
-        this.nativeBooleanMap = NativeBoolean.getInitialMap().duplicate();
-        this.nativeDateMap = NativeDate.getInitialMap().duplicate();
-        this.nativeErrorMap = NativeError.getInitialMap().duplicate();
-        this.nativeEvalErrorMap = NativeEvalError.getInitialMap().duplicate();
-        this.nativeJSAdapterMap = NativeJSAdapter.getInitialMap().duplicate();
-        this.nativeNumberMap = NativeNumber.getInitialMap().duplicate();
-        this.nativeRangeErrorMap = NativeRangeError.getInitialMap().duplicate();
-        this.nativeReferenceErrorMap = NativeReferenceError.getInitialMap().duplicate();
-        this.nativeRegExpMap = NativeRegExp.getInitialMap().duplicate();
-        this.nativeRegExpExecResultMap = NativeRegExpExecResult.getInitialMap().duplicate();
-        this.nativeStrictArgumentsMap = NativeStrictArguments.getInitialMap().duplicate();
-        this.nativeStringMap = NativeString.getInitialMap().duplicate();
-        this.nativeSyntaxErrorMap = NativeSyntaxError.getInitialMap().duplicate();
-        this.nativeTypeErrorMap = NativeTypeError.getInitialMap().duplicate();
-        this.nativeURIErrorMap = NativeURIError.getInitialMap().duplicate();
-        this.prototypeObjectMap = PrototypeObject.getInitialMap().duplicate();
-        this.objectMap = JO.getInitialMap().duplicate();
-        this.functionMap = ScriptFunctionImpl.getInitialMap().duplicate();
-        this.anonymousFunctionMap = ScriptFunctionImpl.getInitialAnonymousMap().duplicate();
-        this.strictFunctionMap = ScriptFunctionImpl.getInitialStrictMap().duplicate();
-        this.boundFunctionMap = ScriptFunctionImpl.getInitialBoundMap().duplicate();
-
-        // java
-        if (! env._no_java) {
-            this.nativeJavaImporterMap = NativeJavaImporter.getInitialMap().duplicate();
-        }
-
-        // typed arrays
-        if (! env._no_typed_arrays) {
-            this.arrayBufferViewMap = ArrayBufferView.getInitialMap().duplicate();
-            this.nativeArrayBufferMap = NativeArrayBuffer.getInitialMap().duplicate();
-        }
-    }
-
     // Function and Object constructors are inter-dependent. Also,
     // Function.prototype
     // functions are not properly initialized. We fix the references here.
@@ -2005,13 +1888,13 @@
 
         // Function.prototype === Object.getPrototypeOf(Function) ===
         // <anon-function>
-        builtinFunction.setProto(anon);
+        builtinFunction.setInitialProto(anon);
         builtinFunction.setPrototype(anon);
         anon.set("constructor", builtinFunction, false);
         anon.deleteOwnProperty(anon.getMap().findProperty("prototype"));
 
         // use "getter" so that [[ThrowTypeError]] function's arity is 0 - as specified in step 10 of section 13.2.3
-        this.typeErrorThrower = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER, null, null, false, false, false);
+        this.typeErrorThrower = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER, null, null, 0);
         typeErrorThrower.setPrototype(UNDEFINED);
         // Non-constructor built-in functions do not have "prototype" property
         typeErrorThrower.deleteOwnProperty(typeErrorThrower.getMap().findProperty("prototype"));
@@ -2021,7 +1904,7 @@
         this.builtinObject = (ScriptFunction)initConstructor("Object");
         final ScriptObject ObjectPrototype = getObjectPrototype();
         // Object.getPrototypeOf(Function.prototype) === Object.prototype
-        anon.setProto(ObjectPrototype);
+        anon.setInitialProto(ObjectPrototype);
 
         // Function valued properties of Function.prototype were not properly
         // initialized. Because, these were created before global.function and
@@ -2033,10 +1916,10 @@
 
             if (value instanceof ScriptFunction && value != anon) {
                 final ScriptFunction func = (ScriptFunction)value;
-                func.setProto(getFunctionPrototype());
+                func.setInitialProto(getFunctionPrototype());
                 final ScriptObject prototype = ScriptFunction.getPrototype(func);
                 if (prototype != null) {
-                    prototype.setProto(ObjectPrototype);
+                    prototype.setInitialProto(ObjectPrototype);
                 }
             }
         }
@@ -2051,7 +1934,7 @@
                 final ScriptFunction func = (ScriptFunction)value;
                 final ScriptObject prototype = ScriptFunction.getPrototype(func);
                 if (prototype != null) {
-                    prototype.setProto(ObjectPrototype);
+                    prototype.setInitialProto(ObjectPrototype);
                 }
             }
         }
@@ -2069,7 +1952,7 @@
                 final ScriptFunction func = (ScriptFunction)value;
                 final ScriptObject prototype = ScriptFunction.getPrototype(func);
                 if (prototype != null) {
-                    prototype.setProto(ObjectPrototype);
+                    prototype.setInitialProto(ObjectPrototype);
                 }
             }
         }
--- a/src/jdk/nashorn/internal/objects/NativeArguments.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeArguments.java	Mon Mar 24 13:51:59 2014 -0700
@@ -68,7 +68,7 @@
         final ArrayList<Property> properties = new ArrayList<>(2);
         properties.add(AccessorProperty.create("length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH));
         properties.add(AccessorProperty.create("callee", Property.NOT_ENUMERABLE, G$CALLEE, S$CALLEE));
-        map$ = PropertyMap.newMap(properties).setIsShared();
+        map$ = PropertyMap.newMap(properties);
     }
 
     static PropertyMap getInitialMap() {
@@ -267,9 +267,9 @@
         final Global global = Global.instance();
         final ScriptObject proto = global.getObjectPrototype();
         if (isStrict) {
-            return new NativeStrictArguments(arguments, numParams, proto, global.getStrictArgumentsMap());
+            return new NativeStrictArguments(arguments, numParams, proto, NativeStrictArguments.getInitialMap());
         }
-        return new NativeArguments(arguments, callee, numParams, proto, global.getArgumentsMap());
+        return new NativeArguments(arguments, callee, numParams, proto, NativeArguments.getInitialMap());
     }
 
     /**
--- a/src/jdk/nashorn/internal/objects/NativeArray.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeArray.java	Mon Mar 24 13:51:59 2014 -0700
@@ -31,6 +31,7 @@
 import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE;
 import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.arrayLikeIterator;
 import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.reverseArrayLikeIterator;
+import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
 
 import java.lang.invoke.MethodHandle;
 import java.util.ArrayList;
@@ -156,10 +157,6 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     /*
      * Constructors.
      */
@@ -208,7 +205,7 @@
     }
 
     NativeArray(final ArrayData arrayData, final Global global) {
-        super(global.getArrayPrototype(), global.getArrayMap());
+        super(global.getArrayPrototype(), $nasgenmap$);
         this.setArray(arrayData);
         this.setIsArray();
     }
@@ -354,6 +351,27 @@
     }
 
     /**
+     * Spec. mentions use of [[DefineOwnProperty]] for indexed properties in
+     * certain places (eg. Array.prototype.map, filter). We can not use ScriptObject.set
+     * method in such cases. This is because set method uses inherited setters (if any)
+     * from any object in proto chain such as Array.prototype, Object.prototype.
+     * This method directly sets a particular element value in the current object.
+     *
+     * @param index key for property
+     * @param value value to define
+     */
+    @Override
+    public final void defineOwnProperty(final int index, final Object value) {
+        assert isValidArrayIndex(index) : "invalid array index";
+        final long longIndex = ArrayIndex.toLongIndex(index);
+        if (longIndex >= getArray().length()) {
+            // make array big enough to hold..
+            setArray(getArray().ensure(longIndex));
+        }
+        setArray(getArray().set(index, value, false));
+    }
+
+    /**
      * Return the array contents upcasted as an ObjectArray, regardless of
      * representation
      *
--- a/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java	Mon Mar 24 13:51:59 2014 -0700
@@ -25,6 +25,7 @@
 
 package jdk.nashorn.internal.objects;
 
+import java.nio.ByteBuffer;
 import java.util.Arrays;
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Constructor;
@@ -43,10 +44,6 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     @Constructor(arity = 1)
     public static Object constructor(final boolean newObj, final Object self, final Object... args) {
         if (args.length == 0) {
@@ -57,7 +54,7 @@
     }
 
     protected NativeArrayBuffer(final byte[] byteArray, final Global global) {
-        super(global.getArrayBufferPrototype(), global.getArrayBufferMap());
+        super(global.getArrayBufferPrototype(), $nasgenmap$);
         this.buffer = byteArray;
     }
 
@@ -128,4 +125,16 @@
     public int getByteLength() {
         return buffer.length;
     }
+
+    ByteBuffer getBuffer() {
+       return ByteBuffer.wrap(buffer);
+    }
+
+    ByteBuffer getBuffer(final int offset) {
+        return ByteBuffer.wrap(buffer, offset, buffer.length - offset);
+    }
+
+    ByteBuffer getBuffer(final int offset, final int length) {
+        return ByteBuffer.wrap(buffer, offset, length);
+    }
 }
--- a/src/jdk/nashorn/internal/objects/NativeBoolean.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeBoolean.java	Mon Mar 24 13:51:59 2014 -0700
@@ -30,6 +30,7 @@
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
 import jdk.internal.dynalink.linker.GuardedInvocation;
 import jdk.internal.dynalink.linker.LinkRequest;
 import jdk.nashorn.internal.objects.annotations.Attribute;
@@ -50,22 +51,21 @@
 public final class NativeBoolean extends ScriptObject {
     private final boolean value;
 
-    final static MethodHandle WRAPFILTER = findWrapFilter();
+    // Method handle to create an object wrapper for a primitive boolean
+    private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeBoolean.class, Object.class));
+    // Method handle to retrieve the Boolean prototype object
+    private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
 
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     private NativeBoolean(final boolean value, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
         this.value = value;
     }
 
     NativeBoolean(final boolean flag, final Global global) {
-        this(flag, global.getBooleanPrototype(), global.getBooleanMap());
+        this(flag, global.getBooleanPrototype(), $nasgenmap$);
     }
 
     NativeBoolean(final boolean flag) {
@@ -164,7 +164,7 @@
      * @return Link to be invoked at call site.
      */
     public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
-        return PrimitiveLookup.lookupPrimitive(request, Boolean.class, new NativeBoolean((Boolean)receiver), WRAPFILTER);
+        return PrimitiveLookup.lookupPrimitive(request, Boolean.class, new NativeBoolean((Boolean)receiver), WRAPFILTER, PROTOFILTER);
     }
 
     /**
@@ -178,7 +178,12 @@
         return new NativeBoolean((Boolean)receiver);
     }
 
-    private static MethodHandle findWrapFilter() {
-        return MH.findStatic(MethodHandles.lookup(), NativeBoolean.class, "wrapFilter", MH.type(NativeBoolean.class, Object.class));
+    @SuppressWarnings("unused")
+    private static Object protoFilter(final Object object) {
+        return Global.instance().getBooleanPrototype();
+    }
+
+    private static MethodHandle findOwnMH(final String name, final MethodType type) {
+        return MH.findStatic(MethodHandles.lookup(), NativeBoolean.class, name, type);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk/nashorn/internal/objects/NativeDataView.java	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,1015 @@
+/*
+ * Copyright (c) 2014, 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.objects;
+
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import jdk.nashorn.internal.objects.annotations.Attribute;
+import jdk.nashorn.internal.objects.annotations.Constructor;
+import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.Property;
+import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
+import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * <p>
+ * DataView builtin constructor. Based on the specification here:
+ * http://www.khronos.org/registry/typedarray/specs/latest/#8
+ * </p>
+ * <p>
+ * An ArrayBuffer is a useful object for representing an arbitrary chunk of data.
+ * In many cases, such data will be read from disk or from the network, and will
+ * not follow the alignment restrictions that are imposed on the typed array views
+ * described earlier. In addition, the data will often be heterogeneous in nature
+ * and have a defined byte order. The DataView view provides a low-level interface
+ * for reading such data from and writing it to an ArrayBuffer.
+ * </p>
+ * <p>
+ * Regardless of the host computer's endianness, DataView reads or writes values
+ * to or from main memory with a specified endianness: big or little.
+ * </p>
+ */
+@ScriptClass("DataView")
+public class NativeDataView extends ScriptObject {
+    // initialized by nasgen
+    private static PropertyMap $nasgenmap$;
+
+    // inherited ArrayBufferView properties
+
+    /**
+     * Underlying ArrayBuffer storage object
+     */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+    public final Object buffer;
+
+    /**
+     * The offset in bytes from the start of the ArrayBuffer
+     */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+    public final int byteOffset;
+
+    /**
+     * The number of bytes from the offset that this DataView will reference
+     */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+    public final int byteLength;
+
+    // underlying ByteBuffer
+    private final ByteBuffer buf;
+
+    private NativeDataView(NativeArrayBuffer arrBuf) {
+        this(arrBuf, arrBuf.getBuffer(), 0);
+    }
+
+    private NativeDataView(NativeArrayBuffer arrBuf, int offset) {
+        this(arrBuf, bufferFrom(arrBuf, offset), offset);
+    }
+
+    private NativeDataView(NativeArrayBuffer arrBuf, int offset, int length) {
+        this(arrBuf, bufferFrom(arrBuf, offset, length), offset, length);
+    }
+
+    private NativeDataView(final NativeArrayBuffer arrBuf, final ByteBuffer buf, final int offset) {
+       this(arrBuf, buf, offset, buf.capacity() - offset);
+    }
+
+    private NativeDataView(final NativeArrayBuffer arrBuf, final ByteBuffer buf, final int offset, final int length) {
+        super(Global.instance().getDataViewPrototype(), $nasgenmap$);
+        this.buffer = arrBuf;
+        this.byteOffset = offset;
+        this.byteLength = length;
+        this.buf = buf;
+    }
+
+    /**
+     * Create a new DataView object using the passed ArrayBuffer for its
+     * storage. Optional byteOffset and byteLength can be used to limit the
+     * section of the buffer referenced. The byteOffset indicates the offset in
+     * bytes from the start of the ArrayBuffer, and the byteLength is the number
+     * of bytes from the offset that this DataView will reference. If both
+     * byteOffset and byteLength are omitted, the DataView spans the entire
+     * ArrayBuffer range. If the byteLength is omitted, the DataView extends from
+     * the given byteOffset until the end of the ArrayBuffer.
+     *
+     * If the given byteOffset and byteLength references an area beyond the end
+     * of the ArrayBuffer an exception is raised.
+
+     * @param newObj if this constructor was invoked with 'new' or not
+     * @param self   constructor function object
+     * @param args   arguments to the constructor
+     * @return newly constructed DataView object
+     */
+    @Constructor(arity = 1)
+    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
+        if (args.length == 0 || !(args[0] instanceof NativeArrayBuffer)) {
+            throw typeError("not.an.arraybuffer.in.dataview");
+        }
+
+        final NativeArrayBuffer arrBuf = (NativeArrayBuffer) args[0];
+        switch (args.length) {
+            case 1:
+                return new NativeDataView(arrBuf);
+            case 2:
+                return new NativeDataView(arrBuf, JSType.toInt32(args[1]));
+            default:
+                return new NativeDataView(arrBuf, JSType.toInt32(args[1]), JSType.toInt32(args[2]));
+        }
+    }
+
+    /**
+     * Specialized version of DataView constructor
+     *
+     * @param newObj if this constructor was invoked with 'new' or not
+     * @param self   constructor function object
+     * @param arrBuf underlying ArrayBuffer storage object
+     * @param offset offset in bytes from the start of the ArrayBuffer
+     * @return newly constructed DataView object
+     */
+    @SpecializedConstructor
+    public static Object constructor(final boolean newObj, final Object self, final Object arrBuf, final int offset) {
+        if (!(arrBuf instanceof NativeArrayBuffer)) {
+            throw typeError("not.an.arraybuffer.in.dataview");
+        }
+        return new NativeDataView((NativeArrayBuffer) arrBuf, offset);
+    }
+
+    /**
+     * Specialized version of DataView constructor
+     *
+     * @param newObj if this constructor was invoked with 'new' or not
+     * @param self   constructor function object
+     * @param arrBuf underlying ArrayBuffer storage object
+     * @param offset in bytes from the start of the ArrayBuffer
+     * @param length is the number of bytes from the offset that this DataView will reference
+     * @return newly constructed DataView object
+     */
+    @SpecializedConstructor
+    public static Object constructor(final boolean newObj, final Object self, final Object arrBuf, final int offset, final int length) {
+        if (!(arrBuf instanceof NativeArrayBuffer)) {
+            throw typeError("not.an.arraybuffer.in.dataview");
+        }
+        return new NativeDataView((NativeArrayBuffer) arrBuf, offset, length);
+    }
+
+    // Gets the value of the given type at the specified byte offset
+    // from the start of the view. There is no alignment constraint;
+    // multi-byte values may be fetched from any offset.
+    //
+    // For multi-byte values, the optional littleEndian argument
+    // indicates whether a big-endian or little-endian value should be
+    // read. If false or undefined, a big-endian value is read.
+    //
+    // These methods raise an exception if they would read
+    // beyond the end of the view.
+
+    /**
+     * Get 8-bit signed int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 8-bit signed int value at the byteOffset
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static int getInt8(final Object self, final Object byteOffset) {
+        try {
+            return getBuffer(self).get(JSType.toInt32(byteOffset));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 8-bit signed int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 8-bit signed int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static int getInt8(final Object self, final int byteOffset) {
+        try {
+            return getBuffer(self).get(byteOffset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 8-bit unsigned int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 8-bit unsigned int value at the byteOffset
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static int getUint8(final Object self, final Object byteOffset) {
+        try {
+            return (0xFF & getBuffer(self).get(JSType.toInt32(byteOffset)));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 8-bit unsigned int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 8-bit unsigned int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static int getUint8(final Object self, final int byteOffset) {
+        try {
+            return (0xFF & getBuffer(self).get(byteOffset));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 16-bit signed int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 16-bit signed int value at the byteOffset
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static int getInt16(final Object self, final Object byteOffset, final Object littleEndian) {
+        try {
+            return getBuffer(self, littleEndian).getShort(JSType.toInt32(byteOffset));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 16-bit signed int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 16-bit signed int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static int getInt16(final Object self, final int byteOffset) {
+        try {
+            return getBuffer(self, false).getShort(byteOffset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 16-bit signed int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 16-bit signed int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static int getInt16(final Object self, final int byteOffset, final boolean littleEndian) {
+        try {
+            return getBuffer(self, littleEndian).getShort(byteOffset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 16-bit unsigned int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 16-bit unsigned int value at the byteOffset
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static int getUint16(final Object self, final Object byteOffset, final Object littleEndian) {
+        try {
+            return (int) (0xFFFF & getBuffer(self, littleEndian).getShort(JSType.toInt32(byteOffset)));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 16-bit unsigned int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 16-bit unsigned int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static int getUint16(final Object self, final int byteOffset) {
+        try {
+            return (int) (0xFFFF & getBuffer(self, false).getShort(byteOffset));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 16-bit unsigned int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 16-bit unsigned int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static int getUint16(final Object self, final int byteOffset, final boolean littleEndian) {
+        try {
+            return (int) (0xFFFF & getBuffer(self, littleEndian).getShort(byteOffset));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 32-bit signed int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 32-bit signed int value at the byteOffset
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static int getInt32(final Object self, final Object byteOffset, final Object littleEndian) {
+        try {
+            return getBuffer(self, littleEndian).getInt(JSType.toInt32(byteOffset));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 32-bit signed int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 32-bit signed int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static int getInt32(final Object self, final int byteOffset) {
+        try {
+            return getBuffer(self, false).getInt(byteOffset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 32-bit signed int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 32-bit signed int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static int getInt32(final Object self, final int byteOffset, final boolean littleEndian) {
+        try {
+            return getBuffer(self, littleEndian).getInt(byteOffset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 32-bit unsigned int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 32-bit unsigned int value at the byteOffset
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static long getUint32(final Object self, final Object byteOffset, final Object littleEndian) {
+        try {
+            return (long) (0xFFFFFFFFL & getBuffer(self, littleEndian).getInt(JSType.toInt32(byteOffset)));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 32-bit unsigned int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 32-bit unsigned int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static long getUint32(final Object self, final int byteOffset) {
+        try {
+            return (long) (0xFFFFFFFFL & getBuffer(self, false).getInt(JSType.toInt32(byteOffset)));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 32-bit unsigned int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 32-bit unsigned int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static long getUint32(final Object self, final int byteOffset, final boolean littleEndian) {
+        try {
+            return (long) (0xFFFFFFFFL & getBuffer(self, littleEndian).getInt(JSType.toInt32(byteOffset)));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 32-bit float value from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 32-bit float value at the byteOffset
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static double getFloat32(final Object self, final Object byteOffset, final Object littleEndian) {
+        try {
+            return getBuffer(self, littleEndian).getFloat(JSType.toInt32(byteOffset));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 32-bit float value from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 32-bit float value at the byteOffset
+     */
+    @SpecializedFunction
+    public static double getFloat32(final Object self, final int byteOffset) {
+        try {
+            return getBuffer(self, false).getFloat(byteOffset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 32-bit float value from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 32-bit float value at the byteOffset
+     */
+    @SpecializedFunction
+    public static double getFloat32(final Object self, final int byteOffset, final boolean littleEndian) {
+        try {
+            return getBuffer(self, littleEndian).getFloat(byteOffset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 64-bit float value from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 64-bit float value at the byteOffset
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static double getFloat64(final Object self, final Object byteOffset, final Object littleEndian) {
+        try {
+            return getBuffer(self, littleEndian).getDouble(JSType.toInt32(byteOffset));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 64-bit float value from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 64-bit float value at the byteOffset
+     */
+    @SpecializedFunction
+    public static double getFloat64(final Object self, final int byteOffset) {
+        try {
+            return getBuffer(self, false).getDouble(byteOffset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 64-bit float value from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 64-bit float value at the byteOffset
+     */
+    @SpecializedFunction
+    public static double getFloat64(final Object self, final int byteOffset, final boolean littleEndian) {
+        try {
+            return getBuffer(self, littleEndian).getDouble(byteOffset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    // Stores a value of the given type at the specified byte offset
+    // from the start of the view. There is no alignment constraint;
+    // multi-byte values may be stored at any offset.
+    //
+    // For multi-byte values, the optional littleEndian argument
+    // indicates whether the value should be stored in big-endian or
+    // little-endian byte order. If false or undefined, the value is
+    // stored in big-endian byte order.
+    //
+    // These methods raise an exception if they would write
+    // beyond the end of the view.
+
+    /**
+     * Set 8-bit signed int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param value byte value to set
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setInt8(final Object self, final Object byteOffset, final Object value) {
+        try {
+            getBuffer(self).put(JSType.toInt32(byteOffset), (byte)JSType.toInt32(value));
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 8-bit signed int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param value byte value to set
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setInt8(final Object self, final int byteOffset, final int value) {
+        try {
+            getBuffer(self).put(byteOffset, (byte)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 8-bit unsigned int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value byte value to set
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setUint8(final Object self, final Object byteOffset, final Object value) {
+        try {
+            getBuffer(self).put(JSType.toInt32(byteOffset), (byte)JSType.toInt32(value));
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 8-bit unsigned int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value byte value to set
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setUint8(final Object self, final int byteOffset, final int value) {
+        try {
+            getBuffer(self).put(byteOffset, (byte)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 16-bit signed int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value short value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setInt16(final Object self, final Object byteOffset, final Object value, final Object littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putShort(JSType.toInt32(byteOffset), (short)JSType.toInt32(value));
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 16-bit signed int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value short value to set
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setInt16(final Object self, final int byteOffset, final int value) {
+        try {
+            getBuffer(self, false).putShort(byteOffset, (short)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 16-bit signed int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value short value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setInt16(final Object self, final int byteOffset, final int value, final boolean littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putShort(byteOffset, (short)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 16-bit unsigned int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value short value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setUint16(final Object self, final Object byteOffset, final Object value, final Object littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putShort(JSType.toInt32(byteOffset), (short)JSType.toInt32(value));
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 16-bit unsigned int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value short value to set
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setUint16(final Object self, final int byteOffset, final int value) {
+        try {
+            getBuffer(self, false).putShort(byteOffset, (short)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 16-bit unsigned int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value short value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setUint16(final Object self, final int byteOffset, final int value, final boolean littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putShort(byteOffset, (short)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 32-bit signed int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value int value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setInt32(final Object self, final Object byteOffset, final Object value, final Object littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putInt(JSType.toInt32(byteOffset), (int)JSType.toInt32(value));
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 32-bit signed int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value int value to set
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setInt32(final Object self, final int byteOffset, final int value) {
+        try {
+            getBuffer(self, false).putInt(byteOffset, value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 32-bit signed int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value int value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setInt32(final Object self, final int byteOffset, final int value, final boolean littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putInt(byteOffset, value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 32-bit unsigned int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value int value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setUint32(final Object self, final Object byteOffset, final Object value, final Object littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putInt(JSType.toInt32(byteOffset), (int)JSType.toUint32(value));
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 32-bit unsigned int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value int value to set
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setUint32(final Object self, final int byteOffset, final long value) {
+        try {
+            getBuffer(self, false).putInt(byteOffset, (int)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 32-bit unsigned int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value int value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setUint32(final Object self, final int byteOffset, final long value, final boolean littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putInt(byteOffset, (int)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 32-bit float at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value float value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setFloat32(final Object self, final Object byteOffset, final Object value, final Object littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putFloat((int)JSType.toUint32(byteOffset), (float)JSType.toNumber(value));
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 32-bit float at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value float value to set
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setFloat32(final Object self, final int byteOffset, final double value) {
+        try {
+            getBuffer(self, false).putFloat(byteOffset, (float)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 32-bit float at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value float value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setFloat32(final Object self, final int byteOffset, final double value, final boolean littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putFloat(byteOffset, (float)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 64-bit float at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value double value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setFloat64(final Object self, final Object byteOffset, final Object value, final Object littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putDouble((int)JSType.toUint32(byteOffset), JSType.toNumber(value));
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 64-bit float at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value double value to set
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setFloat64(final Object self, final int byteOffset, final double value) {
+        try {
+            getBuffer(self, false).putDouble(byteOffset, value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 64-bit float at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value double value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setFloat64(final Object self, final int byteOffset, final double value, final boolean littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putDouble(byteOffset, value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    // internals only below this point
+    private static ByteBuffer bufferFrom(final NativeArrayBuffer nab, final int offset) {
+        try {
+            return nab.getBuffer(offset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.constructor.offset");
+        }
+    }
+
+    private static ByteBuffer bufferFrom(final NativeArrayBuffer nab, final int offset, final int length) {
+        try {
+            return nab.getBuffer(offset, length);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.constructor.offset");
+        }
+    }
+
+    private static NativeDataView checkSelf(final Object self) {
+        if (!(self instanceof NativeDataView)) {
+            throw typeError("not.an.arraybuffer", ScriptRuntime.safeToString(self));
+        }
+        return (NativeDataView)self;
+    }
+
+    private static ByteBuffer getBuffer(final Object self) {
+        return checkSelf(self).buf;
+    }
+
+    private static ByteBuffer getBuffer(final Object self, final Object littleEndian) {
+        return getBuffer(self, JSType.toBoolean(littleEndian));
+    }
+
+    private static ByteBuffer getBuffer(final Object self, final boolean littleEndian) {
+        return getBuffer(self).order(littleEndian? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN);
+    }
+}
--- a/src/jdk/nashorn/internal/objects/NativeDate.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeDate.java	Mon Mar 24 13:51:59 2014 -0700
@@ -114,10 +114,6 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     private NativeDate(final double time, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
         final ScriptEnvironment env = Global.getEnv();
@@ -127,7 +123,7 @@
     }
 
     NativeDate(final double time, final Global global) {
-        this(time, global.getDatePrototype(), global.getDateMap());
+        this(time, global.getDatePrototype(), $nasgenmap$);
     }
 
     private NativeDate (final double time) {
--- a/src/jdk/nashorn/internal/objects/NativeDebug.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeDebug.java	Mon Mar 24 13:51:59 2014 -0700
@@ -34,7 +34,7 @@
 import jdk.nashorn.internal.objects.annotations.ScriptClass;
 import jdk.nashorn.internal.objects.annotations.Where;
 import jdk.nashorn.internal.runtime.Context;
-import jdk.nashorn.internal.runtime.PropertyListenerManager;
+import jdk.nashorn.internal.runtime.PropertyListeners;
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
@@ -186,7 +186,7 @@
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
     public static Object getListenerCount(final Object self, final Object obj) {
-        return (obj instanceof ScriptObject)? ((ScriptObject)obj).getListenerCount() : 0;
+        return (obj instanceof ScriptObject) ? PropertyListeners.getListenerCount((ScriptObject) obj) : 0;
     }
 
     /**
@@ -203,14 +203,13 @@
 
         out.println("ScriptObject count " + ScriptObject.getCount());
         out.println("Scope count " + ScriptObject.getScopeCount());
-        out.println("ScriptObject listeners added " + PropertyListenerManager.getListenersAdded());
-        out.println("ScriptObject listeners removed " + PropertyListenerManager.getListenersRemoved());
+        out.println("ScriptObject listeners added " + PropertyListeners.getListenersAdded());
+        out.println("ScriptObject listeners removed " + PropertyListeners.getListenersRemoved());
         out.println("ScriptFunction constructor calls " + ScriptFunction.getConstructorCount());
         out.println("ScriptFunction invokes " + ScriptFunction.getInvokes());
         out.println("ScriptFunction allocations " + ScriptFunction.getAllocations());
         out.println("PropertyMap count " + PropertyMap.getCount());
         out.println("PropertyMap cloned " + PropertyMap.getClonedCount());
-        out.println("PropertyMap shared " + PropertyMap.getSharedCount());
         out.println("PropertyMap duplicated " + PropertyMap.getDuplicatedCount());
         out.println("PropertyMap history hit " + PropertyMap.getHistoryHit());
         out.println("PropertyMap proto invalidations " + PropertyMap.getProtoInvalidations());
--- a/src/jdk/nashorn/internal/objects/NativeError.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeError.java	Mon Mar 24 13:51:59 2014 -0700
@@ -38,7 +38,6 @@
 import jdk.nashorn.internal.objects.annotations.Property;
 import jdk.nashorn.internal.objects.annotations.ScriptClass;
 import jdk.nashorn.internal.objects.annotations.Where;
-import jdk.nashorn.internal.objects.ScriptFunctionImpl;
 import jdk.nashorn.internal.runtime.ECMAException;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.PropertyMap;
@@ -75,7 +74,7 @@
     static final String FILENAME = "__fileName__";
 
     /** Message property name */
-    @Property(name = NativeError.MESSAGE)
+    @Property(name = NativeError.MESSAGE, attributes = Attribute.NOT_ENUMERABLE)
     public Object instMessage;
 
     /** ECMA 15.11.4.2 Error.prototype.name */
@@ -86,13 +85,14 @@
     @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
     public Object message;
 
+    /** Nashorn extension: underlying exception */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object nashornException;
+
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
+    @SuppressWarnings("LeakingThisInConstructor")
     private NativeError(final Object msg, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
         if (msg != UNDEFINED) {
@@ -100,10 +100,11 @@
         } else {
             this.delete(NativeError.MESSAGE, false);
         }
+        initException(this);
     }
 
     NativeError(final Object msg, final Global global) {
-        this(msg, global.getErrorPrototype(), global.getErrorMap());
+        this(msg, global.getErrorPrototype(), $nasgenmap$);
     }
 
     private NativeError(final Object msg) {
@@ -129,6 +130,14 @@
         return new NativeError(msg);
     }
 
+    // This is called NativeError, NativeTypeError etc. to
+    // associate a ECMAException with the ECMA Error object.
+    @SuppressWarnings("unused")
+    static void initException(final ScriptObject self) {
+        // ECMAException constructor has side effects
+        new ECMAException(self, null);
+    }
+
     /**
      * Nashorn extension: Error.captureStackTrace. Capture stack trace at the point of call into the Error object provided.
      *
@@ -136,16 +145,17 @@
      * @param errorObj the error object
      * @return undefined
      */
-    @SuppressWarnings("unused")
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
     public static Object captureStackTrace(final Object self, final Object errorObj) {
         Global.checkObject(errorObj);
         final ScriptObject sobj = (ScriptObject)errorObj;
-        new ECMAException(sobj, null); //constructor has side effects
-        sobj.delete("stack", false);
-        final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", GET_STACK);
-        final ScriptFunction setStack = ScriptFunctionImpl.makeFunction("setStack", SET_STACK);
-        sobj.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack);
+        initException(sobj);
+        sobj.delete(STACK, false);
+        if (! sobj.has("stack")) {
+            final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", GET_STACK);
+            final ScriptFunction setStack = ScriptFunctionImpl.makeFunction("setStack", SET_STACK);
+            sobj.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack);
+        }
         return UNDEFINED;
     }
 
@@ -226,7 +236,11 @@
     public static Object setLineNumber(final Object self, final Object value) {
         Global.checkObject(self);
         final ScriptObject sobj = (ScriptObject)self;
-        sobj.set(LINENUMBER, value, false);
+        if (sobj.hasOwnProperty(LINENUMBER)) {
+            sobj.put(LINENUMBER, value, false);
+        } else {
+            sobj.addOwnProperty(LINENUMBER, Attribute.NOT_ENUMERABLE, value);
+        }
         return value;
     }
 
@@ -254,7 +268,11 @@
     public static Object setColumnNumber(final Object self, final Object value) {
         Global.checkObject(self);
         final ScriptObject sobj = (ScriptObject)self;
-        sobj.set(COLUMNNUMBER, value, false);
+        if (sobj.hasOwnProperty(COLUMNNUMBER)) {
+            sobj.put(COLUMNNUMBER, value, false);
+        } else {
+            sobj.addOwnProperty(COLUMNNUMBER, Attribute.NOT_ENUMERABLE, value);
+        }
         return value;
     }
 
@@ -282,7 +300,11 @@
     public static Object setFileName(final Object self, final Object value) {
         Global.checkObject(self);
         final ScriptObject sobj = (ScriptObject)self;
-        sobj.set(FILENAME, value, false);
+        if (sobj.hasOwnProperty(FILENAME)) {
+            sobj.put(FILENAME, value, false);
+        } else {
+            sobj.addOwnProperty(FILENAME, Attribute.NOT_ENUMERABLE, value);
+        }
         return value;
     }
 
@@ -304,10 +326,12 @@
 
         final Object exception = ECMAException.getException(sobj);
         if (exception instanceof Throwable) {
-            return getScriptStackString(sobj, (Throwable)exception);
+            Object value = getScriptStackString(sobj, (Throwable)exception);
+            sobj.put(STACK, value, false);
+            return value;
         }
 
-        return "";
+        return UNDEFINED;
     }
 
     /**
--- a/src/jdk/nashorn/internal/objects/NativeEvalError.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeEvalError.java	Mon Mar 24 13:51:59 2014 -0700
@@ -44,7 +44,7 @@
 public final class NativeEvalError extends ScriptObject {
 
     /** message property in instance */
-    @Property(name = NativeError.MESSAGE)
+    @Property(name = NativeError.MESSAGE, attributes = Attribute.NOT_ENUMERABLE)
     public Object instMessage;
 
     /** error name property */
@@ -55,13 +55,14 @@
     @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
     public Object message;
 
+    /** Nashorn extension: underlying exception */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object nashornException;
+
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
+    @SuppressWarnings("LeakingThisInConstructor")
     private NativeEvalError(final Object msg, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
         if (msg != UNDEFINED) {
@@ -69,10 +70,11 @@
         } else {
             this.delete(NativeError.MESSAGE, false);
         }
+        NativeError.initException(this);
     }
 
     NativeEvalError(final Object msg, final Global global) {
-        this(msg, global.getEvalErrorPrototype(), global.getEvalErrorMap());
+        this(msg, global.getEvalErrorPrototype(), $nasgenmap$);
     }
 
     private NativeEvalError(final Object msg) {
--- a/src/jdk/nashorn/internal/objects/NativeJSAdapter.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeJSAdapter.java	Mon Mar 24 13:51:59 2014 -0700
@@ -146,10 +146,6 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     NativeJSAdapter(final Object overrides, final ScriptObject adaptee, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
         this.adaptee = wrapAdaptee(adaptee);
@@ -163,7 +159,7 @@
     }
 
     private static ScriptObject wrapAdaptee(final ScriptObject adaptee) {
-        return new JO(adaptee, Global.instance().getObjectMap());
+        return new JO(adaptee, JO.getInitialMap());
     }
 
     @Override
@@ -577,7 +573,7 @@
             proto = global.getJSAdapterPrototype();
         }
 
-        return new NativeJSAdapter(overrides, (ScriptObject)adaptee, (ScriptObject)proto, global.getJSAdapterMap());
+        return new NativeJSAdapter(overrides, (ScriptObject)adaptee, (ScriptObject)proto, $nasgenmap$);
     }
 
     @Override
@@ -622,14 +618,14 @@
         case "getMethod":
             final FindProperty find = adaptee.findProperty(__call__, true);
             if (find != null) {
-                final Object value = getObjectValue(find);
+                final Object value = find.getObjectValue();
                 if (value instanceof ScriptFunction) {
                     final ScriptFunctionImpl func = (ScriptFunctionImpl)value;
                     // TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound
                     // to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice.
                     return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class,
                             func.makeBoundFunction(this, new Object[] { name })), 0, Object.class),
-                            adaptee.getMap().getProtoGetSwitchPoint(adaptee.getProto(), __call__),
+                            adaptee.getProtoSwitchPoint(__call__, find.getOwner()),
                             testJSAdaptor(adaptee, null, null, null));
                 }
             }
@@ -691,7 +687,7 @@
         final MethodType type = desc.getMethodType();
         if (findData != null) {
             final String name = desc.getNameTokenCount() > 2 ? desc.getNameToken(2) : null;
-            final Object value = getObjectValue(findData);
+            final Object value = findData.getObjectValue();
             if (value instanceof ScriptFunction) {
                 final ScriptFunction func = (ScriptFunction)value;
 
@@ -700,7 +696,7 @@
                 if (methodHandle != null) {
                     return new GuardedInvocation(
                             methodHandle,
-                            adaptee.getMap().getProtoGetSwitchPoint(adaptee.getProto(), hook),
+                            adaptee.getProtoSwitchPoint(hook, findData.getOwner()),
                             testJSAdaptor(adaptee, findData.getGetter(Object.class), findData.getOwner(), func));
                 }
              }
@@ -713,7 +709,7 @@
             final MethodHandle methodHandle = hook.equals(__put__) ?
             MH.asType(Lookup.EMPTY_SETTER, type) :
             Lookup.emptyGetter(type.returnType());
-            return new GuardedInvocation(methodHandle, adaptee.getMap().getProtoGetSwitchPoint(adaptee.getProto(), hook), testJSAdaptor(adaptee, null, null, null));
+            return new GuardedInvocation(methodHandle, adaptee.getProtoSwitchPoint(hook, null), testJSAdaptor(adaptee, null, null, null));
         }
     }
 
--- a/src/jdk/nashorn/internal/objects/NativeJavaImporter.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeJavaImporter.java	Mon Mar 24 13:51:59 2014 -0700
@@ -60,17 +60,13 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     private NativeJavaImporter(final Object[] args, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
         this.args = args;
     }
 
     private NativeJavaImporter(final Object[] args, final Global global) {
-        this(args, global.getJavaImporterPrototype(), global.getJavaImporterMap());
+        this(args, global.getJavaImporterPrototype(), $nasgenmap$);
     }
 
     private NativeJavaImporter(final Object[] args) {
@@ -134,6 +130,11 @@
         return createAndSetProperty(desc) ? super.lookup(desc, request) : super.noSuchMethod(desc, request);
     }
 
+    @Override
+    protected Object invokeNoSuchProperty(final String name) {
+        return createProperty(name);
+    }
+
     private boolean createAndSetProperty(final CallSiteDescriptor desc) {
         final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
         final Object value = createProperty(name);
--- a/src/jdk/nashorn/internal/objects/NativeMath.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeMath.java	Mon Mar 24 13:51:59 2014 -0700
@@ -92,7 +92,7 @@
      * @return abs of value
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object abs(final Object self, final Object x) {
+    public static double abs(final Object self, final Object x) {
         return Math.abs(JSType.toNumber(x));
     }
 
@@ -144,7 +144,7 @@
      * @return acos of argument
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object acos(final Object self, final Object x) {
+    public static double acos(final Object self, final Object x) {
         return Math.acos(JSType.toNumber(x));
     }
 
@@ -170,7 +170,7 @@
      * @return asin of argument
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object asin(final Object self, final Object x) {
+    public static double asin(final Object self, final Object x) {
         return Math.asin(JSType.toNumber(x));
     }
 
@@ -196,7 +196,7 @@
      * @return atan of argument
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object atan(final Object self, final Object x) {
+    public static double atan(final Object self, final Object x) {
         return Math.atan(JSType.toNumber(x));
     }
 
@@ -223,7 +223,7 @@
      * @return atan2 of x and y
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object atan2(final Object self, final Object y, final Object x) {
+    public static double atan2(final Object self, final Object y, final Object x) {
         return Math.atan2(JSType.toNumber(y), JSType.toNumber(x));
     }
 
@@ -250,7 +250,7 @@
      * @return ceil of argument
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object ceil(final Object self, final Object x) {
+    public static double ceil(final Object self, final Object x) {
         return Math.ceil(JSType.toNumber(x));
     }
 
@@ -302,7 +302,7 @@
      * @return cos of argument
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object cos(final Object self, final Object x) {
+    public static double cos(final Object self, final Object x) {
         return Math.cos(JSType.toNumber(x));
     }
 
@@ -328,7 +328,7 @@
      * @return exp of argument
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object exp(final Object self, final Object x) {
+    public static double exp(final Object self, final Object x) {
         return Math.exp(JSType.toNumber(x));
     }
 
@@ -341,7 +341,7 @@
      * @return floor of argument
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object floor(final Object self, final Object x) {
+    public static double floor(final Object self, final Object x) {
         return Math.floor(JSType.toNumber(x));
     }
 
@@ -393,7 +393,7 @@
      * @return log of argument
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object log(final Object self, final Object x) {
+    public static double log(final Object self, final Object x) {
         return Math.log(JSType.toNumber(x));
     }
 
@@ -419,7 +419,7 @@
      * @return the largest of the arguments, {@link Double#NEGATIVE_INFINITY} if no args given, or identity if one arg is given
      */
     @Function(arity = 2, attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object max(final Object self, final Object... args) {
+    public static double max(final Object self, final Object... args) {
         switch (args.length) {
         case 0:
             return Double.NEGATIVE_INFINITY;
@@ -497,7 +497,7 @@
      * @return the smallest of the arguments, {@link Double#NEGATIVE_INFINITY} if no args given, or identity if one arg is given
      */
     @Function(arity = 2, attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object min(final Object self, final Object... args) {
+    public static double min(final Object self, final Object... args) {
         switch (args.length) {
         case 0:
             return Double.POSITIVE_INFINITY;
@@ -576,7 +576,7 @@
      * @return x raised to the power of y
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object pow(final Object self, final Object x, final Object y) {
+    public static double pow(final Object self, final Object x, final Object y) {
         return Math.pow(JSType.toNumber(x), JSType.toNumber(y));
     }
 
@@ -602,7 +602,7 @@
      * @return random number in the range [0..1)
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object random(final Object self) {
+    public static double random(final Object self) {
         return Math.random();
     }
 
@@ -615,7 +615,7 @@
      * @return x rounded
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object round(final Object self, final Object x) {
+    public static double round(final Object self, final Object x) {
         final double d = JSType.toNumber(x);
         if (Math.getExponent(d) >= 52) {
             return d;
@@ -632,7 +632,7 @@
      * @return sin of x
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object sin(final Object self, final Object x) {
+    public static double sin(final Object self, final Object x) {
         return Math.sin(JSType.toNumber(x));
     }
 
@@ -658,7 +658,7 @@
      * @return sqrt of x
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object sqrt(final Object self, final Object x) {
+    public static double sqrt(final Object self, final Object x) {
         return Math.sqrt(JSType.toNumber(x));
     }
 
@@ -684,7 +684,7 @@
      * @return tan of x
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where=Where.CONSTRUCTOR)
-    public static Object tan(final Object self, final Object x) {
+    public static double tan(final Object self, final Object x) {
         return Math.tan(JSType.toNumber(x));
     }
 
--- a/src/jdk/nashorn/internal/objects/NativeNumber.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeNumber.java	Mon Mar 24 13:51:59 2014 -0700
@@ -34,6 +34,7 @@
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
 import java.text.NumberFormat;
 import java.util.Locale;
 import jdk.internal.dynalink.linker.GuardedInvocation;
@@ -57,7 +58,10 @@
 @ScriptClass("Number")
 public final class NativeNumber extends ScriptObject {
 
-    static final MethodHandle WRAPFILTER = findWrapFilter();
+    // Method handle to create an object wrapper for a primitive number
+    private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeNumber.class, Object.class));
+    // Method handle to retrieve the Number prototype object
+    private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
 
     /** ECMA 15.7.3.2 largest positive finite value */
     @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
@@ -86,10 +90,6 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     private NativeNumber(final double value, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
         this.value = value;
@@ -98,7 +98,7 @@
     }
 
     NativeNumber(final double value, final Global global) {
-        this(value, global.getNumberPrototype(), global.getNumberMap());
+        this(value, global.getNumberPrototype(), $nasgenmap$);
     }
 
     private NativeNumber(final double value) {
@@ -322,7 +322,7 @@
      * @return Link to be invoked at call site.
      */
     public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
-        return PrimitiveLookup.lookupPrimitive(request, Number.class, new NativeNumber(((Number)receiver).doubleValue()), WRAPFILTER);
+        return PrimitiveLookup.lookupPrimitive(request, Number.class, new NativeNumber(((Number)receiver).doubleValue()), WRAPFILTER, PROTOFILTER);
     }
 
     @SuppressWarnings("unused")
@@ -330,6 +330,11 @@
         return new NativeNumber(((Number)receiver).doubleValue());
     }
 
+    @SuppressWarnings("unused")
+    private static Object protoFilter(final Object object) {
+        return Global.instance().getNumberPrototype();
+    }
+
     private static double getNumberValue(final Object self) {
         if (self instanceof Number) {
             return ((Number)self).doubleValue();
@@ -378,7 +383,7 @@
         return str;
     }
 
-    private static MethodHandle findWrapFilter() {
-        return MH.findStatic(MethodHandles.lookup(), NativeNumber.class, "wrapFilter", MH.type(NativeNumber.class, Object.class));
+    private static MethodHandle findOwnMH(final String name, final MethodType type) {
+        return MH.findStatic(MethodHandles.lookup(), NativeNumber.class, name, type);
     }
 }
--- a/src/jdk/nashorn/internal/objects/NativeObject.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeObject.java	Mon Mar 24 13:51:59 2014 -0700
@@ -31,6 +31,7 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
+import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
@@ -58,6 +59,7 @@
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
 import jdk.nashorn.internal.runtime.linker.InvokeByName;
 import jdk.nashorn.internal.runtime.linker.NashornBeansLinker;
@@ -101,6 +103,27 @@
     }
 
     /**
+     * Nashorn extension: setIndexedPropertiesToExternalArrayData
+     *
+     * @param self self reference
+     * @param obj object whose index properties are backed by buffer
+     * @param buf external buffer - should be a nio ByteBuffer
+     * @return the 'obj' object
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+    public static Object setIndexedPropertiesToExternalArrayData(final Object self, final Object obj, final Object buf) {
+        Global.checkObject(obj);
+        final ScriptObject sobj = (ScriptObject)obj;
+        if (buf instanceof ByteBuffer) {
+            sobj.setArray(ArrayData.allocate((ByteBuffer)buf));
+        } else {
+            throw typeError("not.a.bytebuffer", "setIndexedPropertiesToExternalArrayData's buf argument");
+        }
+        return sobj;
+    }
+
+
+    /**
      * ECMA 15.2.3.2 Object.getPrototypeOf ( O )
      *
      * @param  self self reference
--- a/src/jdk/nashorn/internal/objects/NativeRangeError.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeRangeError.java	Mon Mar 24 13:51:59 2014 -0700
@@ -44,7 +44,7 @@
 public final class NativeRangeError extends ScriptObject {
 
     /** message property in instance */
-    @Property(name = NativeError.MESSAGE)
+    @Property(name = NativeError.MESSAGE, attributes = Attribute.NOT_ENUMERABLE)
     public Object instMessage;
 
     /** error name property */
@@ -55,13 +55,14 @@
     @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
     public Object message;
 
+    /** Nashorn extension: underlying exception */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object nashornException;
+
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
+    @SuppressWarnings("LeakingThisInConstructor")
     private NativeRangeError(final Object msg, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
         if (msg != UNDEFINED) {
@@ -69,10 +70,11 @@
         } else {
             this.delete(NativeError.MESSAGE, false);
         }
+        NativeError.initException(this);
     }
 
     NativeRangeError(final Object msg, final Global global) {
-        this(msg, global.getRangeErrorPrototype(), global.getRangeErrorMap());
+        this(msg, global.getRangeErrorPrototype(), $nasgenmap$);
     }
 
     private NativeRangeError(final Object msg) {
--- a/src/jdk/nashorn/internal/objects/NativeReferenceError.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeReferenceError.java	Mon Mar 24 13:51:59 2014 -0700
@@ -44,7 +44,7 @@
 public final class NativeReferenceError extends ScriptObject {
 
     /** message property in instance */
-    @Property(name = NativeError.MESSAGE)
+    @Property(name = NativeError.MESSAGE, attributes = Attribute.NOT_ENUMERABLE)
     public Object instMessage;
 
     /** error name property */
@@ -55,13 +55,14 @@
     @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
     public Object message;
 
+    /** Nashorn extension: underlying exception */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object nashornException;
+
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
+    @SuppressWarnings("LeakingThisInConstructor")
     private NativeReferenceError(final Object msg, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
         if (msg != UNDEFINED) {
@@ -69,10 +70,11 @@
         } else {
             this.delete(NativeError.MESSAGE, false);
         }
+        NativeError.initException(this);
     }
 
     NativeReferenceError(final Object msg, final Global global) {
-        this(msg, global.getReferenceErrorPrototype(), global.getReferenceErrorMap());
+        this(msg, global.getReferenceErrorPrototype(), $nasgenmap$);
     }
 
     private NativeReferenceError(final Object msg) {
--- a/src/jdk/nashorn/internal/objects/NativeRegExp.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeRegExp.java	Mon Mar 24 13:51:59 2014 -0700
@@ -70,12 +70,8 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     private NativeRegExp(final Global global) {
-        super(global.getRegExpPrototype(), global.getRegExpMap());
+        super(global.getRegExpPrototype(), $nasgenmap$);
         this.globalObject = global;
     }
 
--- a/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java	Mon Mar 24 13:51:59 2014 -0700
@@ -53,12 +53,8 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     NativeRegExpExecResult(final RegExpResult result, final Global global) {
-        super(global.getArrayPrototype(), global.getRegExpExecResultMap());
+        super(global.getArrayPrototype(), $nasgenmap$);
         setIsArray();
         this.setArray(ArrayData.allocate(result.getGroups().clone()));
         this.index = result.getIndex();
--- a/src/jdk/nashorn/internal/objects/NativeStrictArguments.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeStrictArguments.java	Mon Mar 24 13:51:59 2014 -0700
@@ -60,9 +60,9 @@
         // In strict mode, the caller and callee properties should throw TypeError
         // Need to add properties directly to map since slots are assigned speculatively by newUserAccessors.
         final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
-        map = map.addProperty(map.newUserAccessors("caller", flags));
-        map = map.addProperty(map.newUserAccessors("callee", flags));
-        map$ = map.setIsShared();
+        map = map.addPropertyNoHistory(map.newUserAccessors("caller", flags));
+        map = map.addPropertyNoHistory(map.newUserAccessors("callee", flags));
+        map$ = map;
     }
 
     static PropertyMap getInitialMap() {
--- a/src/jdk/nashorn/internal/objects/NativeString.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeString.java	Mon Mar 24 13:51:59 2014 -0700
@@ -32,6 +32,7 @@
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
 import java.text.Collator;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -69,21 +70,20 @@
 
     private final CharSequence value;
 
-    static final MethodHandle WRAPFILTER = findWrapFilter();
+    // Method handle to create an object wrapper for a primitive string
+    private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeString.class, Object.class));
+    // Method handle to retrieve the String prototype object
+    private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
 
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     private NativeString(final CharSequence value) {
         this(value, Global.instance());
     }
 
     NativeString(final CharSequence value, final Global global) {
-        this(value, global.getStringPrototype(), global.getStringMap());
+        this(value, global.getStringPrototype(), $nasgenmap$);
     }
 
     private NativeString(final CharSequence value, final ScriptObject proto, final PropertyMap map) {
@@ -1199,7 +1199,7 @@
      */
     public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
         final MethodHandle guard = NashornGuards.getInstanceOf2Guard(String.class, ConsString.class);
-        return PrimitiveLookup.lookupPrimitive(request, guard, new NativeString((CharSequence)receiver), WRAPFILTER);
+        return PrimitiveLookup.lookupPrimitive(request, guard, new NativeString((CharSequence)receiver), WRAPFILTER, PROTOFILTER);
     }
 
     @SuppressWarnings("unused")
@@ -1207,6 +1207,11 @@
         return new NativeString((CharSequence)receiver);
     }
 
+    @SuppressWarnings("unused")
+    private static Object protoFilter(final Object object) {
+        return Global.instance().getStringPrototype();
+    }
+
     private static CharSequence getCharSequence(final Object self) {
         if (self instanceof String || self instanceof ConsString) {
             return (CharSequence)self;
@@ -1254,7 +1259,7 @@
         return key >= 0 && key < value.length();
     }
 
-    private static MethodHandle findWrapFilter() {
-        return MH.findStatic(MethodHandles.lookup(), NativeString.class, "wrapFilter", MH.type(NativeString.class, Object.class));
+    private static MethodHandle findOwnMH(final String name, final MethodType type) {
+        return MH.findStatic(MethodHandles.lookup(), NativeString.class, name, type);
     }
 }
--- a/src/jdk/nashorn/internal/objects/NativeSyntaxError.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeSyntaxError.java	Mon Mar 24 13:51:59 2014 -0700
@@ -44,7 +44,7 @@
 public final class NativeSyntaxError extends ScriptObject {
 
     /** message property in instance */
-    @Property(name = NativeError.MESSAGE)
+    @Property(name = NativeError.MESSAGE, attributes = Attribute.NOT_ENUMERABLE)
     public Object instMessage;
 
     /** error name property */
@@ -55,20 +55,22 @@
     @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
     public Object message;
 
+    /** Nashorn extension: underlying exception */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object nashornException;
+
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
+    @SuppressWarnings("LeakingThisInConstructor")
     NativeSyntaxError(final Object msg, final Global global) {
-        super(global.getSyntaxErrorPrototype(), global.getSyntaxErrorMap());
+        super(global.getSyntaxErrorPrototype(), $nasgenmap$);
         if (msg != UNDEFINED) {
             this.instMessage = JSType.toString(msg);
         } else {
             this.delete(NativeError.MESSAGE, false);
         }
+        NativeError.initException(this);
     }
 
     private NativeSyntaxError(final Object msg) {
--- a/src/jdk/nashorn/internal/objects/NativeTypeError.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeTypeError.java	Mon Mar 24 13:51:59 2014 -0700
@@ -44,7 +44,7 @@
 public final class NativeTypeError extends ScriptObject {
 
     /** message property in instance */
-    @Property(name = NativeError.MESSAGE)
+    @Property(name = NativeError.MESSAGE, attributes = Attribute.NOT_ENUMERABLE)
     public Object instMessage;
 
     /** error name property */
@@ -55,20 +55,22 @@
     @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
     public Object message;
 
+    /** Nashorn extension: underlying exception */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object nashornException;
+
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
+    @SuppressWarnings("LeakingThisInConstructor")
     NativeTypeError(final Object msg, final Global global) {
-        super(global.getTypeErrorPrototype(), global.getTypeErrorMap());
+        super(global.getTypeErrorPrototype(), $nasgenmap$);
         if (msg != UNDEFINED) {
             this.instMessage = JSType.toString(msg);
         } else {
             delete(NativeError.MESSAGE, false);
         }
+        NativeError.initException(this);
     }
 
     private NativeTypeError(final Object msg) {
--- a/src/jdk/nashorn/internal/objects/NativeURIError.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/NativeURIError.java	Mon Mar 24 13:51:59 2014 -0700
@@ -43,7 +43,7 @@
 public final class NativeURIError extends ScriptObject {
 
     /** message property in instance */
-    @Property(name = NativeError.MESSAGE)
+    @Property(name = NativeError.MESSAGE, attributes = Attribute.NOT_ENUMERABLE)
     public Object instMessage;
 
     /** error name property */
@@ -54,20 +54,22 @@
     @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
     public Object message;
 
+    /** Nashorn extension: underlying exception */
+    @Property(attributes = Attribute.NOT_ENUMERABLE)
+    public Object nashornException;
+
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
+    @SuppressWarnings("LeakingThisInConstructor")
     NativeURIError(final Object msg, final Global global) {
-        super(global.getURIErrorPrototype(), global.getURIErrorMap());
+        super(global.getURIErrorPrototype(), $nasgenmap$);
         if (msg != UNDEFINED) {
             this.instMessage = JSType.toString(msg);
         } else {
             this.delete(NativeError.MESSAGE, false);
         }
+        NativeError.initException(this);
     }
 
     private NativeURIError(final Object msg) {
--- a/src/jdk/nashorn/internal/objects/PrototypeObject.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/PrototypeObject.java	Mon Mar 24 13:51:59 2014 -0700
@@ -54,16 +54,11 @@
     static {
         final ArrayList<Property> properties = new ArrayList<>(1);
         properties.add(AccessorProperty.create("constructor", Property.NOT_ENUMERABLE, GET_CONSTRUCTOR, SET_CONSTRUCTOR));
-        map$ = PropertyMap.newMap(properties).setIsShared();
-    }
-
-    static PropertyMap getInitialMap() {
-        return map$;
+        map$ = PropertyMap.newMap(properties);
     }
 
     private PrototypeObject(final Global global, final PropertyMap map) {
-        super(map != map$? map.addAll(global.getPrototypeObjectMap()) : global.getPrototypeObjectMap());
-        setProto(global.getObjectPrototype());
+        super(global.getObjectPrototype(), map != map$? map.addAll(map$) : map$);
     }
 
     PrototypeObject() {
--- a/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Mon Mar 24 13:51:59 2014 -0700
@@ -37,7 +37,6 @@
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptFunctionData;
 import jdk.nashorn.internal.runtime.ScriptObject;
-import jdk.nashorn.internal.lookup.Lookup;
 import jdk.nashorn.internal.runtime.AccessorProperty;
 
 /**
@@ -56,27 +55,11 @@
     // property map for non-strict, non-bound functions.
     private static final PropertyMap map$;
 
-    static PropertyMap getInitialMap() {
-        return map$;
-    }
-
-    static PropertyMap getInitialAnonymousMap() {
-        return AnonymousFunction.getInitialMap();
-    }
-
-    static PropertyMap getInitialStrictMap() {
-        return strictmodemap$;
-    }
-
-    static PropertyMap getInitialBoundMap() {
-        return boundfunctionmap$;
-    }
-
     // Marker object for lazily initialized prototype object
     private static final Object LAZY_PROTOTYPE = new Object();
 
     private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final MethodHandle[] specs, final Global global) {
-        super(name, invokeHandle, global.getFunctionMap(), null, specs, false, true, true);
+        super(name, invokeHandle, map$, null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR);
         init(global);
     }
 
@@ -93,7 +76,7 @@
     }
 
     private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final MethodHandle[] specs, final Global global) {
-        super(name, invokeHandle, map.addAll(global.getFunctionMap()), null, specs, false, true, true);
+        super(name, invokeHandle, map.addAll(map$), null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR);
         init(global);
     }
 
@@ -110,8 +93,8 @@
         this(name, invokeHandle, map, specs, Global.instance());
     }
 
-    private ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor, final Global global) {
-        super(name, methodHandle, getMap(global, isStrict), scope, specs, isStrict, isBuiltin, isConstructor);
+    private ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final int flags, final Global global) {
+        super(name, methodHandle, getMap(isStrict(flags)), scope, specs, flags);
         init(global);
     }
 
@@ -122,16 +105,14 @@
      * @param methodHandle handle for invocation
      * @param scope scope object
      * @param specs specialized versions of this method, if available, null otherwise
-     * @param isStrict are we in strict mode
-     * @param isBuiltin is this a built-in function
-     * @param isConstructor can the function be used as a constructor (most can; some built-ins are restricted).
+     * @param flags {@link ScriptFunctionData} flags
      */
-    ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) {
-        this(name, methodHandle, scope, specs, isStrict, isBuiltin, isConstructor, Global.instance());
+    ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final int flags) {
+        this(name, methodHandle, scope, specs, flags, Global.instance());
     }
 
     private ScriptFunctionImpl(final RecompilableScriptFunctionData data, final ScriptObject scope, final Global global) {
-        super(data, getMap(global, data.isStrict()), scope);
+        super(data, getMap(data.isStrict()), scope);
         init(global);
     }
 
@@ -151,7 +132,7 @@
      * @param global the global object
      */
     ScriptFunctionImpl(final ScriptFunctionData data, final Global global) {
-        super(data, global.getBoundFunctionMap(), null);
+        super(data, boundfunctionmap$, null);
         init(global);
     }
 
@@ -163,25 +144,24 @@
         map$ = PropertyMap.newMap(properties);
         strictmodemap$ = createStrictModeMap(map$);
         boundfunctionmap$ = createBoundFunctionMap(strictmodemap$);
-        // There are order dependencies between normal map, struct map and bound map
-        // We can make these 'shared' only after initialization of all three.
-        map$.setIsShared();
-        strictmodemap$.setIsShared();
-        boundfunctionmap$.setIsShared();
     }
 
     private static PropertyMap createStrictModeMap(final PropertyMap map) {
         final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
         PropertyMap newMap = map;
         // Need to add properties directly to map since slots are assigned speculatively by newUserAccessors.
-        newMap = newMap.addProperty(map.newUserAccessors("arguments", flags));
-        newMap = newMap.addProperty(map.newUserAccessors("caller", flags));
+        newMap = newMap.addPropertyNoHistory(map.newUserAccessors("arguments", flags));
+        newMap = newMap.addPropertyNoHistory(map.newUserAccessors("caller", flags));
         return newMap;
     }
 
+    private static boolean isStrict(final int flags) {
+        return (flags & ScriptFunctionData.IS_STRICT) != 0;
+    }
+
     // Choose the map based on strict mode!
-    private static PropertyMap getMap(final Global global, final boolean strict) {
-        return strict ? global.getStrictFunctionMap() : global.getFunctionMap();
+    private static PropertyMap getMap(final boolean strict) {
+        return strict ? strictmodemap$ : map$;
     }
 
     private static PropertyMap createBoundFunctionMap(final PropertyMap strictModeMap) {
@@ -193,14 +173,10 @@
     // Instance of this class is used as global anonymous function which
     // serves as Function.prototype object.
     private static class AnonymousFunction extends ScriptFunctionImpl {
-        private static final PropertyMap anonmap$ = PropertyMap.newMap().setIsShared();
-
-        static PropertyMap getInitialMap() {
-            return anonmap$;
-        }
+        private static final PropertyMap anonmap$ = PropertyMap.newMap();
 
         AnonymousFunction(final Global global) {
-            super("", GlobalFunctions.ANONYMOUS, global.getAnonymousFunctionMap(), null);
+            super("", GlobalFunctions.ANONYMOUS, anonmap$, null);
         }
     }
 
@@ -217,7 +193,7 @@
      * @return new ScriptFunction
      */
     static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final MethodHandle[] specs) {
-        final ScriptFunctionImpl func = new ScriptFunctionImpl(name, methodHandle, null, specs, false, true, false);
+        final ScriptFunctionImpl func = new ScriptFunctionImpl(name, methodHandle, null, specs, ScriptFunctionData.IS_BUILTIN);
         func.setPrototype(UNDEFINED);
         // Non-constructor built-in functions do not have "prototype" property
         func.deleteOwnProperty(func.getMap().findProperty("prototype"));
@@ -281,13 +257,17 @@
     }
 
     @Override
-    public final void setPrototype(final Object prototype) {
-        this.prototype = prototype;
+    public final void setPrototype(final Object newProto) {
+        if (newProto instanceof ScriptObject && newProto != this.prototype && allocatorMap != null) {
+            // Replace our current allocator map with one that is associated with the new prototype.
+            allocatorMap = allocatorMap.changeProto((ScriptObject)newProto);
+        }
+        this.prototype = newProto;
     }
 
     // Internals below..
     private void init(final Global global) {
-        this.setProto(global.getFunctionPrototype());
+        this.setInitialProto(global.getFunctionPrototype());
         this.prototype = LAZY_PROTOTYPE;
 
         // We have to fill user accessor functions late as these are stored
--- a/src/jdk/nashorn/internal/parser/AbstractParser.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/parser/AbstractParser.java	Mon Mar 24 13:51:59 2014 -0700
@@ -26,6 +26,7 @@
 package jdk.nashorn.internal.parser;
 
 import static jdk.nashorn.internal.parser.TokenType.COMMENT;
+import static jdk.nashorn.internal.parser.TokenType.DIRECTIVE_COMMENT;
 import static jdk.nashorn.internal.parser.TokenType.EOF;
 import static jdk.nashorn.internal.parser.TokenType.EOL;
 import static jdk.nashorn.internal.parser.TokenType.IDENT;
@@ -84,6 +85,9 @@
     /** Is this parser running under strict mode? */
     protected boolean isStrictMode;
 
+    /** //@ sourceURL or //# sourceURL */
+    protected String sourceURL;
+
     /**
      * Construct a parser.
      *
@@ -156,17 +160,38 @@
     protected final TokenType nextOrEOL() {
         do {
             nextToken();
-        } while (type == COMMENT);
+            if (type == DIRECTIVE_COMMENT) {
+                checkDirectiveComment();
+            }
+        } while (type == COMMENT || type == DIRECTIVE_COMMENT);
 
         return type;
     }
 
+    // sourceURL= after directive comment
+    private static final String SOURCE_URL_PREFIX = "sourceURL=";
+
+    // currently only @sourceURL=foo supported
+    private void checkDirectiveComment() {
+        // if already set, ignore this one
+        if (sourceURL != null) {
+            return;
+        }
+
+        final String comment = (String) lexer.getValueOf(token, isStrictMode);
+        final int len = comment.length();
+        // 4 characters for directive comment marker //@\s or //#\s
+        if (len > 4 && comment.substring(4).startsWith(SOURCE_URL_PREFIX)) {
+            sourceURL = comment.substring(4 + SOURCE_URL_PREFIX.length());
+        }
+    }
+
     /**
      * Seek next token.
      *
      * @return tokenType of next token.
      */
-    private final TokenType nextToken() {
+    private TokenType nextToken() {
         // Capture last token tokenType.
         last = type;
         if (type != EOF) {
--- a/src/jdk/nashorn/internal/parser/Lexer.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/parser/Lexer.java	Mon Mar 24 13:51:59 2014 -0700
@@ -27,6 +27,7 @@
 
 import static jdk.nashorn.internal.parser.TokenType.ADD;
 import static jdk.nashorn.internal.parser.TokenType.COMMENT;
+import static jdk.nashorn.internal.parser.TokenType.DIRECTIVE_COMMENT;
 import static jdk.nashorn.internal.parser.TokenType.DECIMAL;
 import static jdk.nashorn.internal.parser.TokenType.EOF;
 import static jdk.nashorn.internal.parser.TokenType.EOL;
@@ -434,12 +435,18 @@
             if (ch1 == '/') {
                 // Skip over //.
                 skip(2);
+
+                boolean directiveComment = false;
+                if ((ch0 == '#' || ch0 == '@') && (ch1 == ' ')) {
+                    directiveComment = true;
+                }
+
                 // Scan for EOL.
                 while (!atEOF() && !isEOL(ch0)) {
                     skip(1);
                 }
                 // Did detect a comment.
-                add(COMMENT, start);
+                add(directiveComment? DIRECTIVE_COMMENT : COMMENT, start);
                 return true;
             } else if (ch1 == '*') {
                 // Skip over /*.
@@ -1623,6 +1630,8 @@
             return valueOfPattern(start, len); // RegexToken::LexerToken
         case XML:
             return valueOfXML(start, len); // XMLToken::LexerToken
+        case DIRECTIVE_COMMENT:
+            return source.getString(start, len);
         default:
             break;
         }
--- a/src/jdk/nashorn/internal/parser/Parser.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/parser/Parser.java	Mon Mar 24 13:51:59 2014 -0700
@@ -26,7 +26,7 @@
 package jdk.nashorn.internal.parser;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.EVAL;
-import static jdk.nashorn.internal.codegen.CompilerConstants.FUNCTION_PREFIX;
+import static jdk.nashorn.internal.codegen.CompilerConstants.ANON_FUNCTION_PREFIX;
 import static jdk.nashorn.internal.codegen.CompilerConstants.RUN_SCRIPT;
 import static jdk.nashorn.internal.parser.TokenType.ASSIGN;
 import static jdk.nashorn.internal.parser.TokenType.CASE;
@@ -389,7 +389,9 @@
             sb.append(parentFunction.getName()).append('$');
         }
 
-        sb.append(ident != null ? ident.getName() : FUNCTION_PREFIX.symbolName());
+        assert ident.getName() != null;
+        sb.append(ident.getName());
+
         final String name = namespace.uniqueName(sb.toString());
         assert parentFunction != null || name.equals(RUN_SCRIPT.symbolName())  : "name = " + name;// must not rename runScript().
 
@@ -419,7 +421,8 @@
                 name,
                 parameters,
                 kind,
-                flags);
+                flags,
+                sourceURL);
 
         lc.push(functionNode);
         // Create new block, and just put it on the context stack, restoreFunctionNode() will associate it with the
@@ -638,6 +641,10 @@
 
         script = restoreFunctionNode(script, token); //commit code
         script = script.setBody(lc, script.getBody().setNeedsScope(lc));
+        // user may have directive comment to set sourceURL
+        if (sourceURL != null) {
+            script = script.setSourceURL(lc, sourceURL);
+        }
 
         return script;
     }
@@ -1792,6 +1799,7 @@
         case THIS:
             final String name = type.getName();
             next();
+            lc.setFlag(lc.getCurrentFunction(), FunctionNode.USES_THIS);
             return new IdentNode(primaryToken, finish, name);
         case IDENT:
             final IdentNode ident = getIdent();
@@ -2132,11 +2140,20 @@
                     final String setterName = setIdent.getPropertyName();
                     final IdentNode setNameNode = new IdentNode(((Node)setIdent).getToken(), finish, NameCodec.encode("set " + setterName));
                     expect(LPAREN);
-                    final IdentNode argIdent = getIdent();
-                    verifyStrictIdent(argIdent, "setter argument");
+                    // be sloppy and allow missing setter parameter even though
+                    // spec does not permit it!
+                    final IdentNode argIdent;
+                    if (type == IDENT || isNonStrictModeIdent()) {
+                        argIdent = getIdent();
+                        verifyStrictIdent(argIdent, "setter argument");
+                    } else {
+                        argIdent = null;
+                    }
                     expect(RPAREN);
                     List<IdentNode> parameters = new ArrayList<>();
-                    parameters.add(argIdent);
+                    if (argIdent != null) {
+                        parameters.add(argIdent);
+                    }
                     functionNode = functionBody(getSetToken, setNameNode, parameters, FunctionNode.Kind.SETTER);
                     return new PropertyNode(propertyToken, finish, setIdent, null, null, functionNode);
 
@@ -2448,7 +2465,7 @@
         // name is null, generate anonymous name
         boolean isAnonymous = false;
         if (name == null) {
-            final String tmpName = "_L" + functionLine;
+            final String tmpName = ANON_FUNCTION_PREFIX.symbolName() + functionLine;
             name = new IdentNode(functionToken, Token.descPosition(functionToken), tmpName);
             isAnonymous = true;
         }
--- a/src/jdk/nashorn/internal/parser/TokenType.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/parser/TokenType.java	Mon Mar 24 13:51:59 2014 -0700
@@ -41,10 +41,14 @@
  */
 @SuppressWarnings("javadoc")
 public enum TokenType {
-    ERROR          (SPECIAL,  null),
-    EOF            (SPECIAL,  null),
-    EOL            (SPECIAL,  null),
-    COMMENT        (SPECIAL,  null),
+    ERROR                (SPECIAL,  null),
+    EOF                  (SPECIAL,  null),
+    EOL                  (SPECIAL,  null),
+    COMMENT              (SPECIAL,  null),
+    // comments of the form //@ foo=bar or //# foo=bar
+    // These comments are treated as special instructions
+    // to the lexer, parser or codegenerator.
+    DIRECTIVE_COMMENT    (SPECIAL,  null),
 
     NOT            (UNARY,   "!",    14, false),
     NE             (BINARY,  "!=",    9, true),
--- a/src/jdk/nashorn/internal/runtime/AccessorProperty.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/AccessorProperty.java	Mon Mar 24 13:51:59 2014 -0700
@@ -141,10 +141,12 @@
     private Class<?> currentType;
 
     /**
-     * Delegate constructor. This is used when adding properties to the Global scope, which
-     * is necessary for outermost levels in a script (the ScriptObject is represented by
-     * a JO-prefixed ScriptObject class, but the properties need to be in the Global scope
-     * and are thus rebound with that as receiver
+     * Delegate constructor for bound properties. This is used for properties created by
+     * {@link ScriptRuntime#mergeScope} and the Nashorn {@code Object.bindProperties} method.
+     * The former is used to add a script's defined globals to the current global scope while
+     * still storing them in a JO-prefixed ScriptObject class.
+     *
+     * <p>All properties created by this constructor have the {@link #IS_BOUND} flag set.</p>
      *
      * @param property  accessor property to rebind
      * @param delegate  delegate object to rebind receiver to
@@ -157,6 +159,8 @@
         this.objectGetter    = bindTo(property.ensureObjectGetter(), delegate);
         this.objectSetter    = bindTo(property.ensureObjectSetter(), delegate);
 
+        // Properties created this way are bound to a delegate
+        this.flags |= IS_BOUND;
         setCurrentType(property.getCurrentType());
     }
 
--- a/src/jdk/nashorn/internal/runtime/Context.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/Context.java	Mon Mar 24 13:51:59 2014 -0700
@@ -36,6 +36,8 @@
 import java.io.PrintWriter;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
 import java.lang.reflect.Modifier;
 import java.util.concurrent.atomic.AtomicLong;
 import java.net.MalformedURLException;
@@ -47,6 +49,7 @@
 import java.security.Permissions;
 import java.security.PrivilegedAction;
 import java.security.ProtectionDomain;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 import jdk.internal.org.objectweb.asm.ClassReader;
@@ -91,6 +94,11 @@
      */
     public static final String NASHORN_JAVA_REFLECTION = "nashorn.JavaReflection";
 
+    /**
+     * Permission to enable nashorn debug mode.
+     */
+    public static final String NASHORN_DEBUG_MODE = "nashorn.debugMode";
+
     // nashorn load psuedo URL prefixes
     private static final String LOAD_CLASSPATH = "classpath:";
     private static final String LOAD_FX = "fx:";
@@ -149,16 +157,19 @@
     /** Is Context global debug mode enabled ? */
     public static final boolean DEBUG = Options.getBooleanProperty("nashorn.debug");
 
-    private static final ThreadLocal<ScriptObject> currentGlobal = new ThreadLocal<>();
+    private static final ThreadLocal<Global> currentGlobal = new ThreadLocal<>();
+
+    // class cache
+    private ClassCache classCache;
 
     /**
      * Get the current global scope
      * @return the current global scope
      */
-    public static ScriptObject getGlobal() {
+    public static Global getGlobal() {
         // This class in a package.access protected package.
         // Trusted code only can call this method.
-        return getGlobalTrusted();
+        return currentGlobal.get();
     }
 
     /**
@@ -167,10 +178,19 @@
      */
     public static void setGlobal(final ScriptObject global) {
         if (global != null && !(global instanceof Global)) {
-            throw new IllegalArgumentException("global is not an instance of Global!");
+            throw new IllegalArgumentException("not a global!");
         }
+        setGlobal((Global)global);
+    }
 
-        setGlobalTrusted(global);
+    /**
+     * Set the current global scope
+     * @param global the global scope
+     */
+    public static void setGlobal(final Global global) {
+        // This class in a package.access protected package.
+        // Trusted code only can call this method.
+        currentGlobal.set(global);
     }
 
     /**
@@ -191,7 +211,7 @@
      * @return error writer of the current context
      */
     public static PrintWriter getCurrentErr() {
-        final ScriptObject global = getGlobalTrusted();
+        final ScriptObject global = getGlobal();
         return (global != null)? global.getContext().getErr() : new PrintWriter(System.err);
     }
 
@@ -344,6 +364,11 @@
             this.classPathLoader = null;
         }
 
+        final int cacheSize = env._class_cache_size;
+        if (cacheSize > 0) {
+            classCache = new ClassCache(cacheSize);
+        }
+
         // print version info if asked.
         if (env._version) {
             getErr().println("nashorn " + Version.version());
@@ -391,7 +416,7 @@
      * @return the property map of the current global scope
      */
     public static PropertyMap getGlobalMap() {
-        return Context.getGlobalTrusted().getMap();
+        return Context.getGlobal().getMap();
     }
 
     /**
@@ -421,7 +446,7 @@
         final String  file       = (location == UNDEFINED || location == null) ? "<eval>" : location.toString();
         final Source  source     = new Source(file, string);
         final boolean directEval = location != UNDEFINED; // is this direct 'eval' call or indirectly invoked eval?
-        final ScriptObject global = Context.getGlobalTrusted();
+        final Global  global = Context.getGlobal();
 
         ScriptObject scope = initialScope;
 
@@ -453,7 +478,7 @@
         // in the caller's environment. A new environment is created!
         if (strictFlag) {
             // Create a new scope object
-            final ScriptObject strictEvalScope = ((GlobalObject)global).newObject();
+            final ScriptObject strictEvalScope = global.newObject();
 
             // bless it as a "scope"
             strictEvalScope.setIsScope();
@@ -578,10 +603,10 @@
      * @throws IOException if source cannot be found or loaded
      */
     public Object loadWithNewGlobal(final Object from, final Object...args) throws IOException {
-        final ScriptObject oldGlobal = getGlobalTrusted();
-        final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction<ScriptObject>() {
+        final Global oldGlobal = getGlobal();
+        final Global newGlobal = AccessController.doPrivileged(new PrivilegedAction<Global>() {
            @Override
-           public ScriptObject run() {
+           public Global run() {
                try {
                    return newGlobal();
                } catch (final RuntimeException e) {
@@ -594,17 +619,17 @@
         }, CREATE_GLOBAL_ACC_CTXT);
         // initialize newly created Global instance
         initGlobal(newGlobal);
-        setGlobalTrusted(newGlobal);
+        setGlobal(newGlobal);
 
         final Object[] wrapped = args == null? ScriptRuntime.EMPTY_ARRAY :  ScriptObjectMirror.wrapArray(args, oldGlobal);
-        newGlobal.put("arguments", ((GlobalObject)newGlobal).wrapAsObject(wrapped), env._strict);
+        newGlobal.put("arguments", newGlobal.wrapAsObject(wrapped), env._strict);
 
         try {
             // wrap objects from newGlobal's world as mirrors - but if result
             // is from oldGlobal's world, unwrap it!
             return ScriptObjectMirror.unwrap(ScriptObjectMirror.wrap(load(newGlobal, from), newGlobal), oldGlobal);
         } finally {
-            setGlobalTrusted(oldGlobal);
+            setGlobal(oldGlobal);
         }
     }
 
@@ -633,7 +658,7 @@
      * Checks that the given Class can be accessed from no permissions context.
      *
      * @param clazz Class object
-     * @throw SecurityException if not accessible
+     * @throws SecurityException if not accessible
      */
     public static void checkPackageAccess(final Class<?> clazz) {
         final SecurityManager sm = System.getSecurityManager();
@@ -650,12 +675,12 @@
      * Checks that the given package name can be accessed from no permissions context.
      *
      * @param pkgName package name
-     * @throw SecurityException if not accessible
+     * @throws SecurityException if not accessible
      */
     public static void checkPackageAccess(final String pkgName) {
         final SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
-            checkPackageAccess(sm, pkgName.endsWith(".")? pkgName : pkgName + ".");
+            checkPackageAccess(sm, pkgName.endsWith(".") ? pkgName : pkgName + ".");
         }
     }
 
@@ -779,7 +804,7 @@
      *
      * @return the initialized global scope object.
      */
-    public ScriptObject createGlobal() {
+    public Global createGlobal() {
         return initGlobal(newGlobal());
     }
 
@@ -787,7 +812,7 @@
      * Create a new uninitialized global scope object
      * @return the global script object
      */
-    public ScriptObject newGlobal() {
+    public Global newGlobal() {
         return new Global(this);
     }
 
@@ -797,20 +822,16 @@
      * @param global the global
      * @return the initialized global scope object.
      */
-    public ScriptObject initGlobal(final ScriptObject global) {
-        if (! (global instanceof GlobalObject)) {
-            throw new IllegalArgumentException("not a global object!");
-        }
-
+    public Global initGlobal(final Global global) {
         // Need only minimal global object, if we are just compiling.
         if (!env._compile_only) {
-            final ScriptObject oldGlobal = Context.getGlobalTrusted();
+            final Global oldGlobal = Context.getGlobal();
             try {
-                Context.setGlobalTrusted(global);
+                Context.setGlobal(global);
                 // initialize global scope with builtin global objects
-                ((GlobalObject)global).initBuiltinObjects();
+                global.initBuiltinObjects();
             } finally {
-                Context.setGlobalTrusted(oldGlobal);
+                Context.setGlobal(oldGlobal);
             }
         }
 
@@ -818,30 +839,15 @@
     }
 
     /**
-     * Trusted variants - package-private
-     */
-
-    /**
-     * Return the current global scope
-     * @return current global scope
+     * Trusted variant - package-private
      */
-    static ScriptObject getGlobalTrusted() {
-        return currentGlobal.get();
-    }
-
-    /**
-     * Set the current global scope
-     */
-    static void setGlobalTrusted(ScriptObject global) {
-         currentGlobal.set(global);
-    }
 
     /**
      * Return the current global's context
      * @return current global's context
      */
     static Context getContextTrusted() {
-        return Context.getGlobalTrusted().getContext();
+        return ((ScriptObject)Context.getGlobal()).getContext();
     }
 
     /**
@@ -910,7 +916,7 @@
         }
 
         // Package as a JavaScript function and pass function back to shell.
-        return ((GlobalObject)Context.getGlobalTrusted()).newScriptFunction(RUN_SCRIPT.symbolName(), runMethodHandle, scope, strict);
+        return Context.getGlobal().newScriptFunction(RUN_SCRIPT.symbolName(), runMethodHandle, scope, strict);
     }
 
     private ScriptFunction compileScript(final Source source, final ScriptObject scope, final ErrorManager errMan) {
@@ -921,16 +927,10 @@
         // start with no errors, no warnings.
         errMan.reset();
 
-        GlobalObject global = null;
-        Class<?> script;
-
-        if (env._class_cache_size > 0) {
-            global = (GlobalObject)Context.getGlobalTrusted();
-            script = global.findCachedClass(source);
-            if (script != null) {
-                Compiler.LOG.fine("Code cache hit for ", source, " avoiding recompile.");
-                return script;
-            }
+        Class<?> script = findCachedClass(source);
+        if (script != null) {
+            Compiler.LOG.fine("Code cache hit for ", source, " avoiding recompile.");
+            return script;
         }
 
         final FunctionNode functionNode = new Parser(env, source, errMan, strict).parse();
@@ -952,17 +952,14 @@
 
         final URL          url    = source.getURL();
         final ScriptLoader loader = env._loader_per_compile ? createNewLoader() : scriptLoader;
-        final CodeSource   cs     = url == null ? null : new CodeSource(url, (CodeSigner[])null);
+        final CodeSource   cs     = new CodeSource(url, (CodeSigner[])null);
         final CodeInstaller<ScriptEnvironment> installer = new ContextCodeInstaller(this, loader, cs);
 
         final Compiler compiler = new Compiler(installer, strict);
 
         final FunctionNode newFunctionNode = compiler.compile(functionNode);
         script = compiler.install(newFunctionNode);
-
-        if (global != null) {
-            global.cacheClass(source, script);
-        }
+        cacheClass(source, script);
 
         return script;
     }
@@ -984,4 +981,60 @@
     private long getUniqueScriptId() {
         return uniqueScriptId.getAndIncrement();
     }
+
+    /**
+     * Cache for compiled script classes.
+     */
+    @SuppressWarnings("serial")
+    private static class ClassCache extends LinkedHashMap<Source, ClassReference> {
+        private final int size;
+        private final ReferenceQueue<Class<?>> queue;
+
+        ClassCache(int size) {
+            super(size, 0.75f, true);
+            this.size = size;
+            this.queue = new ReferenceQueue<>();
+        }
+
+        void cache(final Source source, final Class<?> clazz) {
+            put(source, new ClassReference(clazz, queue, source));
+        }
+
+        @Override
+        protected boolean removeEldestEntry(final Map.Entry<Source, ClassReference> eldest) {
+            return size() > size;
+        }
+
+        @Override
+        public ClassReference get(Object key) {
+            for (ClassReference ref; (ref = (ClassReference)queue.poll()) != null; ) {
+                remove(ref.source);
+            }
+            return super.get(key);
+        }
+
+    }
+
+    private static class ClassReference extends SoftReference<Class<?>> {
+        private final Source source;
+
+        ClassReference(final Class<?> clazz, final ReferenceQueue<Class<?>> queue, final Source source) {
+            super(clazz, queue);
+            this.source = source;
+        }
+    }
+
+    // Class cache management
+    private Class<?> findCachedClass(final Source source) {
+        ClassReference ref = classCache == null ? null : classCache.get(source);
+        return ref != null ? ref.get() : null;
+    }
+
+    private void cacheClass(final Source source, final Class<?> clazz) {
+        if (classCache != null) {
+            classCache.cache(source, clazz);
+        }
+    }
+
+
 }
--- a/src/jdk/nashorn/internal/runtime/DebuggerSupport.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/DebuggerSupport.java	Mon Mar 24 13:51:59 2014 -0700
@@ -75,7 +75,7 @@
      * @return context global.
      */
     static Object getGlobal() {
-        return Context.getGlobalTrusted();
+        return Context.getGlobal();
     }
 
     /**
@@ -87,7 +87,7 @@
      * @return Result of eval as string, or, an exception or null depending on returnException.
      */
     static Object eval(final ScriptObject scope, final Object self, final String string, final boolean returnException) {
-        final ScriptObject global = Context.getGlobalTrusted();
+        final ScriptObject global = Context.getGlobal();
         final ScriptObject initialScope = scope != null ? scope : global;
         final Object callThis = self != null ? self : global;
         final Context context = global.getContext();
--- a/src/jdk/nashorn/internal/runtime/ECMAErrors.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/ECMAErrors.java	Mon Mar 24 13:51:59 2014 -0700
@@ -30,6 +30,8 @@
 import java.util.ResourceBundle;
 import jdk.nashorn.api.scripting.NashornException;
 import jdk.nashorn.internal.scripts.JS;
+import jdk.nashorn.internal.codegen.CompilerConstants;
+import jdk.nashorn.internal.objects.Global;
 
 /**
  * Helper class to throw various standard "ECMA error" exceptions such as Error, ReferenceError, TypeError etc.
@@ -65,7 +67,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException asEcmaException(final ParserException e) {
-        return asEcmaException(Context.getGlobalTrusted(), e);
+        return asEcmaException(Context.getGlobal(), e);
     }
 
     /**
@@ -77,11 +79,11 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException asEcmaException(final ScriptObject global, final ParserException e) {
+    public static ECMAException asEcmaException(final Global global, final ParserException e) {
         final JSErrorType errorType = e.getErrorType();
         assert errorType != null : "error type for " + e + " was null";
 
-        final GlobalObject globalObj = (GlobalObject)global;
+        final Global globalObj    = global;
         final String       msg    = e.getMessage();
 
         // translate to ECMAScript Error object using error type
@@ -115,7 +117,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException syntaxError(final String msgId, final String... args) {
-        return syntaxError(Context.getGlobalTrusted(), msgId, args);
+        return syntaxError(Context.getGlobal(), msgId, args);
     }
 
     /**
@@ -127,7 +129,7 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException syntaxError(final ScriptObject global, final String msgId, final String... args) {
+    public static ECMAException syntaxError(final Global global, final String msgId, final String... args) {
         return syntaxError(global, null, msgId, args);
     }
 
@@ -141,7 +143,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException syntaxError(final Throwable cause, final String msgId, final String... args) {
-        return syntaxError(Context.getGlobalTrusted(), cause, msgId, args);
+        return syntaxError(Context.getGlobal(), cause, msgId, args);
     }
 
     /**
@@ -154,9 +156,9 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException syntaxError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+    public static ECMAException syntaxError(final Global global, final Throwable cause, final String msgId, final String... args) {
         final String msg = getMessage("syntax.error." + msgId, args);
-        return error(((GlobalObject)global).newSyntaxError(msg), cause);
+        return error(global.newSyntaxError(msg), cause);
     }
 
     /**
@@ -168,7 +170,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException typeError(final String msgId, final String... args) {
-        return typeError(Context.getGlobalTrusted(), msgId, args);
+        return typeError(Context.getGlobal(), msgId, args);
     }
 
     /**
@@ -180,7 +182,7 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException typeError(final ScriptObject global, final String msgId, final String... args) {
+    public static ECMAException typeError(final Global global, final String msgId, final String... args) {
         return typeError(global, null, msgId, args);
     }
 
@@ -194,7 +196,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException typeError(final Throwable cause, final String msgId, final String... args) {
-        return typeError(Context.getGlobalTrusted(), cause, msgId, args);
+        return typeError(Context.getGlobal(), cause, msgId, args);
     }
 
     /**
@@ -207,9 +209,9 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException typeError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+    public static ECMAException typeError(final Global global, final Throwable cause, final String msgId, final String... args) {
         final String msg = getMessage("type.error." + msgId, args);
-        return error(((GlobalObject)global).newTypeError(msg), cause);
+        return error(global.newTypeError(msg), cause);
     }
 
     /**
@@ -221,7 +223,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException rangeError(final String msgId, final String... args) {
-        return rangeError(Context.getGlobalTrusted(), msgId, args);
+        return rangeError(Context.getGlobal(), msgId, args);
     }
 
     /**
@@ -233,7 +235,7 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException rangeError(final ScriptObject global, final String msgId, final String... args) {
+    public static ECMAException rangeError(final Global global, final String msgId, final String... args) {
         return rangeError(global, null, msgId, args);
     }
 
@@ -247,7 +249,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException rangeError(final Throwable cause, final String msgId, final String... args) {
-        return rangeError(Context.getGlobalTrusted(), cause, msgId, args);
+        return rangeError(Context.getGlobal(), cause, msgId, args);
     }
 
     /**
@@ -260,9 +262,9 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException rangeError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+    public static ECMAException rangeError(final Global global, final Throwable cause, final String msgId, final String... args) {
         final String msg = getMessage("range.error." + msgId, args);
-        return error(((GlobalObject)global).newRangeError(msg), cause);
+        return error(global.newRangeError(msg), cause);
     }
 
     /**
@@ -274,7 +276,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException referenceError(final String msgId, final String... args) {
-        return referenceError(Context.getGlobalTrusted(), msgId, args);
+        return referenceError(Context.getGlobal(), msgId, args);
     }
 
     /**
@@ -286,7 +288,7 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException referenceError(final ScriptObject global, final String msgId, final String... args) {
+    public static ECMAException referenceError(final Global global, final String msgId, final String... args) {
         return referenceError(global, null, msgId, args);
     }
 
@@ -300,7 +302,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException referenceError(final Throwable cause, final String msgId, final String... args) {
-        return referenceError(Context.getGlobalTrusted(), cause, msgId, args);
+        return referenceError(Context.getGlobal(), cause, msgId, args);
     }
 
     /**
@@ -313,9 +315,9 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException referenceError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+    public static ECMAException referenceError(final Global global, final Throwable cause, final String msgId, final String... args) {
         final String msg = getMessage("reference.error." + msgId, args);
-        return error(((GlobalObject)global).newReferenceError(msg), cause);
+        return error(global.newReferenceError(msg), cause);
     }
 
     /**
@@ -327,7 +329,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException uriError(final String msgId, final String... args) {
-        return uriError(Context.getGlobalTrusted(), msgId, args);
+        return uriError(Context.getGlobal(), msgId, args);
     }
 
     /**
@@ -339,7 +341,7 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException uriError(final ScriptObject global, final String msgId, final String... args) {
+    public static ECMAException uriError(final Global global, final String msgId, final String... args) {
         return uriError(global, null, msgId, args);
     }
 
@@ -353,7 +355,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException uriError(final Throwable cause, final String msgId, final String... args) {
-        return uriError(Context.getGlobalTrusted(), cause, msgId, args);
+        return uriError(Context.getGlobal(), cause, msgId, args);
     }
 
     /**
@@ -366,9 +368,9 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException uriError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+    public static ECMAException uriError(final Global global, final Throwable cause, final String msgId, final String... args) {
         final String msg = getMessage("uri.error." + msgId, args);
-        return error(((GlobalObject)global).newURIError(msg), cause);
+        return error(global.newURIError(msg), cause);
     }
 
     /**
@@ -401,7 +403,7 @@
         final String className = frame.getClassName();
 
         // Look for script package in class name (into which compiler puts generated code)
-        if (className.startsWith(scriptPackage)) {
+        if (className.startsWith(scriptPackage) && !frame.getMethodName().startsWith(CompilerConstants.INTERNAL_METHOD_PREFIX)) {
             final String source = frame.getFileName();
             /*
              * Make sure that it is not some Java code that Nashorn has in that package!
--- a/src/jdk/nashorn/internal/runtime/ECMAException.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/ECMAException.java	Mon Mar 24 13:51:59 2014 -0700
@@ -25,7 +25,7 @@
 
 package jdk.nashorn.internal.runtime;
 
-import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
+import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
 import static jdk.nashorn.internal.codegen.CompilerConstants.virtualField;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
 
@@ -44,9 +44,9 @@
 @SuppressWarnings("serial")
 public final class ECMAException extends NashornException {
     /**
-     * Method handle pointing to the constructor {@link ECMAException#ECMAException(Object, String, int, int)},
+     * Method handle pointing to the constructor {@link ECMAException#create(Object, String, int, int)},
      */
-    public static final Call THROW_INIT = constructorNoLookup(ECMAException.class, Object.class, String.class, int.class, int.class);
+    public static final Call CREATE = staticCallNoLookup(ECMAException.class, "create", ECMAException.class, Object.class, String.class, int.class, int.class);
 
     /** Field handle to the{@link ECMAException#thrown} field, so that it can be accessed from generated code */
     public static final FieldAccess THROWN = virtualField(ECMAException.class, "thrown", Object.class);
@@ -57,23 +57,21 @@
     public final Object thrown;
 
     /**
-     * Constructor. This is called from generated code to implement the {@code throw}
-     * instruction from generated script code
+     * Constructor. Called from the factory method 'create'.
      *
      * @param thrown    object to be thrown
      * @param fileName  script file name
      * @param line      line number of throw
      * @param column    column number of throw
      */
-    public ECMAException(final Object thrown, final String fileName, final int line, final int column) {
+    private ECMAException(final Object thrown, final String fileName, final int line, final int column) {
         super(ScriptRuntime.safeToString(thrown), asThrowable(thrown), fileName, line, column);
         this.thrown = thrown;
         setExceptionToThrown();
     }
 
     /**
-     * Constructor. This is called from runtime code in Nashorn to throw things like
-     * type errors.
+     * Constructor. This is called from the runtime code.
      *
      * @param thrown   object to be thrown
      * @param cause    Java exception that triggered this throw
@@ -85,9 +83,39 @@
     }
 
     /**
+     * Factory method to retrieve the underlying exception or create an exception.
+     * This method is called from the generated code.
+     *
+     * @param thrown    object to be thrown
+     * @param fileName  script file name
+     * @param line      line number of throw
+     * @param column    column number of throw
+     * @return ECMAException object
+     */
+    public static ECMAException create(final Object thrown, final String fileName, final int line, final int column) {
+        // If thrown object is an Error or sub-object like TypeError, then
+        // an ECMAException object has been already initialized at constructor.
+        if (thrown instanceof ScriptObject) {
+            ScriptObject sobj = (ScriptObject)thrown;
+            Object exception = getException(sobj);
+            if (exception instanceof ECMAException) {
+                // copy over file name, line number and column number.
+                final ECMAException ee = (ECMAException)exception;
+                ee.setFileName(fileName);
+                ee.setLineNumber(line);
+                ee.setColumnNumber(column);
+                return ee;
+            }
+        }
+
+        return new ECMAException(thrown, fileName, line, column);
+    }
+
+    /**
      * Get the thrown object
      * @return thrown object
      */
+    @Override
     public Object getThrown() {
         return thrown;
     }
@@ -256,6 +284,8 @@
             final ScriptObject sobj = (ScriptObject)thrown;
             if (!sobj.has(EXCEPTION_PROPERTY)) {
                 sobj.addOwnProperty(EXCEPTION_PROPERTY, Property.NOT_ENUMERABLE, this);
+            } else {
+                sobj.set(EXCEPTION_PROPERTY, this, false);
             }
         }
     }
--- a/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java	Mon Mar 24 13:51:59 2014 -0700
@@ -38,31 +38,27 @@
     /**
      * Constructor - used for bind
      *
-     * @param name          name
-     * @param arity         arity
-     * @param functions     precompiled code
-     * @param isStrict      strict
-     * @param isBuiltin     builtin
-     * @param isConstructor constructor
+     * @param name      name
+     * @param arity     arity
+     * @param functions precompiled code
+     * @param flags     {@link ScriptFunctionData} flags
      */
-    FinalScriptFunctionData(final String name, int arity, CompiledFunctions functions, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) {
-        super(name, arity, isStrict, isBuiltin, isConstructor);
+    FinalScriptFunctionData(final String name, final int arity, final CompiledFunctions functions, final int flags) {
+        super(name, arity, flags);
         code.addAll(functions);
     }
 
     /**
-     * Constructor - used from ScriptFunction. This assumes that we have code alraedy for the
+     * Constructor - used from ScriptFunction. This assumes that we have code already for the
      * method (typically a native method) and possibly specializations.
      *
-     * @param name           name
-     * @param mh             method handle for generic version of method
-     * @param specs          specializations
-     * @param isStrict       strict
-     * @param isBuiltin      builtin
-     * @param isConstructor  constructor
+     * @param name  name
+     * @param mh    method handle for generic version of method
+     * @param specs specializations
+     * @param flags {@link ScriptFunctionData} flags
      */
-    FinalScriptFunctionData(final String name, final MethodHandle mh, final MethodHandle[] specs, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) {
-        super(name, arity(mh), isStrict, isBuiltin, isConstructor);
+    FinalScriptFunctionData(final String name, final MethodHandle mh, final MethodHandle[] specs, final int flags) {
+        super(name, arity(mh), flags);
 
         addInvoker(mh);
         if (specs != null) {
--- a/src/jdk/nashorn/internal/runtime/FindProperty.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/FindProperty.java	Mon Mar 24 13:51:59 2014 -0700
@@ -112,7 +112,7 @@
         return property != null && property.hasGetterFunction(prototype) ? self : prototype;
     }
 
-   /**
+    /**
      * Return the appropriate receiver for a setter.
      * @return appropriate receiver
      */
@@ -172,5 +172,20 @@
         property.setObjectValue(getSetterReceiver(), getOwner(), value, strict);
     }
 
+    /**
+     * Get the number of objects in the prototype chain between the {@code self} and the
+     * {@code owner} objects.
+     * @return the prototype chain length
+     */
+    int getProtoChainLength() {
+        assert self != null;
+        int length = 0;
+        for (ScriptObject obj = self; obj != prototype; obj = obj.getProto()) {
+            assert !(obj instanceof WithObject);
+            ++length;
+        }
+        return length;
+    }
+
 }
 
--- a/src/jdk/nashorn/internal/runtime/GlobalObject.java	Mon Mar 24 13:16:11 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,244 +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.lang.invoke.MethodHandle;
-import java.util.concurrent.Callable;
-import jdk.internal.dynalink.linker.GuardedInvocation;
-import jdk.internal.dynalink.linker.LinkRequest;
-import jdk.nashorn.internal.runtime.linker.InvokeByName;
-
-/**
- * Runtime interface to the global scope objects.
- */
-
-public interface GlobalObject {
-    /**
-     * Is this global of the given Context?
-     * @param ctxt the context
-     * @return true if this global belongs to the given Context
-     */
-    public boolean isOfContext(final Context ctxt);
-
-    /**
-     * Does this global belong to a strict Context?
-     * @return true if this global belongs to a strict Context
-     */
-    public boolean isStrictContext();
-
-    /**
-     * Initialize standard builtin objects like "Object", "Array", "Function" etc.
-     * as well as our extension builtin objects like "Java", "JSAdapter" as properties
-     * of the global scope object.
-     */
-    public void initBuiltinObjects();
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newScriptFunction(String, MethodHandle, ScriptObject, boolean)}
-     *
-     * @param name   function name
-     * @param handle invocation handle for function
-     * @param scope  the scope
-     * @param strict are we in strict mode
-     *
-     * @return new script function
-     */
-   public ScriptFunction newScriptFunction(String name, MethodHandle handle, ScriptObject scope, boolean strict);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#wrapAsObject(Object)}
-     *
-     * @param obj object to wrap
-     * @return    wrapped object
-     */
-   public Object wrapAsObject(Object obj);
-
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#primitiveLookup(LinkRequest, Object)}
-     *
-     * @param request the link request for the dynamic call site.
-     * @param self     self reference
-     *
-     * @return guarded invocation
-     */
-   public GuardedInvocation primitiveLookup(LinkRequest request, Object self);
-
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newObject()}
-     *
-     * @return the new ScriptObject
-     */
-   public ScriptObject newObject();
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#isError(ScriptObject)}
-     *
-     * @param sobj to check if it is an error object
-     * @return true if error object
-     */
-   public boolean isError(ScriptObject sobj);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newError(String)}
-     *
-     * @param msg the error message
-     *
-     * @return the new ScriptObject representing the error
-     */
-   public ScriptObject newError(String msg);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newEvalError(String)}
-     *
-     * @param msg the error message
-     *
-     * @return the new ScriptObject representing the eval error
-     */
-   public ScriptObject newEvalError(String msg);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newRangeError(String)}
-     *
-     * @param msg the error message
-     *
-     * @return the new ScriptObject representing the range error
-     */
-   public ScriptObject newRangeError(String msg);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newReferenceError(String)}
-     *
-     * @param msg the error message
-     *
-     * @return the new ScriptObject representing the reference error
-     */
-   public ScriptObject newReferenceError(String msg);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newSyntaxError(String)}
-     *
-     * @param msg the error message
-     *
-     * @return the new ScriptObject representing the syntax error
-     */
-   public ScriptObject newSyntaxError(String msg);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newTypeError(String)}
-     *
-     * @param msg the error message
-     *
-     * @return the new ScriptObject representing the type error
-     */
-   public ScriptObject newTypeError(String msg);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newURIError(String)}
-     *
-     * @param msg the error message
-     *
-     * @return the new ScriptObject representing the URI error
-     */
-    public ScriptObject newURIError(String msg);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newGenericDescriptor(boolean, boolean)}
-     *
-     * @param configurable is the described property configurable
-     * @param enumerable   is the described property enumerable
-     *
-     * @return property descriptor
-     */
-    public PropertyDescriptor newGenericDescriptor(boolean configurable, boolean enumerable);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newDataDescriptor(Object, boolean, boolean, boolean)}
-     *
-     * @param value        data value
-     * @param configurable is the described property configurable
-     * @param enumerable   is the described property enumerable
-     * @param writable     is the described property writable
-     *
-     * @return property descriptor
-     */
-    public PropertyDescriptor newDataDescriptor(Object value, boolean configurable, boolean enumerable, boolean writable);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newAccessorDescriptor(Object, Object, boolean, boolean)}
-     *
-     * @param get          property getter, or null if none
-     * @param set          property setter, or null if none
-     * @param configurable is the described property configurable
-     * @param enumerable   is the described property enumerable
-     *
-     * @return property descriptor
-     */
-    public PropertyDescriptor newAccessorDescriptor(Object get, Object set, boolean configurable, boolean enumerable);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#getDefaultValue(ScriptObject, Class)}
-     *
-     * @param sobj     script object
-     * @param typeHint type hint
-     *
-     * @return default value
-     */
-    public Object getDefaultValue(ScriptObject sobj, Class<?> typeHint);
-
-    /**
-     * Find the compiled Class for the given script source, if available
-     *
-     * @param source Source object of the script
-     * @return compiled Class object or null
-     */
-    public Class<?> findCachedClass(Source source);
-
-    /**
-     * Put the Source associated Class object in the Source-to-Class cache
-     *
-     * @param source Source of the script
-     * @param clazz compiled Class object for the source
-     */
-    public void cacheClass(Source source, Class<?> clazz);
-
-    /**
-     * Get cached InvokeByName object for the given key
-     * @param key key to be associated with InvokeByName object
-     * @param creator if InvokeByName is absent 'creator' is called to make one (lazy init)
-     * @return InvokeByName object associated with the key.
-     */
-    public InvokeByName getInvokeByName(final Object key, final Callable<InvokeByName> creator);
-
-    /**
-     * Get cached dynamic method handle for the given key
-     * @param key key to be associated with dynamic method handle
-     * @param creator if method handle is absent 'creator' is called to make one (lazy init)
-     * @return dynamic method handle associated with the key.
-     */
-    public MethodHandle getDynamicInvoker(final Object key, final Callable<MethodHandle> creator);
-}
--- a/src/jdk/nashorn/internal/runtime/JSONFunctions.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/JSONFunctions.java	Mon Mar 24 13:51:59 2014 -0700
@@ -33,6 +33,7 @@
 import jdk.nashorn.internal.ir.ObjectNode;
 import jdk.nashorn.internal.ir.PropertyNode;
 import jdk.nashorn.internal.ir.UnaryNode;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.parser.JSONParser;
 import jdk.nashorn.internal.parser.TokenType;
 import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
@@ -47,7 +48,7 @@
     private static final Object REVIVER_INVOKER = new Object();
 
     private static MethodHandle getREVIVER_INVOKER() {
-        return ((GlobalObject)Context.getGlobal()).getDynamicInvoker(REVIVER_INVOKER,
+        return Context.getGlobal().getDynamicInvoker(REVIVER_INVOKER,
                 new Callable<MethodHandle>() {
                     @Override
                     public MethodHandle call() {
@@ -88,7 +89,7 @@
             throw ECMAErrors.syntaxError(e, "invalid.json", e.getMessage());
         }
 
-        final ScriptObject global = Context.getGlobalTrusted();
+        final Global global = Context.getGlobal();
         Object unfiltered = convertNode(global, node);
         return applyReviver(global, unfiltered, reviver);
     }
@@ -98,10 +99,9 @@
     // parse helpers
 
     // apply 'reviver' function if available
-    private static Object applyReviver(final ScriptObject global, final Object unfiltered, final Object reviver) {
+    private static Object applyReviver(final Global global, final Object unfiltered, final Object reviver) {
         if (reviver instanceof ScriptFunction) {
-            assert global instanceof GlobalObject;
-            final ScriptObject root = ((GlobalObject)global).newObject();
+            final ScriptObject root = global.newObject();
             root.addOwnProperty("", Property.WRITABLE_ENUMERABLE_CONFIGURABLE, unfiltered);
             return walk(root, "", (ScriptFunction)reviver);
         }
@@ -138,8 +138,8 @@
     }
 
     // Converts IR node to runtime value
-    private static Object convertNode(final ScriptObject global, final Node node) {
-        assert global instanceof GlobalObject;
+    private static Object convertNode(final Global global, final Node node) {
+        assert global instanceof Global;
 
         if (node instanceof LiteralNode) {
             // check for array literal
@@ -157,7 +157,7 @@
                     for (final Node elem : elements) {
                         values[index++] = JSType.toNumber(convertNode(global, elem));
                     }
-                    return ((GlobalObject)global).wrapAsObject(values);
+                    return global.wrapAsObject(values);
                 }
 
                 final Object[] values = new Object[elements.length];
@@ -167,14 +167,14 @@
                     values[index++] = convertNode(global, elem);
                 }
 
-                return ((GlobalObject)global).wrapAsObject(values);
+                return global.wrapAsObject(values);
             }
 
             return ((LiteralNode<?>)node).getValue();
 
         } else if (node instanceof ObjectNode) {
             final ObjectNode   objNode  = (ObjectNode) node;
-            final ScriptObject object   = ((GlobalObject)global).newObject();
+            final ScriptObject object   = global.newObject();
 
             for (final PropertyNode pNode: objNode.getElements()) {
                 final Node         valueNode = pNode.getValue();
--- a/src/jdk/nashorn/internal/runtime/JSType.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/JSType.java	Mon Mar 24 13:51:59 2014 -0700
@@ -36,6 +36,7 @@
 import jdk.internal.dynalink.beans.StaticClass;
 import jdk.nashorn.api.scripting.JSObject;
 import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.parser.Lexer;
 import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
@@ -852,7 +853,7 @@
      * @return the wrapped object
      */
     public static Object toScriptObject(final Object obj) {
-        return toScriptObject(Context.getGlobalTrusted(), obj);
+        return toScriptObject(Context.getGlobal(), obj);
     }
 
     /**
@@ -865,7 +866,7 @@
      *
      * @return the wrapped object
      */
-    public static Object toScriptObject(final ScriptObject global, final Object obj) {
+    public static Object toScriptObject(final Global global, final Object obj) {
         if (nullOrUndefined(obj)) {
             throw typeError(global, "not.an.object", ScriptRuntime.safeToString(obj));
         }
@@ -874,7 +875,7 @@
             return obj;
         }
 
-        return ((GlobalObject)global).wrapAsObject(obj);
+        return global.wrapAsObject(obj);
     }
 
     /**
@@ -984,7 +985,7 @@
         if (obj instanceof ScriptObject) {
             if (safe) {
                 final ScriptObject sobj = (ScriptObject)obj;
-                final GlobalObject gobj = (GlobalObject)Context.getGlobalTrusted();
+                final Global gobj = Context.getGlobal();
                 return gobj.isError(sobj) ?
                     ECMAException.safeToString(sobj) :
                     sobj.safeToString();
--- a/src/jdk/nashorn/internal/runtime/ListAdapter.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/ListAdapter.java	Mon Mar 24 13:51:59 2014 -0700
@@ -34,6 +34,7 @@
 import java.util.concurrent.Callable;
 import jdk.nashorn.api.scripting.JSObject;
 import jdk.nashorn.api.scripting.ScriptObjectMirror;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
 import jdk.nashorn.internal.runtime.linker.InvokeByName;
 
@@ -54,7 +55,7 @@
     // These add to the back and front of the list
     private static final Object PUSH    = new Object();
     private static InvokeByName getPUSH() {
-        return ((GlobalObject)Context.getGlobal()).getInvokeByName(PUSH,
+        return Context.getGlobal().getInvokeByName(PUSH,
                 new Callable<InvokeByName>() {
                     @Override
                     public InvokeByName call() {
@@ -65,7 +66,7 @@
 
     private static final Object UNSHIFT = new Object();
     private static InvokeByName getUNSHIFT() {
-        return ((GlobalObject)Context.getGlobal()).getInvokeByName(UNSHIFT,
+        return Context.getGlobal().getInvokeByName(UNSHIFT,
                 new Callable<InvokeByName>() {
                     @Override
                     public InvokeByName call() {
@@ -77,7 +78,7 @@
     // These remove from the back and front of the list
     private static final Object POP = new Object();
     private static InvokeByName getPOP() {
-        return ((GlobalObject)Context.getGlobal()).getInvokeByName(POP,
+        return Context.getGlobal().getInvokeByName(POP,
                 new Callable<InvokeByName>() {
                     @Override
                     public InvokeByName call() {
@@ -88,7 +89,7 @@
 
     private static final Object SHIFT = new Object();
     private static InvokeByName getSHIFT() {
-        return ((GlobalObject)Context.getGlobal()).getInvokeByName(SHIFT,
+        return Context.getGlobal().getInvokeByName(SHIFT,
                 new Callable<InvokeByName>() {
                     @Override
                     public InvokeByName call() {
@@ -100,7 +101,7 @@
     // These insert and remove in the middle of the list
     private static final Object SPLICE_ADD = new Object();
     private static InvokeByName getSPLICE_ADD() {
-        return ((GlobalObject)Context.getGlobal()).getInvokeByName(SPLICE_ADD,
+        return Context.getGlobal().getInvokeByName(SPLICE_ADD,
                 new Callable<InvokeByName>() {
                     @Override
                     public InvokeByName call() {
@@ -111,7 +112,7 @@
 
     private static final Object SPLICE_REMOVE = new Object();
     private static InvokeByName getSPLICE_REMOVE() {
-        return ((GlobalObject)Context.getGlobal()).getInvokeByName(SPLICE_REMOVE,
+        return  Context.getGlobal().getInvokeByName(SPLICE_REMOVE,
                 new Callable<InvokeByName>() {
                     @Override
                     public InvokeByName call() {
--- a/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java	Mon Mar 24 13:51:59 2014 -0700
@@ -35,7 +35,6 @@
 import jdk.internal.dynalink.support.Guards;
 import jdk.nashorn.internal.lookup.MethodHandleFactory;
 import jdk.nashorn.internal.lookup.MethodHandleFunctionality;
-import jdk.nashorn.internal.objects.NativeJava;
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Function;
 
@@ -52,7 +51,7 @@
  * var ArrayList = java.util.ArrayList
  * var list = new ArrayList
  * </pre>
- * You can also use {@link NativeJava#type(Object, Object)} to access Java classes. These two statements are mostly
+ * You can also use {@link jdk.nashorn.internal.objects.NativeJava#type(Object, Object)} to access Java classes. These two statements are mostly
  * equivalent:
  * <pre>
  * var listType1 = java.util.ArrayList
@@ -198,24 +197,13 @@
     @Override
     public GuardedInvocation noSuchProperty(final CallSiteDescriptor desc, final LinkRequest request) {
         final String propertyName = desc.getNameToken(2);
-        final String fullName     = name.isEmpty() ? propertyName : name + "." + propertyName;
-
-        final Context context = Context.getContextTrusted();
+        createProperty(propertyName);
+        return super.lookup(desc, request);
+    }
 
-        Class<?> javaClass = null;
-        try {
-            javaClass = context.findClass(fullName);
-        } catch (final NoClassDefFoundError | ClassNotFoundException e) {
-            //ignored
-        }
-
-        if (javaClass == null) {
-            set(propertyName, new NativeJavaPackage(fullName, getProto()), false);
-        } else {
-            set(propertyName, StaticClass.forClass(javaClass), false);
-        }
-
-        return super.lookup(desc, request);
+    @Override
+    protected Object invokeNoSuchProperty(final String name) {
+        return createProperty(name);
     }
 
     @Override
@@ -226,4 +214,26 @@
     private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
         return MH.findStatic(MethodHandles.lookup(), NativeJavaPackage.class, name, MH.type(rtype, types));
     }
+
+    private Object createProperty(final String propertyName) {
+        final String fullName     = name.isEmpty() ? propertyName : name + "." + propertyName;
+        final Context context = Context.getContextTrusted();
+
+        Class<?> javaClass = null;
+        try {
+            javaClass = context.findClass(fullName);
+        } catch (final NoClassDefFoundError | ClassNotFoundException e) {
+            //ignored
+        }
+
+        final Object propertyValue;
+        if (javaClass == null) {
+            propertyValue = new NativeJavaPackage(fullName, getProto());
+        } else {
+            propertyValue = StaticClass.forClass(javaClass);
+        }
+
+        set(propertyName, propertyValue, false);
+        return propertyValue;
+    }
 }
--- a/src/jdk/nashorn/internal/runtime/ParserException.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/ParserException.java	Mon Mar 24 13:51:59 2014 -0700
@@ -26,6 +26,7 @@
 package jdk.nashorn.internal.runtime;
 
 import jdk.nashorn.api.scripting.NashornException;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.parser.Token;
 
 /**
@@ -110,7 +111,7 @@
      * Throw this {@code ParserException} as one of the 7 native JavaScript errors
      * @param global global scope object
      */
-    public void throwAsEcmaException(final ScriptObject global) {
+    public void throwAsEcmaException(final Global global) {
         throw ECMAErrors.asEcmaException(global, this);
     }
 }
--- a/src/jdk/nashorn/internal/runtime/Property.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/Property.java	Mon Mar 24 13:51:59 2014 -0700
@@ -84,9 +84,13 @@
     /** Can this property be undefined? */
     public static final int CAN_BE_UNDEFINED = 1 << 8;
 
-    /* Is this a function declaration property ? */
+    /** Is this a function declaration property ? */
     public static final int IS_FUNCTION_DECLARATION = 1 << 9;
 
+    /** Is this property bound to a receiver? This means get/set operations will be delegated to
+     *  a statically defined object instead of the object passed as callsite parameter. */
+    public static final int IS_BOUND = 1 << 10;
+
     /** Property key. */
     private final String key;
 
@@ -252,6 +256,16 @@
     }
 
     /**
+     * Is this property bound to a receiver? If this method returns {@code true} get and set operations
+     * will be delegated to a statically bound object instead of the object passed as parameter.
+     *
+     * @return true if this is a bound property
+     */
+    public boolean isBound() {
+        return (flags & IS_BOUND) == IS_BOUND;
+    }
+
+    /**
      * Does this property use any slots in the spill array described in
      * {@link Property#isSpill}? In that case how many. Currently a property
      * only uses max one spill slot, but this may change in future representations
--- a/src/jdk/nashorn/internal/runtime/PropertyDescriptor.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/PropertyDescriptor.java	Mon Mar 24 13:51:59 2014 -0700
@@ -151,5 +151,12 @@
      * @return true if property exists in implementor
      */
     public boolean has(Object key);
+
+    /**
+     * Check existence and compare attributes of descriptors.
+     *
+     * @return true if every field of this desc exists in otherDesc and has the same value.
+     */
+    public boolean hasAndEquals(PropertyDescriptor otherDesc);
 }
 
--- a/src/jdk/nashorn/internal/runtime/PropertyListener.java	Mon Mar 24 13:16:11 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +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;
-
-/**
- * Property change listener gets notified whenever properties are added/deleted/modified.
- */
-public interface PropertyListener {
-    /**
-     * A new property is being added.
-     *
-     * @param object The ScriptObject to which property was added.
-     * @param prop The new Property added.
-     */
-    public void propertyAdded(ScriptObject object, Property prop);
-
-    /**
-     * An existing property is being deleted.
-     *
-     * @param object The ScriptObject whose property is being deleted.
-     * @param prop The property being deleted.
-     */
-    public void propertyDeleted(ScriptObject object, Property prop);
-
-    /**
-     * An existing Property is being replaced with a new Property.
-     *
-     * @param object The ScriptObject whose property is being modified.
-     * @param oldProp The old property that is being replaced.
-     * @param newProp The new property that replaces the old property.
-     *
-     */
-    public void propertyModified(ScriptObject object, Property oldProp, Property newProp);
-
-    /**
-     * Given object's __proto__ has changed.
-     *
-     * @param object object whose __proto__ has changed.
-     * @param oldProto old __proto__
-     * @param newProto new __proto__
-     */
-    public void protoChanged(ScriptObject object, ScriptObject oldProto, ScriptObject newProto);
-}
--- a/src/jdk/nashorn/internal/runtime/PropertyListenerManager.java	Mon Mar 24 13:16:11 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +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.Map;
-import java.util.WeakHashMap;
-
-/**
- * Helper class to manage property listeners and notification.
- */
-public class PropertyListenerManager implements PropertyListener {
-    PropertyListenerManager() {}
-
-    /** property listeners for this object. */
-    private Map<PropertyListener,Boolean> listeners;
-
-    // These counters are updated in debug mode
-    private static int listenersAdded;
-    private static int listenersRemoved;
-
-    /**
-     * Return aggregate listeners added to all PropertyListenerManagers
-     * @return the listenersAdded
-     */
-    public static int getListenersAdded() {
-        return listenersAdded;
-    }
-
-    /**
-     * Return aggregate listeners removed from all PropertyListenerManagers
-     * @return the listenersRemoved
-     */
-    public static int getListenersRemoved() {
-        return listenersRemoved;
-    }
-
-    /**
-     * Return listeners added to this PropertyListenerManager.
-     * @return the listener count
-     */
-    public final int getListenerCount() {
-        return listeners != null? listeners.size() : 0;
-    }
-
-    // Property listener management methods
-
-    /**
-     * Add a property listener to this object.
-     *
-     * @param listener The property listener that is added.
-     */
-    public synchronized final void addPropertyListener(final PropertyListener listener) {
-        if (listeners == null) {
-            listeners = new WeakHashMap<>();
-        }
-
-        if (Context.DEBUG) {
-            listenersAdded++;
-        }
-        listeners.put(listener, Boolean.TRUE);
-    }
-
-    /**
-     * Remove a property listener from this object.
-     *
-     * @param listener The property listener that is removed.
-     */
-    public synchronized final void removePropertyListener(final PropertyListener listener) {
-        if (listeners != null) {
-            if (Context.DEBUG) {
-                listenersRemoved++;
-            }
-            listeners.remove(listener);
-        }
-    }
-
-    /**
-     * This method can be called to notify property addition to this object's listeners.
-     *
-     * @param object The ScriptObject to which property was added.
-     * @param prop The property being added.
-     */
-    protected synchronized final void notifyPropertyAdded(final ScriptObject object, final Property prop) {
-        if (listeners != null) {
-            for (PropertyListener listener : listeners.keySet()) {
-                listener.propertyAdded(object, prop);
-            }
-        }
-    }
-
-    /**
-     * This method can be called to notify property deletion to this object's listeners.
-     *
-     * @param object The ScriptObject from which property was deleted.
-     * @param prop The property being deleted.
-     */
-    protected synchronized final void notifyPropertyDeleted(final ScriptObject object, final Property prop) {
-        if (listeners != null) {
-            for (PropertyListener listener : listeners.keySet()) {
-                listener.propertyDeleted(object, prop);
-            }
-        }
-    }
-
-    /**
-     * This method can be called to notify property modification to this object's listeners.
-     *
-     * @param object The ScriptObject to which property was modified.
-     * @param oldProp The old property being replaced.
-     * @param newProp The new property that replaces the old property.
-     */
-    protected synchronized final void notifyPropertyModified(final ScriptObject object, final Property oldProp, final Property newProp) {
-        if (listeners != null) {
-            for (PropertyListener listener : listeners.keySet()) {
-                listener.propertyModified(object, oldProp, newProp);
-            }
-        }
-    }
-
-    /**
-     * This method can be called to notify __proto__ modification to this object's listeners.
-     *
-     * @param object The ScriptObject whose __proto__ was changed.
-     * @param oldProto old __proto__
-     * @param newProto new __proto__
-     */
-    protected synchronized final void notifyProtoChanged(final ScriptObject object, final ScriptObject oldProto, final ScriptObject newProto) {
-        if (listeners != null) {
-            for (PropertyListener listener : listeners.keySet()) {
-                listener.protoChanged(object, oldProto, newProto);
-            }
-        }
-    }
-
-    // PropertyListener methods
-
-    @Override
-    public final void propertyAdded(final ScriptObject object, final Property prop) {
-        notifyPropertyAdded(object, prop);
-    }
-
-    @Override
-    public final void propertyDeleted(final ScriptObject object, final Property prop) {
-        notifyPropertyDeleted(object, prop);
-    }
-
-    @Override
-    public final void propertyModified(final ScriptObject object, final Property oldProp, final Property newProp) {
-        notifyPropertyModified(object, oldProp, newProp);
-    }
-
-    @Override
-    public final void protoChanged(final ScriptObject object, final ScriptObject oldProto, final ScriptObject newProto) {
-        notifyProtoChanged(object, oldProto, newProto);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk/nashorn/internal/runtime/PropertyListeners.java	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2010, 2014, 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.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+/**
+ * Helper class to manage property listeners and notification.
+ */
+public class PropertyListeners {
+
+    private Map<String, WeakPropertyMapSet> listeners;
+
+    // These counters are updated in debug mode
+    private static int listenersAdded;
+    private static int listenersRemoved;
+
+    /**
+     * Copy constructor
+     * @param listener listener to copy
+     */
+    PropertyListeners(final PropertyListeners listener) {
+        if (listener != null && listener.listeners != null) {
+            this.listeners = new WeakHashMap<>(listener.listeners);
+        }
+    }
+
+    /**
+     * Return aggregate listeners added to all PropertyListenerManagers
+     * @return the listenersAdded
+     */
+    public static int getListenersAdded() {
+        return listenersAdded;
+    }
+
+    /**
+     * Return aggregate listeners removed from all PropertyListenerManagers
+     * @return the listenersRemoved
+     */
+    public static int getListenersRemoved() {
+        return listenersRemoved;
+    }
+
+    /**
+     * Return listeners added to this ScriptObject.
+     * @param obj the object
+     * @return the listener count
+     */
+    public static int getListenerCount(final ScriptObject obj) {
+        final PropertyListeners propertyListeners = obj.getMap().getListeners();
+        if (propertyListeners != null) {
+            return propertyListeners.listeners == null ? 0 : propertyListeners.listeners.size();
+        }
+        return 0;
+    }
+
+    // Property listener management methods
+
+    /**
+     * Add {@code propertyMap} as property listener to {@code listeners} using key {@code key} by
+     * creating and returning a new {@code PropertyListeners} instance.
+     *
+     * @param listeners the original property listeners instance, may be null
+     * @param key the property key
+     * @param propertyMap the property map
+     * @return the new property map
+     */
+    public static PropertyListeners addListener(final PropertyListeners listeners, final String key, final PropertyMap propertyMap) {
+        final PropertyListeners newListeners;
+        if (listeners == null || !listeners.containsListener(key, propertyMap)) {
+            newListeners = new PropertyListeners(listeners);
+            newListeners.addListener(key, propertyMap);
+            return newListeners;
+        }
+        return listeners;
+    }
+
+    /**
+     * Checks whether {@code propertyMap} is registered as listener with {@code key}.
+     *
+     * @param key the property key
+     * @param propertyMap the property map
+     * @return true if property map is registered with property key
+     */
+    synchronized boolean containsListener(final String key, final PropertyMap propertyMap) {
+        if (listeners == null) {
+            return false;
+        }
+        WeakPropertyMapSet set = listeners.get(key);
+        return set != null && set.contains(propertyMap);
+    }
+
+    /**
+     * Add a property listener to this object.
+     *
+     * @param propertyMap The property listener that is added.
+     */
+    synchronized final void addListener(final String key, final PropertyMap propertyMap) {
+        if (Context.DEBUG) {
+            listenersAdded++;
+        }
+        if (listeners == null) {
+            listeners = new WeakHashMap<>();
+        }
+
+        WeakPropertyMapSet set = listeners.get(key);
+        if (set == null) {
+            set = new WeakPropertyMapSet();
+            listeners.put(key, set);
+        }
+        if (!set.contains(propertyMap)) {
+            set.add(propertyMap);
+        }
+    }
+
+    /**
+     * A new property is being added.
+     *
+     * @param prop The new Property added.
+     */
+    public synchronized void propertyAdded(final Property prop) {
+        if (listeners != null) {
+            WeakPropertyMapSet set = listeners.get(prop.getKey());
+            if (set != null) {
+                for (PropertyMap propertyMap : set.elements()) {
+                    propertyMap.propertyAdded(prop);
+                }
+                listeners.remove(prop.getKey());
+            }
+        }
+    }
+
+    /**
+     * An existing property is being deleted.
+     *
+     * @param prop The property being deleted.
+     */
+    public synchronized void propertyDeleted(final Property prop) {
+        if (listeners != null) {
+            WeakPropertyMapSet set = listeners.get(prop.getKey());
+            if (set != null) {
+                for (PropertyMap propertyMap : set.elements()) {
+                    propertyMap.propertyDeleted(prop);
+                }
+                listeners.remove(prop.getKey());
+            }
+        }
+    }
+
+    /**
+     * An existing Property is being replaced with a new Property.
+     *
+     * @param oldProp The old property that is being replaced.
+     * @param newProp The new property that replaces the old property.
+     *
+     */
+    public synchronized void propertyModified(final Property oldProp, final Property newProp) {
+        if (listeners != null) {
+            WeakPropertyMapSet set = listeners.get(oldProp.getKey());
+            if (set != null) {
+                for (PropertyMap propertyMap : set.elements()) {
+                    propertyMap.propertyModified(oldProp, newProp);
+                }
+                listeners.remove(oldProp.getKey());
+            }
+        }
+    }
+
+    public synchronized void protoChanged() {
+        if (listeners != null) {
+            for (WeakPropertyMapSet set : listeners.values()) {
+                for (PropertyMap propertyMap : set.elements()) {
+                    propertyMap.protoChanged();
+                }
+            }
+            listeners.clear();
+        }
+    }
+
+    private static class WeakPropertyMapSet {
+
+        private WeakHashMap<PropertyMap, Boolean> map = new WeakHashMap<>();
+
+        void add(final PropertyMap propertyMap) {
+            map.put(propertyMap, Boolean.TRUE);
+        }
+
+        boolean contains(final PropertyMap propertyMap) {
+            return map.containsKey(propertyMap);
+        }
+
+        Set<PropertyMap> elements() {
+            return map.keySet();
+        }
+
+    }
+}
--- a/src/jdk/nashorn/internal/runtime/PropertyMap.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/PropertyMap.java	Mon Mar 24 13:51:59 2014 -0700
@@ -30,13 +30,11 @@
 import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
 
 import java.lang.invoke.SwitchPoint;
-import java.lang.ref.WeakReference;
+import java.lang.ref.SoftReference;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.WeakHashMap;
 
@@ -49,17 +47,11 @@
  * All property maps are immutable. If a property is added, modified or removed, the mutator
  * will return a new map.
  */
-public final class PropertyMap implements Iterable<Object>, PropertyListener {
+public final class PropertyMap implements Iterable<Object> {
     /** Used for non extensible PropertyMaps, negative logic as the normal case is extensible. See {@link ScriptObject#preventExtensions()} */
     public static final int NOT_EXTENSIBLE        = 0b0000_0001;
     /** Does this map contain valid array keys? */
     public static final int CONTAINS_ARRAY_KEYS   = 0b0000_0010;
-    /** This mask is used to preserve certain flags when cloning the PropertyMap. Others should not be copied */
-    private static final int CLONEABLE_FLAGS_MASK = 0b0000_1111;
-    /** Has a listener been added to this property map. This flag is not copied when cloning a map. See {@link PropertyListener} */
-    public static final int IS_LISTENER_ADDED     = 0b0001_0000;
-    /** Is this process wide "shared" map?. This flag is not copied when cloning a map */
-    public static final int IS_SHARED             = 0b0010_0000;
 
     /** Map status flags. */
     private int flags;
@@ -77,16 +69,16 @@
     private int spillLength;
 
     /** {@link SwitchPoint}s for gets on inherited properties. */
-    private Map<String, SwitchPoint> protoGetSwitches;
+    private HashMap<String, SwitchPoint> protoGetSwitches;
 
     /** History of maps, used to limit map duplication. */
-    private HashMap<Property, PropertyMap> history;
+    private WeakHashMap<Property, SoftReference<PropertyMap>> history;
 
     /** History of prototypes, used to limit map duplication. */
-    private WeakHashMap<ScriptObject, WeakReference<PropertyMap>> protoHistory;
+    private WeakHashMap<PropertyMap, SoftReference<PropertyMap>> protoHistory;
 
-    /** Cache for hashCode */
-    private int hashCode;
+    /** property listeners */
+    private PropertyListeners listeners;
 
     /**
      * Constructor.
@@ -119,10 +111,12 @@
      */
     private PropertyMap(final PropertyMap propertyMap, final PropertyHashMap properties) {
         this.properties   = properties;
-        this.flags        = propertyMap.getClonedFlags();
+        this.flags        = propertyMap.flags;
         this.spillLength  = propertyMap.spillLength;
         this.fieldCount   = propertyMap.fieldCount;
         this.fieldMaximum = propertyMap.fieldMaximum;
+        // We inherit the parent property listeners instance. It will be cloned when a new listener is added.
+        this.listeners    = propertyMap.listeners;
 
         if (Context.DEBUG) {
             count++;
@@ -203,35 +197,92 @@
     }
 
     /**
+     * Get the listeners of this map, or null if none exists
+     *
+     * @return the listeners
+     */
+    public PropertyListeners getListeners() {
+        return listeners;
+    }
+
+    /**
+     * Add {@code listenerMap} as a listener to this property map for the given {@code key}.
+     *
+     * @param key the property name
+     * @param listenerMap the listener map
+     */
+    public void addListener(final String key, final PropertyMap listenerMap) {
+        if (listenerMap != this) {
+            // We need to clone listener instance when adding a new listener since we share
+            // the listeners instance with our parent maps that don't need to see the new listener.
+            listeners = PropertyListeners.addListener(listeners, key, listenerMap);
+        }
+    }
+
+    /**
+     * A new property is being added.
+     *
+     * @param property The new Property added.
+     */
+    public void propertyAdded(final Property property) {
+        invalidateProtoGetSwitchPoint(property);
+        if (listeners != null) {
+            listeners.propertyAdded(property);
+        }
+    }
+
+    /**
+     * An existing property is being deleted.
+     *
+     * @param property The property being deleted.
+     */
+    public void propertyDeleted(final Property property) {
+        invalidateProtoGetSwitchPoint(property);
+        if (listeners != null) {
+            listeners.propertyDeleted(property);
+        }
+    }
+
+    /**
+     * An existing property is being redefined.
+     *
+     * @param oldProperty The old property
+     * @param newProperty The new property
+     */
+    public void propertyModified(final Property oldProperty, final Property newProperty) {
+        invalidateProtoGetSwitchPoint(oldProperty);
+        if (listeners != null) {
+            listeners.propertyModified(oldProperty, newProperty);
+        }
+    }
+
+    /**
+     * The prototype of an object associated with this {@link PropertyMap} is changed.
+     */
+    public void protoChanged() {
+        invalidateAllProtoGetSwitchPoints();
+        if (listeners != null) {
+            listeners.protoChanged();
+        }
+    }
+
+    /**
      * Return a SwitchPoint used to track changes of a property in a prototype.
      *
-     * @param proto  Object prototype.
-     * @param key    {@link Property} key.
-     *
+     * @param key Property key.
      * @return A shared {@link SwitchPoint} for the property.
      */
-    public SwitchPoint getProtoGetSwitchPoint(final ScriptObject proto, final String key) {
-        assert !isShared() : "proto SwitchPoint from a shared PropertyMap";
-
-        if (proto == null) {
-            return null;
+    public synchronized SwitchPoint getSwitchPoint(final String key) {
+        if (protoGetSwitches == null) {
+            protoGetSwitches = new HashMap<>();
         }
 
-        if (protoGetSwitches == null) {
-            protoGetSwitches = new HashMap<>();
-            if (! isListenerAdded()) {
-                proto.addPropertyListener(this);
-                setIsListenerAdded();
-            }
+        SwitchPoint switchPoint = protoGetSwitches.get(key);
+        if (switchPoint == null) {
+            switchPoint = new SwitchPoint();
+            protoGetSwitches.put(key, switchPoint);
         }
 
-        if (protoGetSwitches.containsKey(key)) {
-            return protoGetSwitches.get(key);
-        }
-
-        final SwitchPoint switchPoint = new SwitchPoint();
-        protoGetSwitches.put(key, switchPoint);
-
         return switchPoint;
     }
 
@@ -240,14 +291,13 @@
      *
      * @param property {@link Property} to invalidate.
      */
-    private void invalidateProtoGetSwitchPoint(final Property property) {
-        assert !isShared() : "proto invalidation on a shared PropertyMap";
+    synchronized void invalidateProtoGetSwitchPoint(final Property property) {
+        if (protoGetSwitches != null) {
 
-        if (protoGetSwitches != null) {
             final String key = property.getKey();
             final SwitchPoint sp = protoGetSwitches.get(key);
             if (sp != null) {
-                protoGetSwitches.put(key, new SwitchPoint());
+                protoGetSwitches.remove(key);
                 if (Context.DEBUG) {
                     protoInvalidations++;
                 }
@@ -257,14 +307,15 @@
     }
 
     /**
-     * Indicate that proto itself has changed in hierachy somewhere.
+     * Indicate that proto itself has changed in hierarchy somewhere.
      */
-    private void invalidateAllProtoGetSwitchPoints() {
-        assert !isShared() : "proto invalidation on a shared PropertyMap";
-
-        if (protoGetSwitches != null) {
-            final Collection<SwitchPoint> sws = protoGetSwitches.values();
-            SwitchPoint.invalidateAll(sws.toArray(new SwitchPoint[sws.size()]));
+    synchronized void invalidateAllProtoGetSwitchPoints() {
+        if (protoGetSwitches != null && !protoGetSwitches.isEmpty()) {
+            if (Context.DEBUG) {
+                protoInvalidations += protoGetSwitches.size();
+            }
+            SwitchPoint.invalidateAll(protoGetSwitches.values().toArray(new SwitchPoint[protoGetSwitches.values().size()]));
+            protoGetSwitches.clear();
         }
     }
 
@@ -279,7 +330,33 @@
      * @return New {@link PropertyMap} with {@link Property} added.
      */
     PropertyMap addPropertyBind(final AccessorProperty property, final Object bindTo) {
-        return addProperty(new AccessorProperty(property, bindTo));
+        // No need to store bound property in the history as bound properties can't be reused.
+        return addPropertyNoHistory(new AccessorProperty(property, bindTo));
+    }
+
+    /**
+     * Add a property to the map without adding it to the history. This should be used for properties that
+     * can't be shared such as bound properties, or properties that are expected to be added only once.
+     *
+     * @param property {@link Property} being added.
+     * @return New {@link PropertyMap} with {@link Property} added.
+     */
+    public PropertyMap addPropertyNoHistory(final Property property) {
+        if (listeners != null) {
+            listeners.propertyAdded(property);
+        }
+        final PropertyHashMap newProperties = properties.immutableAdd(property);
+        final PropertyMap newMap = new PropertyMap(this, newProperties);
+
+        if(!property.isSpill()) {
+            newMap.fieldCount = Math.max(newMap.fieldCount, property.getSlot() + 1);
+        }
+        if (isValidArrayIndex(getArrayIndex(property.getKey()))) {
+            newMap.setContainsArrayKeys();
+        }
+
+        newMap.spillLength += property.getSpillCount();
+        return newMap;
     }
 
     /**
@@ -290,6 +367,9 @@
      * @return New {@link PropertyMap} with {@link Property} added.
      */
     public PropertyMap addProperty(final Property property) {
+        if (listeners != null) {
+            listeners.propertyAdded(property);
+        }
         PropertyMap newMap = checkHistory(property);
 
         if (newMap == null) {
@@ -318,6 +398,9 @@
      * @return New {@link PropertyMap} with {@link Property} removed or {@code null} if not found.
      */
     public PropertyMap deleteProperty(final Property property) {
+        if (listeners != null) {
+            listeners.propertyDeleted(property);
+        }
         PropertyMap newMap = checkHistory(property);
         final String key = property.getKey();
 
@@ -339,6 +422,9 @@
      * @return New {@link PropertyMap} with {@link Property} replaced.
      */
     PropertyMap replaceProperty(final Property oldProperty, final Property newProperty) {
+        if (listeners != null) {
+            listeners.propertyModified(oldProperty, newProperty);
+        }
         // Add replaces existing property.
         final PropertyHashMap newProperties = properties.immutableAdd(newProperty);
         final PropertyMap newMap = new PropertyMap(this, newProperties);
@@ -363,7 +449,7 @@
                 (oldProperty instanceof AccessorProperty &&
                 newProperty instanceof UserAccessorProperty) : "arbitrary replaceProperty attempted";
 
-        newMap.flags = getClonedFlags();
+        newMap.flags = flags;
 
         /*
          * spillLength remains same in case (1) and (2) because of slot reuse. Only for case (3), we need
@@ -491,28 +577,6 @@
     }
 
     /**
-     * Make this property map 'shared' one. Shared property map instances are
-     * process wide singleton objects. A shaped map should never be added as a listener
-     * to a proto object. Nor it should have history or proto history. A shared map
-     * is just a template that is meant to be duplicated before use. All nasgen initialized
-     * property maps are shared.
-     *
-     * @return this map after making it as shared
-     */
-    public PropertyMap setIsShared() {
-        assert !isListenerAdded() : "making PropertyMap shared after listener added";
-        assert protoHistory == null : "making PropertyMap shared after associating a proto with it";
-        if (Context.DEBUG) {
-            sharedCount++;
-        }
-
-        flags |= IS_SHARED;
-        // clear any history on this PropertyMap, won't be used.
-        history = null;
-        return this;
-    }
-
-    /**
      * Check for any configurable properties.
      *
      * @return {@code true} if any configurable.
@@ -551,14 +615,14 @@
     /**
      * Check prototype history for an existing property map with specified prototype.
      *
-     * @param newProto New prototype object.
+     * @param parentMap New prototype object.
      *
      * @return Existing {@link PropertyMap} or {@code null} if not found.
      */
-    private PropertyMap checkProtoHistory(final ScriptObject newProto) {
+    private PropertyMap checkProtoHistory(final PropertyMap parentMap) {
         final PropertyMap cachedMap;
         if (protoHistory != null) {
-            final WeakReference<PropertyMap> weakMap = protoHistory.get(newProto);
+            final SoftReference<PropertyMap> weakMap = protoHistory.get(parentMap);
             cachedMap = (weakMap != null ? weakMap.get() : null);
         } else {
             cachedMap = null;
@@ -574,17 +638,15 @@
     /**
      * Add a map to the prototype history.
      *
-     * @param newProto Prototype to add (key.)
+     * @param parentMap Prototype to add (key.)
      * @param newMap   {@link PropertyMap} associated with prototype.
      */
-    private void addToProtoHistory(final ScriptObject newProto, final PropertyMap newMap) {
-        assert !isShared() : "proto history modified on a shared PropertyMap";
-
+    private void addToProtoHistory(final PropertyMap parentMap, final PropertyMap newMap) {
         if (protoHistory == null) {
             protoHistory = new WeakHashMap<>();
         }
 
-        protoHistory.put(newProto, new WeakReference<>(newMap));
+        protoHistory.put(parentMap, new SoftReference<>(newMap));
     }
 
     /**
@@ -594,14 +656,12 @@
      * @param newMap   Modified {@link PropertyMap}.
      */
     private void addToHistory(final Property property, final PropertyMap newMap) {
-        assert !isShared() : "history modified on a shared PropertyMap";
-
         if (!properties.isEmpty()) {
             if (history == null) {
-                history = new LinkedHashMap<>();
+                history = new WeakHashMap<>();
             }
 
-            history.put(property, newMap);
+            history.put(property, new SoftReference<>(newMap));
         }
     }
 
@@ -613,8 +673,10 @@
      * @return Existing map or {@code null} if not found.
      */
     private PropertyMap checkHistory(final Property property) {
+
         if (history != null) {
-            PropertyMap historicMap = history.get(property);
+            SoftReference<PropertyMap> ref = history.get(property);
+            final PropertyMap historicMap = ref == null ? null : ref.get();
 
             if (historicMap != null) {
                 if (Context.DEBUG) {
@@ -628,54 +690,6 @@
         return null;
     }
 
-    /**
-     * Calculate the hash code for the map.
-     *
-     * @return Computed hash code.
-     */
-    private int computeHashCode() {
-        int hash = 0;
-
-        for (final Property property : getProperties()) {
-            hash = hash << 7 ^ hash >> 7;
-            hash ^= property.hashCode();
-        }
-
-        return hash;
-    }
-
-    @Override
-    public int hashCode() {
-        if (hashCode == 0 && !properties.isEmpty()) {
-            hashCode = computeHashCode();
-        }
-        return hashCode;
-    }
-
-    @Override
-    public boolean equals(final Object other) {
-        if (!(other instanceof PropertyMap)) {
-            return false;
-        }
-
-        final PropertyMap otherMap = (PropertyMap)other;
-
-        if (properties.size() != otherMap.properties.size()) {
-            return false;
-        }
-
-        final Iterator<Property> iter      = properties.values().iterator();
-        final Iterator<Property> otherIter = otherMap.properties.values().iterator();
-
-        while (iter.hasNext() && otherIter.hasNext()) {
-            if (!iter.next().equals(otherIter.next())) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
     @Override
     public String toString() {
         final StringBuilder sb = new StringBuilder();
@@ -728,24 +742,6 @@
     }
 
     /**
-     * Check whether a {@link PropertyListener} has been added to this map.
-     *
-     * @return {@code true} if {@link PropertyListener} exists
-     */
-    public boolean isListenerAdded() {
-        return (flags & IS_LISTENER_ADDED) != 0;
-    }
-
-    /**
-     * Check if this map shared or not.
-     *
-     * @return true if this map is shared.
-     */
-    public boolean isShared() {
-        return (flags & IS_SHARED) != 0;
-    }
-
-    /**
      * Test to see if {@link PropertyMap} is extensible.
      *
      * @return {@code true} if {@link PropertyMap} can be added to.
@@ -800,50 +796,29 @@
     }
 
     /**
-     * Change the prototype of objects associated with this {@link PropertyMap}.
+     * Return a property map with the same layout that is associated with the new prototype object.
      *
-     * @param oldProto Current prototype object.
      * @param newProto New prototype object to replace oldProto.
-     *
      * @return New {@link PropertyMap} with prototype changed.
      */
-    PropertyMap changeProto(final ScriptObject oldProto, final ScriptObject newProto) {
-        assert !isShared() : "proto associated with a shared PropertyMap";
+    public PropertyMap changeProto(final ScriptObject newProto) {
 
-        if (oldProto == newProto) {
-            return this;
-        }
-
-        final PropertyMap nextMap = checkProtoHistory(newProto);
+        final PropertyMap parentMap = newProto == null ? null : newProto.getMap();
+        final PropertyMap nextMap = checkProtoHistory(parentMap);
         if (nextMap != null) {
             return nextMap;
         }
 
         if (Context.DEBUG) {
-            incrementSetProtoNewMapCount();
+            setProtoNewMapCount++;
         }
 
         final PropertyMap newMap = new PropertyMap(this);
-        addToProtoHistory(newProto, newMap);
+        addToProtoHistory(parentMap, newMap);
 
         return newMap;
     }
 
-    /**
-     * Indicate that the map has listeners.
-     */
-    private void setIsListenerAdded() {
-        flags |= IS_LISTENER_ADDED;
-    }
-
-    /**
-     * Return only the flags that should be copied during cloning.
-     *
-     * @return Subset of flags that should be copied.
-     */
-    private int getClonedFlags() {
-        return flags & CLONEABLE_FLAGS_MASK;
-    }
 
     /**
      * {@link PropertyMap} iterator.
@@ -900,41 +875,12 @@
     }
 
     /*
-     * PropertyListener implementation.
-     */
-
-    @Override
-    public void propertyAdded(final ScriptObject object, final Property prop) {
-        invalidateProtoGetSwitchPoint(prop);
-    }
-
-    @Override
-    public void propertyDeleted(final ScriptObject object, final Property prop) {
-        invalidateProtoGetSwitchPoint(prop);
-    }
-
-    @Override
-    public void propertyModified(final ScriptObject object, final Property oldProp, final Property newProp) {
-        invalidateProtoGetSwitchPoint(oldProp);
-    }
-
-    @Override
-    public void protoChanged(final ScriptObject object, final ScriptObject oldProto, final ScriptObject newProto) {
-        // We may walk and invalidate SwitchPoints for properties inherited
-        // from 'object' or it's old proto chain. But, it may not be worth it.
-        // For example, a new proto may have a user defined getter/setter for
-        // a data property down the chain. So, invalidating all is better.
-        invalidateAllProtoGetSwitchPoints();
-    }
-
-    /*
      * Debugging and statistics.
      */
 
     // counters updated only in debug mode
     private static int count;
     private static int clonedCount;
-    private static int sharedCount;
     private static int duplicatedCount;
     private static int historyHit;
     private static int protoInvalidations;
@@ -956,13 +902,6 @@
     }
 
     /**
-     * @return The number of maps that are shared.
-     */
-    public static int getSharedCount() {
-        return sharedCount;
-    }
-
-    /**
      * @return The number of maps that are duplicated.
      */
     public static int getDuplicatedCount() {
@@ -997,10 +936,4 @@
         return setProtoNewMapCount;
     }
 
-    /**
-     * Increment the prototype set count.
-     */
-    private static void incrementSetProtoNewMapCount() {
-        setProtoNewMapCount++;
-    }
 }
--- a/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Mon Mar 24 13:51:59 2014 -0700
@@ -103,9 +103,7 @@
     public RecompilableScriptFunctionData(final FunctionNode functionNode, final CodeInstaller<ScriptEnvironment> installer, final String allocatorClassName, final PropertyMap allocatorMap) {
         super(functionName(functionNode),
               functionNode.getParameters().size(),
-              functionNode.isStrict(),
-              false,
-              true);
+              getFlags(functionNode));
 
         this.functionNode       = functionNode;
         this.source             = functionNode.getSource();
@@ -129,10 +127,11 @@
         final StringBuilder sb = new StringBuilder();
 
         if (source != null) {
-            sb.append(source.getName())
-                .append(':')
-                .append(functionNode.getLineNumber())
-                .append(' ');
+            sb.append(source.getName());
+            if (functionNode != null) {
+                sb.append(':').append(functionNode.getLineNumber());
+            }
+            sb.append(' ');
         }
 
         return sb.toString() + super.toString();
@@ -159,11 +158,25 @@
         return Token.toDesc(TokenType.FUNCTION, position, length);
     }
 
+    private static int getFlags(final FunctionNode functionNode) {
+        int flags = IS_CONSTRUCTOR;
+        if (functionNode.isStrict()) {
+            flags |= IS_STRICT;
+        }
+        if (functionNode.needsCallee()) {
+            flags |= NEEDS_CALLEE;
+        }
+        if (functionNode.usesThis() || functionNode.hasEval()) {
+            flags |= USES_THIS;
+        }
+        return flags;
+    }
+
     @Override
-    ScriptObject allocate() {
+    ScriptObject allocate(final PropertyMap map) {
         try {
             ensureHasAllocator(); //if allocatorClass name is set to null (e.g. for bound functions) we don't even try
-            return allocator == null ? null : (ScriptObject)allocator.invokeExact(allocatorMap);
+            return allocator == null ? null : (ScriptObject)allocator.invokeExact(map);
         } catch (final RuntimeException | Error e) {
             throw e;
         } catch (final Throwable t) {
@@ -178,40 +191,46 @@
     }
 
     @Override
-    protected synchronized void ensureCodeGenerated() {
-         if (!code.isEmpty()) {
-             return; // nothing to do, we have code, at least some.
-         }
+    PropertyMap getAllocatorMap() {
+        return allocatorMap;
+    }
+
 
-         if (functionNode.isLazy()) {
-             Compiler.LOG.info("Trampoline hit: need to do lazy compilation of '", functionNode.getName(), "'");
-             final Compiler compiler = new Compiler(installer);
-             functionNode = compiler.compile(functionNode);
-             assert !functionNode.isLazy();
-             compiler.install(functionNode);
+    @Override
+    protected void ensureCompiled() {
+        if (functionNode != null && functionNode.isLazy()) {
+            Compiler.LOG.info("Trampoline hit: need to do lazy compilation of '", functionNode.getName(), "'");
+            final Compiler compiler = new Compiler(installer);
+            functionNode = compiler.compile(functionNode);
+            assert !functionNode.isLazy();
+            compiler.install(functionNode);
+            flags = getFlags(functionNode);
+        }
+    }
 
-             /*
-              * We don't need to update any flags - varArgs and needsCallee are instrincic
-              * in the function world we need to get a destination node from the compile instead
-              * and replace it with our function node. TODO
-              */
-         }
+    @Override
+    protected synchronized void ensureCodeGenerated() {
+        if (!code.isEmpty()) {
+            return; // nothing to do, we have code, at least some.
+        }
+
+        ensureCompiled();
 
-         /*
-          * We can't get to this program point unless we have bytecode, either from
-          * eager compilation or from running a lazy compile on the lines above
-          */
+        /*
+         * We can't get to this program point unless we have bytecode, either from
+         * eager compilation or from running a lazy compile on the lines above
+         */
 
-         assert functionNode.hasState(CompilationState.EMITTED) : functionNode.getName() + " " + functionNode.getState() + " " + Debug.id(functionNode);
+        assert functionNode.hasState(CompilationState.EMITTED) : functionNode.getName() + " " + functionNode.getState() + " " + Debug.id(functionNode);
 
-         // code exists - look it up and add it into the automatically sorted invoker list
-         addCode(functionNode);
+        // code exists - look it up and add it into the automatically sorted invoker list
+        addCode(functionNode);
 
-         if (! functionNode.canSpecialize()) {
-             // allow GC to claim IR stuff that is not needed anymore
-             functionNode = null;
-             installer = null;
-         }
+        if (! functionNode.canSpecialize()) {
+            // allow GC to claim IR stuff that is not needed anymore
+            functionNode = null;
+            installer = null;
+        }
     }
 
     private MethodHandle addCode(final FunctionNode fn) {
--- a/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Mon Mar 24 13:51:59 2014 -0700
@@ -38,6 +38,7 @@
 import jdk.internal.dynalink.linker.LinkRequest;
 import jdk.nashorn.internal.codegen.CompilerConstants.Call;
 import jdk.nashorn.internal.lookup.MethodHandleFactory;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
 import jdk.nashorn.internal.runtime.linker.NashornGuards;
 
@@ -66,6 +67,8 @@
 
     private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", Object.class, Object.class);
 
+    private static final MethodHandle GLOBALFILTER = findOwnMH("globalFilter", Object.class, Object.class);
+
     /** method handle to scope getter for this ScriptFunction */
     public static final Call GET_SCOPE = virtualCallNoLookup(ScriptFunction.class, "getScope", ScriptObject.class);
 
@@ -80,6 +83,9 @@
 
     private final ScriptFunctionData data;
 
+    /** The property map used for newly allocated object when function is used as constructor. */
+    protected PropertyMap allocatorMap;
+
     /**
      * Constructor
      *
@@ -88,9 +94,7 @@
      * @param map           property map
      * @param scope         scope
      * @param specs         specialized version of this function - other method handles
-     * @param strict        is this a strict mode function?
-     * @param builtin       is this a built in function?
-     * @param isConstructor is this a constructor?
+     * @param flags         {@link ScriptFunctionData} flags
      */
     protected ScriptFunction(
             final String name,
@@ -98,11 +102,9 @@
             final PropertyMap map,
             final ScriptObject scope,
             final MethodHandle[] specs,
-            final boolean strict,
-            final boolean builtin,
-            final boolean isConstructor) {
+            final int flags) {
 
-        this(new FinalScriptFunctionData(name, methodHandle, specs, strict, builtin, isConstructor), map, scope);
+        this(new FinalScriptFunctionData(name, methodHandle, specs, flags), map, scope);
     }
 
     /**
@@ -125,6 +127,7 @@
 
         this.data  = data;
         this.scope = scope;
+        this.allocatorMap = data.getAllocatorMap();
     }
 
     @Override
@@ -229,16 +232,16 @@
         }
         assert !isBoundFunction(); // allocate never invoked on bound functions
 
-        final ScriptObject object = data.allocate();
+        final ScriptObject object = data.allocate(allocatorMap);
 
         if (object != null) {
             Object prototype = getPrototype();
             if (prototype instanceof ScriptObject) {
-                object.setProto((ScriptObject)prototype);
+                object.setInitialProto((ScriptObject)prototype);
             }
 
             if (object.getProto() == null) {
-                object.setProto(getObjectPrototype());
+                object.setInitialProto(getObjectPrototype());
             }
         }
 
@@ -473,7 +476,14 @@
         if (obj instanceof ScriptObject || !ScriptFunctionData.isPrimitiveThis(obj)) {
             return obj;
         }
-        return ((GlobalObject)Context.getGlobalTrusted()).wrapAsObject(obj);
+        return Context.getGlobal().wrapAsObject(obj);
+    }
+
+
+    @SuppressWarnings("unused")
+    private static Object globalFilter(final Object object) {
+        // replace whatever we get with the current global object
+        return Context.getGlobal();
     }
 
     /**
@@ -491,11 +501,11 @@
     @Override
     protected GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final LinkRequest request) {
         final MethodType type = desc.getMethodType();
+        final boolean scopeCall = NashornCallSiteDescriptor.isScope(desc);
 
         if (request.isCallSiteUnstable()) {
-            // (this, callee, args...) => (this, callee, args[])
-            final MethodHandle collector = MH.asCollector(ScriptRuntime.APPLY.methodHandle(), Object[].class,
-                    type.parameterCount() - 2);
+            // (callee, this, args...) => (callee, this, args[])
+            final MethodHandle collector = MH.asCollector(ScriptRuntime.APPLY.methodHandle(), Object[].class, type.parameterCount() - 2);
 
             // If call site is statically typed to take a ScriptFunction, we don't need a guard, otherwise we need a
             // generic "is this a ScriptFunction?" guard.
@@ -506,17 +516,12 @@
         MethodHandle boundHandle;
         MethodHandle guard = null;
 
-        final boolean scopeCall = NashornCallSiteDescriptor.isScope(desc);
-
         if (data.needsCallee()) {
             final MethodHandle callHandle = getBestInvoker(type, request.getArguments());
-            if (scopeCall) {
+            if (scopeCall && needsWrappedThis()) {
                 // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
-                // (callee, this, args...) => (callee, args...)
-                boundHandle = MH.insertArguments(callHandle, 1, needsWrappedThis() ? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED);
-                // (callee, args...) => (callee, [this], args...)
-                boundHandle = MH.dropArguments(boundHandle, 1, Object.class);
-
+                // (callee, this, args...) => (callee, [this], args...)
+                boundHandle = MH.filterArguments(callHandle, 1, GLOBALFILTER);
             } else {
                 // It's already (callee, this, args...), just what we need
                 boundHandle = callHandle;
@@ -527,12 +532,12 @@
                 // NOTE: the only built-in named "extend" is NativeJava.extend. As a special-case we're binding the
                 // current lookup as its "this" so it can do security-sensitive creation of adapter classes.
                 boundHandle = MH.dropArguments(MH.bindTo(callHandle, desc.getLookup()), 0, Object.class, Object.class);
-            } else if (scopeCall) {
+            } else if (scopeCall && needsWrappedThis()) {
                 // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
-                // (this, args...) => (args...)
-                boundHandle = MH.bindTo(callHandle, needsWrappedThis() ? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED);
-                // (args...) => ([callee], [this], args...)
-                boundHandle = MH.dropArguments(boundHandle, 0, Object.class, Object.class);
+                // (this, args...) => ([this], args...)
+                boundHandle = MH.filterArguments(callHandle, 0, GLOBALFILTER);
+                // ([this], args...) => ([callee], [this], args...)
+                boundHandle = MH.dropArguments(boundHandle, 0, Object.class);
             } else {
                 // (this, args...) => ([callee], this, args...)
                 boundHandle = MH.dropArguments(callHandle, 0, Object.class);
--- a/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Mon Mar 24 13:51:59 2014 -0700
@@ -32,6 +32,7 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
 
 /**
@@ -47,33 +48,44 @@
     /** All versions of this function that have been generated to code */
     protected final CompiledFunctions code;
 
-    private int arity;
-
-    private final boolean isStrict;
+    /** Function flags */
+    protected int flags;
 
-    private final boolean isBuiltin;
-
-    private final boolean isConstructor;
+    private int arity;
 
     private static final MethodHandle NEWFILTER     = findOwnMH("newFilter", Object.class, Object.class, Object.class);
     private static final MethodHandle BIND_VAR_ARGS = findOwnMH("bindVarArgs", Object[].class, Object[].class, Object[].class);
 
+    /** Is this a strict mode function? */
+    public static final int IS_STRICT      = 1 << 0;
+    /** Is this a built-in function? */
+    public static final int IS_BUILTIN     = 1 << 1;
+    /** Is this a constructor function? */
+    public static final int IS_CONSTRUCTOR = 1 << 2;
+    /** Does this function expect a callee argument? */
+    public static final int NEEDS_CALLEE   = 1 << 3;
+    /** Does this function make use of the this-object argument? */
+    public static final int USES_THIS      = 1 << 4;
+
+    /** Flag for strict or built-in functions */
+    public static final int IS_STRICT_OR_BUILTIN = IS_STRICT | IS_BUILTIN;
+    /** Flag for built-in constructors */
+    public static final int IS_BUILTIN_CONSTRUCTOR = IS_BUILTIN | IS_CONSTRUCTOR;
+    /** Flag for strict constructors */
+    public static final int IS_STRICT_CONSTRUCTOR = IS_STRICT | IS_CONSTRUCTOR;
+
     /**
      * Constructor
      *
      * @param name          script function name
      * @param arity         arity
-     * @param isStrict      is the function strict
-     * @param isBuiltin     is the function built in
-     * @param isConstructor is the function a constructor
+     * @param flags         the function flags
      */
-    ScriptFunctionData(final String name, final int arity, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) {
-        this.name          = name;
-        this.arity         = arity;
-        this.code          = new CompiledFunctions();
-        this.isStrict      = isStrict;
-        this.isBuiltin     = isBuiltin;
-        this.isConstructor = isConstructor;
+    ScriptFunctionData(final String name, final int arity, final int flags) {
+        this.name  = name;
+        this.arity = arity;
+        this.code  = new CompiledFunctions();
+        this.flags = flags;
     }
 
     final int getArity() {
@@ -105,21 +117,21 @@
      * @return true if strict, false otherwise
      */
     public boolean isStrict() {
-        return isStrict;
+        return (flags & IS_STRICT) != 0;
     }
 
     boolean isBuiltin() {
-        return isBuiltin;
+        return (flags & IS_BUILTIN) != 0;
     }
 
     boolean isConstructor() {
-        return isConstructor;
+        return (flags & IS_CONSTRUCTOR) != 0;
     }
 
     boolean needsCallee() {
-        // we don't know if we need a callee or not unless we are generated
-        ensureCodeGenerated();
-        return code.needsCallee();
+        // we don't know if we need a callee or not unless code has been compiled
+        ensureCompiled();
+        return (flags & NEEDS_CALLEE) != 0;
     }
 
     /**
@@ -128,7 +140,7 @@
      * @return true if this argument must be an object
      */
     boolean needsWrappedThis() {
-        return !isStrict && !isBuiltin;
+        return (flags & USES_THIS) != 0 && (flags & IS_STRICT_OR_BUILTIN) == 0;
     }
 
     String toSource() {
@@ -202,6 +214,15 @@
     }
 
     /**
+     * If we can have lazy code generation, this is a hook to ensure that the code has been compiled.
+     * This does not guarantee the code been installed in this {@code ScriptFunctionData} instance;
+     * use {@link #ensureCodeGenerated()} to install the actual method handles.
+     */
+    protected void ensureCompiled() {
+        //empty
+    }
+
+    /**
      * Return a generic Object/Object invoker for this method. It will ensure code
      * is generated, get the most generic of all versions of this function and adapt it
      * to Objects.
@@ -229,9 +250,20 @@
 
     /**
      * Allocates an object using this function's allocator.
+     *
+     * @param map the property map for the allocated object.
      * @return the object allocated using this function's allocator, or null if the function doesn't have an allocator.
      */
-    ScriptObject allocate() {
+    ScriptObject allocate(final PropertyMap map) {
+        return null;
+    }
+
+    /**
+     * Get the property map to use for objects allocated by this function.
+     *
+     * @return the property map for allocated objects.
+     */
+    PropertyMap getAllocatorMap() {
         return null;
     }
 
@@ -248,6 +280,8 @@
 
         final Object[] allArgs = args == null ? ScriptRuntime.EMPTY_ARRAY : args;
         final int length = args == null ? 0 : args.length;
+        // Clear the callee and this flags
+        final int boundFlags = flags & ~NEEDS_CALLEE & ~USES_THIS;
 
         CompiledFunctions boundList = new CompiledFunctions();
         if (code.size() == 1) {
@@ -262,8 +296,7 @@
             boundList.add(bind(inv, fn, self, allArgs));
         }
 
-        ScriptFunctionData boundData = new FinalScriptFunctionData(name, arity == -1 ? -1 : Math.max(0, arity - length), boundList, isStrict(), isBuiltin(), isConstructor());
-        return boundData;
+        return new FinalScriptFunctionData(name, arity == -1 ? -1 : Math.max(0, arity - length), boundList, boundFlags);
     }
 
     /**
@@ -340,11 +373,11 @@
     private Object convertThisObject(final Object thiz) {
         if (!(thiz instanceof ScriptObject) && needsWrappedThis()) {
             if (JSType.nullOrUndefined(thiz)) {
-                return Context.getGlobalTrusted();
+                return Context.getGlobal();
             }
 
             if (isPrimitiveThis(thiz)) {
-                return ((GlobalObject)Context.getGlobalTrusted()).wrapAsObject(thiz);
+                return Context.getGlobal().wrapAsObject(thiz);
             }
         }
 
--- a/src/jdk/nashorn/internal/runtime/ScriptLoader.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/ScriptLoader.java	Mon Mar 24 13:51:59 2014 -0700
@@ -70,9 +70,8 @@
      * @return Installed class.
      */
     synchronized Class<?> installClass(final String name, final byte[] data, final CodeSource cs) {
-        if (cs == null) {
-            return defineClass(name, data, 0, data.length, new ProtectionDomain(null, getPermissions(null)));
-        }
+        // null check
+        cs.getClass();
         return defineClass(name, data, 0, data.length, cs);
     }
 }
--- a/src/jdk/nashorn/internal/runtime/ScriptObject.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java	Mon Mar 24 13:51:59 2014 -0700
@@ -43,6 +43,7 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
+import java.lang.invoke.SwitchPoint;
 import java.util.AbstractMap;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -65,6 +66,7 @@
 import jdk.nashorn.internal.lookup.MethodHandleFactory;
 import jdk.nashorn.internal.objects.AccessorPropertyDescriptor;
 import jdk.nashorn.internal.objects.DataPropertyDescriptor;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.arrays.ArrayData;
 import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
@@ -88,7 +90,7 @@
  * </ul>
  */
 
-public abstract class ScriptObject extends PropertyListenerManager implements PropertyAccess {
+public abstract class ScriptObject implements PropertyAccess {
     /** __proto__ special property name */
     public static final String PROTO_PROPERTY_NAME   = "__proto__";
 
@@ -107,9 +109,6 @@
     /** Per ScriptObject flag - is this an arguments object? */
     public static final int IS_ARGUMENTS   = 0b0000_0100;
 
-    /** Is this a prototype PropertyMap? */
-    public static final int IS_PROTOTYPE   = 0b0000_1000;
-
     /** Is length property not-writable? */
     public static final int IS_LENGTH_NOT_WRITABLE = 0b0001_0000;
 
@@ -133,7 +132,8 @@
 
     static final MethodHandle GETPROTO           = findOwnMH("getProto", ScriptObject.class);
     static final MethodHandle SETPROTOCHECK      = findOwnMH("setProtoCheck", void.class, Object.class);
-    static final MethodHandle MEGAMORPHIC_GET    = findOwnMH("megamorphicGet", Object.class, String.class, boolean.class);
+    static final MethodHandle MEGAMORPHIC_GET    = findOwnMH("megamorphicGet", Object.class, String.class, boolean.class, boolean.class);
+    static final MethodHandle GLOBALFILTER       = findOwnMH("globalFilter", Object.class, Object.class);
 
     static final MethodHandle SETFIELD           = findOwnMH("setField",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class);
     static final MethodHandle SETSPILL           = findOwnMH("setSpill",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
@@ -143,6 +143,8 @@
     private static final MethodHandle TRUNCATINGFILTER   = findOwnMH("truncatingFilter", Object[].class, int.class, Object[].class);
     private static final MethodHandle KNOWNFUNCPROPGUARD = findOwnMH("knownFunctionPropertyGuard", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, Object.class, ScriptFunction.class);
 
+    private static final ArrayList<MethodHandle> protoFilters = new ArrayList<>();
+
     /** Method handle for getting a function argument at a given index. Used from MapCreator */
     public static final Call GET_ARGUMENT       = virtualCall(MethodHandles.lookup(), ScriptObject.class, "getArgument", Object.class, int.class);
 
@@ -153,7 +155,7 @@
     public static final Call GET_PROTO          = virtualCallNoLookup(ScriptObject.class, "getProto", ScriptObject.class);
 
     /** Method handle for setting the proto of a ScriptObject */
-    public static final Call SET_PROTO          = virtualCallNoLookup(ScriptObject.class, "setProto", void.class, ScriptObject.class);
+    public static final Call SET_PROTO          = virtualCallNoLookup(ScriptObject.class, "setInitialProto", void.class, ScriptObject.class);
 
     /** Method handle for setting the proto of a ScriptObject after checking argument */
     public static final Call SET_PROTO_CHECK    = virtualCallNoLookup(ScriptObject.class, "setProtoCheck", void.class, Object.class);
@@ -199,10 +201,6 @@
         this.arrayData = ArrayData.EMPTY_ARRAY;
         this.setMap(map == null ? PropertyMap.newMap() : map);
         this.proto = proto;
-
-        if (proto != null) {
-            proto.setIsPrototype();
-        }
     }
 
     /**
@@ -229,8 +227,9 @@
             final Property oldProp = newMap.findProperty(key);
             if (oldProp == null) {
                 if (property instanceof UserAccessorProperty) {
+                    // Note: we copy accessor functions to this object which is semantically different from binding.
                     final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source));
-                    newMap = newMap.addProperty(prop);
+                    newMap = newMap.addPropertyNoHistory(prop);
                 } else {
                     newMap = newMap.addPropertyBind((AccessorProperty)property, source);
                 }
@@ -326,18 +325,18 @@
       * @return property descriptor
       */
     public final PropertyDescriptor toPropertyDescriptor() {
-        final GlobalObject global = (GlobalObject) Context.getGlobalTrusted();
+        final Global global = Context.getGlobal();
 
         final PropertyDescriptor desc;
         if (isDataDescriptor()) {
             if (has(SET) || has(GET)) {
-                throw typeError((ScriptObject)global, "inconsistent.property.descriptor");
+                throw typeError(global, "inconsistent.property.descriptor");
             }
 
             desc = global.newDataDescriptor(UNDEFINED, false, false, false);
         } else if (isAccessorDescriptor()) {
             if (has(VALUE) || has(WRITABLE)) {
-                throw typeError((ScriptObject)global, "inconsistent.property.descriptor");
+                throw typeError(global, "inconsistent.property.descriptor");
             }
 
             desc = global.newAccessorDescriptor(UNDEFINED, UNDEFINED, false, false);
@@ -356,7 +355,7 @@
      *
      * @return property descriptor
      */
-    public static PropertyDescriptor toPropertyDescriptor(final ScriptObject global, final Object obj) {
+    public static PropertyDescriptor toPropertyDescriptor(final Global global, final Object obj) {
         if (obj instanceof ScriptObject) {
             return ((ScriptObject)obj).toPropertyDescriptor();
         }
@@ -375,7 +374,7 @@
     public Object getOwnPropertyDescriptor(final String key) {
         final Property property = getMap().findProperty(key);
 
-        final GlobalObject global = (GlobalObject)Context.getGlobalTrusted();
+        final Global global = Context.getGlobal();
 
         if (property != null) {
             final ScriptFunction get   = property.getGetterFunction(this);
@@ -440,7 +439,7 @@
      * @return true if property was successfully defined
      */
     public boolean defineOwnProperty(final String key, final Object propertyDesc, final boolean reject) {
-        final ScriptObject       global  = Context.getGlobalTrusted();
+        final Global             global  = Context.getGlobal();
         final PropertyDescriptor desc    = toPropertyDescriptor(global, propertyDesc);
         final Object             current = getOwnPropertyDescriptor(key);
         final String             name    = JSType.toString(key);
@@ -467,7 +466,7 @@
             return true;
         }
 
-        if (currentDesc.equals(newDesc)) {
+        if (newDesc.hasAndEquals(currentDesc)) {
             // every descriptor field of the new is same as the current
             return true;
         }
@@ -594,23 +593,16 @@
     }
 
     /**
-     * Spec. mentions use of [[DefineOwnProperty]] for indexed properties in
-     * certain places (eg. Array.prototype.map, filter). We can not use ScriptObject.set
-     * method in such cases. This is because set method uses inherited setters (if any)
-     * from any object in proto chain such as Array.prototype, Object.prototype.
-     * This method directly sets a particular element value in the current object.
+     * Almost like defineOwnProperty(int,Object) for arrays this one does
+     * not add 'gap' elements (like the array one does).
      *
      * @param index key for property
      * @param value value to define
      */
-    public final void defineOwnProperty(final int index, final Object value) {
+    public void defineOwnProperty(final int index, final Object value) {
         assert isValidArrayIndex(index) : "invalid array index";
         final long longIndex = ArrayIndex.toLongIndex(index);
-        if (longIndex >= getArray().length()) {
-            // make array big enough to hold..
-            setArray(getArray().ensure(longIndex));
-        }
-        setArray(getArray().set(index, value, false));
+        setValueAtArrayIndex(longIndex, index, value, false);
     }
 
     private void checkIntegerKey(final String key) {
@@ -638,7 +630,7 @@
         final int propFlags = Property.toFlags(pdesc);
 
         if (pdesc.type() == PropertyDescriptor.GENERIC) {
-            final GlobalObject global = (GlobalObject) Context.getGlobalTrusted();
+            final Global global = Context.getGlobal();
             final PropertyDescriptor dDesc = global.newDataDescriptor(UNDEFINED, false, false, false);
 
             dDesc.fillFrom((ScriptObject)pdesc);
@@ -873,8 +865,6 @@
             newProperty = newUserAccessors(oldProperty.getKey(), propertyFlags, getter, setter);
         }
 
-        notifyPropertyModified(this, oldProperty, newProperty);
-
         return modifyOwnProperty(oldProperty, newProperty);
     }
 
@@ -981,17 +971,6 @@
     }
 
     /**
-      * Get the object value of a property
-      *
-      * @param find {@link FindProperty} lookup result
-      *
-      * @return the value of the property
-      */
-    protected static Object getObjectValue(final FindProperty find) {
-        return find.getObjectValue();
-    }
-
-    /**
      * Return methodHandle of value function for call.
      *
      * @param find      data from find property.
@@ -1001,7 +980,7 @@
      * @return value of property as a MethodHandle or null.
      */
     protected MethodHandle getCallMethodHandle(final FindProperty find, final MethodType type, final String bindName) {
-        return getCallMethodHandle(getObjectValue(find), type, bindName);
+        return getCallMethodHandle(find.getObjectValue(), type, bindName);
     }
 
     /**
@@ -1025,7 +1004,7 @@
      * @return Value of property.
      */
     public final Object getWithProperty(final Property property) {
-        return getObjectValue(new FindProperty(this, this, property));
+        return new FindProperty(this, this, property).getObjectValue();
     }
 
     /**
@@ -1118,26 +1097,30 @@
      */
     public synchronized final void setProto(final ScriptObject newProto) {
         final ScriptObject oldProto = proto;
-        map = map.changeProto(oldProto, newProto);
-
-        if (newProto != null) {
-            newProto.setIsPrototype();
+
+        if (oldProto != newProto) {
+            proto = newProto;
+
+            // Let current listeners know that the protototype has changed and set our map
+            final PropertyListeners listeners = getMap().getListeners();
+            if (listeners != null) {
+                listeners.protoChanged();
+            }
+            // Replace our current allocator map with one that is associated with the new prototype.
+            setMap(getMap().changeProto(newProto));
         }
-
-        proto = newProto;
-
-        if (isPrototype()) {
-            // tell listeners that my __proto__ has been changed
-            notifyProtoChanged(this, oldProto, newProto);
-
-            if (oldProto != null) {
-                oldProto.removePropertyListener(this);
-            }
-
-            if (newProto != null) {
-                newProto.addPropertyListener(this);
-            }
-        }
+    }
+
+    /**
+     * Set the initial __proto__ of this object. This should be used instead of
+     * {@link #setProto} if it is known that the current property map will not be
+     * used on a new object with any other parent property map, so we can pass over
+     * property map invalidation/evolution.
+     *
+     * @param initialProto the initial __proto__ to set.
+     */
+    public void setInitialProto(final ScriptObject initialProto) {
+        this.proto = initialProto;
     }
 
     /**
@@ -1160,7 +1143,7 @@
             }
             setProto((ScriptObject)newProto);
         } else {
-            final ScriptObject global = Context.getGlobalTrusted();
+            final Global global = Context.getGlobal();
             final Object  newProtoObject = JSType.toScriptObject(global, newProto);
 
             if (newProtoObject instanceof ScriptObject) {
@@ -1250,11 +1233,11 @@
      * @return the default value
      */
     public Object getDefaultValue(final Class<?> typeHint) {
-        // We delegate to GlobalObject, as the implementation uses dynamic call sites to invoke object's "toString" and
+        // We delegate to Global, as the implementation uses dynamic call sites to invoke object's "toString" and
         // "valueOf" methods, and in order to avoid those call sites from becoming megamorphic when multiple contexts
         // are being executed in a long-running program, we move the code and their associated dynamic call sites
         // (Global.TO_STRING and Global.VALUE_OF) into per-context code.
-        return ((GlobalObject)Context.getGlobalTrusted()).getDefaultValue(this, typeHint);
+        return Context.getGlobal().getDefaultValue(this, typeHint);
     }
 
     /**
@@ -1330,25 +1313,6 @@
     }
 
     /**
-     * Check if this object is a prototype
-     *
-     * @return {@code true} if is prototype
-     */
-    public final boolean isPrototype() {
-        return (flags & IS_PROTOTYPE) != 0;
-    }
-
-    /**
-     * Flag this object as having a prototype.
-     */
-    public final void setIsPrototype() {
-        if (proto != null && !isPrototype()) {
-            proto.addPropertyListener(this);
-        }
-        flags |= IS_PROTOTYPE;
-    }
-
-    /**
      * Check if this object has non-writable length property
      *
      * @return {@code true} if 'length' property is non-writable
@@ -1712,6 +1676,44 @@
     }
 
     /**
+     * Test whether this object contains in its prototype chain or is itself a with-object.
+     * @return true if a with-object was found
+     */
+    final boolean hasWithScope() {
+        if (isScope()) {
+            for (ScriptObject obj = this; obj != null; obj = obj.getProto()) {
+                if (obj instanceof WithObject) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Add a filter to the first argument of {@code methodHandle} that calls its {@link #getProto()} method
+     * {@code depth} times.
+     * @param methodHandle a method handle
+     * @param depth        distance to target prototype
+     * @return the filtered method handle
+     */
+    static MethodHandle addProtoFilter(final MethodHandle methodHandle, final int depth) {
+        if (depth == 0) {
+            return methodHandle;
+        }
+        final int listIndex = depth - 1; // We don't need 0-deep walker
+        MethodHandle filter = listIndex < protoFilters.size() ? protoFilters.get(listIndex) : null;
+
+        if(filter == null) {
+            filter = addProtoFilter(GETPROTO, depth - 1);
+            protoFilters.add(null);
+            protoFilters.set(listIndex, filter);
+        }
+
+        return MH.filterArguments(methodHandle, 0, filter.asType(filter.type().changeReturnType(methodHandle.type().parameterType(0))));
+    }
+
+    /**
      * Find the appropriate GET method for an invoke dynamic call.
      *
      * @param desc     the call site descriptor
@@ -1722,8 +1724,8 @@
      */
     protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
         final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
-        if (request.isCallSiteUnstable()) {
-            return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator));
+        if (request.isCallSiteUnstable() || hasWithScope()) {
+            return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator), isScope() && NashornCallSiteDescriptor.isScope(desc));
         }
 
         final FindProperty find = findProperty(name, true);
@@ -1748,40 +1750,43 @@
         final Property property = find.getProperty();
         methodHandle = find.getGetter(returnType);
 
-        // getMap() is fine as we have the prototype switchpoint depending on where the property was found
-        final MethodHandle guard = NashornGuards.getMapGuard(getMap());
+        // Get the appropriate guard for this callsite and property.
+        final MethodHandle guard = NashornGuards.getGuard(this, property, desc);
+        final ScriptObject owner = find.getOwner();
 
         if (methodHandle != null) {
             assert methodHandle.type().returnType().equals(returnType);
             if (find.isSelf()) {
-                return new GuardedInvocation(methodHandle, ObjectClassGenerator.OBJECT_FIELDS_ONLY &&
-                        NashornCallSiteDescriptor.isFastScope(desc) && !property.canChangeType() ? null : guard);
+                return new GuardedInvocation(methodHandle, guard);
             }
 
-            final ScriptObject prototype = find.getOwner();
-
-            if (!property.hasGetterFunction(prototype)) {
-                methodHandle = bindTo(methodHandle, prototype);
+            if (!property.hasGetterFunction(owner)) {
+                // Add a filter that replaces the self object with the prototype owning the property.
+                methodHandle = addProtoFilter(methodHandle, find.getProtoChainLength());
             }
-            return new GuardedInvocation(methodHandle, getMap().getProtoGetSwitchPoint(proto, name), guard);
+            return new GuardedInvocation(methodHandle, guard == null ? null : getProtoSwitchPoint(name, owner), guard);
         }
 
         assert !NashornCallSiteDescriptor.isFastScope(desc);
-        return new GuardedInvocation(Lookup.emptyGetter(returnType), getMap().getProtoGetSwitchPoint(proto, name), guard);
+        return new GuardedInvocation(Lookup.emptyGetter(returnType), getProtoSwitchPoint(name, owner), guard);
     }
 
-    private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod) {
-        final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod);
+    private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name,
+                                                              final boolean isMethod, final boolean isScope) {
+        final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod, isScope);
         final MethodHandle guard = getScriptObjectGuard(desc.getMethodType());
         return new GuardedInvocation(invoker, guard);
     }
 
     @SuppressWarnings("unused")
-    private Object megamorphicGet(final String key, final boolean isMethod) {
+    private Object megamorphicGet(final String key, final boolean isMethod, final boolean isScope) {
         final FindProperty find = findProperty(key, true);
 
         if (find != null) {
-            return getObjectValue(find);
+            return find.getObjectValue();
+        }
+        if (isScope) {
+            throw referenceError("not.defined", key);
         }
 
         return isMethod ? getNoSuchMethod(key) : invokeNoSuchProperty(key);
@@ -1824,6 +1829,28 @@
     }
 
     /**
+     * Get a switch point for a property with the given {@code name} that will be invalidated when
+     * the property definition is changed in this object's prototype chain. Returns {@code null} if
+     * the property is defined in this object itself.
+     *
+     * @param name the property name
+     * @param owner the property owner, null if property is not defined
+     * @return a SwitchPoint or null
+     */
+    public final SwitchPoint getProtoSwitchPoint(final String name, final ScriptObject owner) {
+        if (owner == this || getProto() == null) {
+            return null;
+        }
+
+        for (ScriptObject obj = this; obj != owner && obj.getProto() != null; obj = obj.getProto()) {
+            ScriptObject parent = obj.getProto();
+            parent.getMap().addListener(name, obj.getMap());
+        }
+
+        return getMap().getSwitchPoint(name);
+    }
+
+    /**
      * Find the appropriate SET method for an invoke dynamic call.
      *
      * @param desc    the call site descriptor
@@ -1833,7 +1860,7 @@
      */
     protected GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final LinkRequest request) {
         final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
-        if (request.isCallSiteUnstable()) {
+        if (request.isCallSiteUnstable() || hasWithScope()) {
             return findMegaMorphicSetMethod(desc, name);
         }
 
@@ -1879,8 +1906,7 @@
                throw typeError(strictErrorMessage, name, ScriptRuntime.safeToString((this)));
            }
            assert canBeFastScope || !NashornCallSiteDescriptor.isFastScope(desc);
-           final PropertyMap myMap = getMap();
-           return new GuardedInvocation(Lookup.EMPTY_SETTER, myMap.getProtoGetSwitchPoint(proto, name), NashornGuards.getMapGuard(myMap));
+           return new GuardedInvocation(Lookup.EMPTY_SETTER, getProtoSwitchPoint(name, null), NashornGuards.getMapGuard(getMap()));
     }
 
     @SuppressWarnings("unused")
@@ -1888,7 +1914,9 @@
         final ScriptObject obj = (ScriptObject)self;
         final boolean isStrict = NashornCallSiteDescriptor.isStrict(desc);
         if (!obj.isExtensible()) {
-            throw typeError("object.non.extensible", desc.getNameToken(2), ScriptRuntime.safeToString(obj));
+            if (isStrict) {
+                throw typeError("object.non.extensible", desc.getNameToken(2), ScriptRuntime.safeToString(obj));
+            }
         } else if (obj.compareAndSetMap(oldMap, newMap)) {
             setter.invokeExact(self, value);
         } else {
@@ -1953,6 +1981,15 @@
         }
     }
 
+    @SuppressWarnings("unused")
+    private static Object globalFilter(final Object object) {
+        ScriptObject sobj = (ScriptObject) object;
+        while (sobj != null && !(sobj instanceof Global)) {
+            sobj = sobj.getProto();
+        }
+        return sobj;
+    }
+
     private static GuardedInvocation findMegaMorphicSetMethod(final CallSiteDescriptor desc, final String name) {
         final MethodType type = desc.getMethodType().insertParameterTypes(1, Object.class);
         final GuardedInvocation inv = findSetIndexMethod(type, NashornCallSiteDescriptor.isStrict(desc));
@@ -1998,7 +2035,7 @@
             return noSuchProperty(desc, request);
         }
 
-        final Object value = getObjectValue(find);
+        final Object value = find.getObjectValue();
         if (! (value instanceof ScriptFunction)) {
             return createEmptyGetter(desc, name);
         }
@@ -2024,7 +2061,7 @@
         final boolean scopeAccess = isScope() && NashornCallSiteDescriptor.isScope(desc);
 
         if (find != null) {
-            final Object   value        = getObjectValue(find);
+            final Object   value        = find.getObjectValue();
             ScriptFunction func         = null;
             MethodHandle   methodHandle = null;
 
@@ -2038,7 +2075,7 @@
                     methodHandle = bindTo(methodHandle, UNDEFINED);
                 }
                 return new GuardedInvocation(methodHandle,
-                        find.isInherited()? getMap().getProtoGetSwitchPoint(proto, NO_SUCH_PROPERTY_NAME) : null,
+                        getProtoSwitchPoint(NO_SUCH_PROPERTY_NAME, find.getOwner()),
                         getKnownFunctionPropertyGuard(getMap(), find.getGetter(Object.class), find.getOwner(), func));
             }
         }
@@ -2049,16 +2086,17 @@
 
         return createEmptyGetter(desc, name);
     }
+
     /**
      * Invoke fall back if a property is not found.
      * @param name Name of property.
      * @return Result from call.
      */
-    private Object invokeNoSuchProperty(final String name) {
+    protected Object invokeNoSuchProperty(final String name) {
         final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true);
 
         if (find != null) {
-            final Object func = getObjectValue(find);
+            final Object func = find.getObjectValue();
 
             if (func instanceof ScriptFunction) {
                 return ScriptRuntime.apply((ScriptFunction)func, this, name);
@@ -2080,7 +2118,7 @@
             return invokeNoSuchProperty(name);
         }
 
-        final Object value = getObjectValue(find);
+        final Object value = find.getObjectValue();
         if (! (value instanceof ScriptFunction)) {
             return UNDEFINED;
         }
@@ -2089,7 +2127,8 @@
     }
 
     private GuardedInvocation createEmptyGetter(final CallSiteDescriptor desc, final String name) {
-        return new GuardedInvocation(Lookup.emptyGetter(desc.getMethodType().returnType()), getMap().getProtoGetSwitchPoint(proto, name), NashornGuards.getMapGuard(getMap()));
+        return new GuardedInvocation(Lookup.emptyGetter(desc.getMethodType().returnType()),
+                getProtoSwitchPoint(name, null), NashornGuards.getMapGuard(getMap()));
     }
 
     private abstract static class ScriptObjectIterator <T extends Object> implements Iterator<T> {
@@ -2170,12 +2209,10 @@
 
         if (fieldCount < fieldMaximum) {
             property = new AccessorProperty(key, propertyFlags & ~Property.IS_SPILL, getClass(), fieldCount);
-            notifyPropertyAdded(this, property);
             property = addOwnProperty(property);
         } else {
             int i = getMap().getSpillLength();
             property = new AccessorProperty(key, propertyFlags | Property.IS_SPILL, i);
-            notifyPropertyAdded(this, property);
             property = addOwnProperty(property);
             i = property.getSlot();
 
@@ -2621,7 +2658,7 @@
                     final FindProperty find = object.findProperty(key, false, false, this);
 
                     if (find != null) {
-                        return getObjectValue(find);
+                        return find.getObjectValue();
                     }
                 }
 
@@ -2639,7 +2676,7 @@
             final FindProperty find = findProperty(key, true);
 
             if (find != null) {
-                return getObjectValue(find);
+                return find.getObjectValue();
             }
         }
 
@@ -2703,9 +2740,7 @@
      * @param strict are we in strict mode
      */
     private void doesNotHave(final int index, final Object value, final boolean strict) {
-        final long oldLength = getArray().length();
         final long longIndex = ArrayIndex.toLongIndex(index);
-
         if (getMap().containsArrayKeys()) {
             final String key = JSType.toString(longIndex);
             final FindProperty find = findProperty(key, true);
@@ -2716,6 +2751,18 @@
             }
         }
 
+        setValueAtArrayIndex(longIndex, index, value, strict);
+    }
+
+    /**
+     * Handle when an array doesn't have a slot - possibly grow and/or convert array.
+     *
+     * @param index  key as index
+     * @param value  element value
+     * @param strict are we in strict mode
+     */
+    private void setValueAtArrayIndex(final long longIndex, final int index, final Object value, final boolean strict) {
+        final long oldLength = getArray().length();
         if (longIndex >= oldLength) {
             if (!isExtensible()) {
                 if (strict) {
@@ -2759,7 +2806,8 @@
     public final void setObject(final FindProperty find, final boolean strict, final String key, final Object value) {
         FindProperty f = find;
 
-        if (f != null && f.isInherited() && !(f.getProperty() instanceof UserAccessorProperty)) {
+        if (f != null && f.isInherited() && !(f.getProperty() instanceof UserAccessorProperty) && !isScope()) {
+            // Setting a property should not modify the property in prototype unless this is a scope object.
             f = null;
         }
 
@@ -2779,7 +2827,15 @@
                 throw typeError("object.non.extensible", key, ScriptRuntime.safeToString(this));
             }
         } else {
-            spill(key, value);
+            ScriptObject sobj = this;
+            // undefined scope properties are set in the global object.
+            if (isScope()) {
+                while (sobj != null && !(sobj instanceof Global)) {
+                    sobj = sobj.getProto();
+                }
+                assert sobj != null : "no parent global object in scope";
+            }
+            sobj.spill(key, value);
         }
     }
 
@@ -3228,7 +3284,6 @@
         }
 
         final Property prop = find.getProperty();
-        notifyPropertyDeleted(this, prop);
         deleteOwnProperty(prop);
 
         return true;
--- a/src/jdk/nashorn/internal/runtime/ScriptRuntime.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java	Mon Mar 24 13:51:59 2014 -0700
@@ -474,7 +474,7 @@
      * @return {@link WithObject} that is the new scope
      */
     public static ScriptObject openWith(final ScriptObject scope, final Object expression) {
-        final ScriptObject global = Context.getGlobalTrusted();
+        final Global global = Context.getGlobal();
         if (expression == UNDEFINED) {
             throw typeError(global, "cant.apply.with.to.undefined");
         } else if (expression == null) {
--- a/src/jdk/nashorn/internal/runtime/SetMethodCreator.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/SetMethodCreator.java	Mon Mar 24 13:51:59 2014 -0700
@@ -31,7 +31,6 @@
 import java.lang.invoke.MethodHandle;
 import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.linker.GuardedInvocation;
-import jdk.nashorn.internal.codegen.ObjectClassGenerator;
 import jdk.nashorn.internal.lookup.Lookup;
 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
 import jdk.nashorn.internal.runtime.linker.NashornGuards;
@@ -80,7 +79,7 @@
     }
 
     /**
-     * This class encapsulates the results of looking up a setter method; it's basically a triple of a method hanle,
+     * This class encapsulates the results of looking up a setter method; it's basically a triple of a method handle,
      * a Property object, and flags for invocation.
      *
      */
@@ -104,21 +103,9 @@
          * @return the composed guarded invocation that represents the dynamic setter method for the property.
          */
         GuardedInvocation createGuardedInvocation() {
-            return new GuardedInvocation(methodHandle, getGuard());
-        }
-
-        private MethodHandle getGuard() {
-            return needsNoGuard() ? null : NashornGuards.getMapGuard(getMap());
+            return new GuardedInvocation(methodHandle, NashornGuards.getGuard(sobj, property, desc));
         }
 
-        private boolean needsNoGuard() {
-            return NashornCallSiteDescriptor.isFastScope(desc) &&
-                    (ObjectClassGenerator.OBJECT_FIELDS_ONLY || isPropertyTypeStable());
-        }
-
-        private boolean isPropertyTypeStable() {
-            return property == null || !property.canChangeType();
-        }
     }
 
     private SetMethod createSetMethod() {
@@ -151,10 +138,9 @@
         assert methodHandle != null;
         assert property     != null;
 
-        final ScriptObject prototype = find.getOwner();
         final MethodHandle boundHandle;
-        if (!property.hasSetterFunction(prototype) && find.isInherited()) {
-            boundHandle = ScriptObject.bindTo(methodHandle, prototype);
+        if (!property.hasSetterFunction(find.getOwner()) && find.isInherited()) {
+            boundHandle = ScriptObject.addProtoFilter(methodHandle, find.getProtoChainLength());
         } else {
             boundHandle = methodHandle;
         }
@@ -162,13 +148,16 @@
     }
 
     private SetMethod createGlobalPropertySetter() {
-        final ScriptObject global = Context.getGlobalTrusted();
-        return new SetMethod(ScriptObject.bindTo(global.addSpill(getName()), global), null);
+        final ScriptObject global = Context.getGlobal();
+        return new SetMethod(MH.filterArguments(global.addSpill(getName()), 0, ScriptObject.GLOBALFILTER), null);
     }
 
     private SetMethod createNewPropertySetter() {
         final SetMethod sm = map.getFieldCount() < map.getFieldMaximum() ? createNewFieldSetter() : createNewSpillPropertySetter();
-        sobj.notifyPropertyAdded(sobj, sm.property);
+        final PropertyListeners listeners = map.getListeners();
+        if (listeners != null) {
+            listeners.propertyAdded(sm.property);
+        }
         return sm;
     }
 
--- a/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java	Mon Mar 24 13:51:59 2014 -0700
@@ -34,6 +34,7 @@
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
+import jdk.nashorn.internal.objects.Global;
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
 
@@ -73,7 +74,7 @@
 
     private static MethodHandle getINVOKE_UA_GETTER() {
 
-        return ((GlobalObject)Context.getGlobal()).getDynamicInvoker(INVOKE_UA_GETTER,
+        return Context.getGlobal().getDynamicInvoker(INVOKE_UA_GETTER,
                 new Callable<MethodHandle>() {
                     @Override
                     public MethodHandle call() {
@@ -86,7 +87,7 @@
     /** Dynamic invoker for setter */
     private static Object INVOKE_UA_SETTER = new Object();
     private static MethodHandle getINVOKE_UA_SETTER() {
-        return ((GlobalObject)Context.getGlobal()).getDynamicInvoker(INVOKE_UA_SETTER,
+        return Context.getGlobal().getDynamicInvoker(INVOKE_UA_SETTER,
                 new Callable<MethodHandle>() {
                     @Override
                     public MethodHandle call() {
--- a/src/jdk/nashorn/internal/runtime/WithObject.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/WithObject.java	Mon Mar 24 13:51:59 2014 -0700
@@ -36,6 +36,7 @@
 import jdk.internal.dynalink.linker.LinkRequest;
 import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
+import jdk.nashorn.internal.runtime.linker.NashornGuards;
 
 /**
  * This class supports the handling of scope in a with body.
@@ -87,6 +88,11 @@
 
     @Override
     public GuardedInvocation lookup(final CallSiteDescriptor desc, final LinkRequest request) {
+        if (request.isCallSiteUnstable()) {
+            // Fall back to megamorphic invocation which performs a complete lookup each time without further relinking.
+            return super.lookup(desc, request);
+        }
+
         // With scopes can never be observed outside of Nashorn code, so all call sites that can address it will of
         // necessity have a Nashorn descriptor - it is safe to cast.
         final NashornCallSiteDescriptor ndesc = (NashornCallSiteDescriptor)desc;
@@ -123,7 +129,7 @@
         }
 
         if (find != null) {
-            return fixScopeCallSite(scope.lookup(desc, request), name);
+            return fixScopeCallSite(scope.lookup(desc, request), name, find.getOwner());
         }
 
         // the property is not found - now check for
@@ -175,7 +181,7 @@
         link = scope.lookup(desc, request);
 
         if (link != null) {
-            return fixScopeCallSite(link, name);
+            return fixScopeCallSite(link, name, null);
         }
 
         return null;
@@ -252,13 +258,10 @@
                 filterGuard(link, WITHEXPRESSIONFILTER));
     }
 
-    private GuardedInvocation fixScopeCallSite(final GuardedInvocation link, final String name) {
+    private GuardedInvocation fixScopeCallSite(final GuardedInvocation link, final String name, final ScriptObject owner) {
         final GuardedInvocation newLink = fixReceiverType(link, WITHSCOPEFILTER);
         return link.replaceMethods(filter(newLink.getInvocation(), WITHSCOPEFILTER),
-            MH.guardWithTest(
-                expressionGuard(name),
-                filterGuard(newLink, WITHSCOPEFILTER),
-                MH.dropArguments(MH.constant(boolean.class, false), 0, Object.class)));
+                NashornGuards.combineGuards(expressionGuard(name, owner), filterGuard(newLink, WITHSCOPEFILTER)));
     }
 
     private static MethodHandle filterGuard(final GuardedInvocation link, final MethodHandle filter) {
@@ -267,7 +270,7 @@
     }
 
     private static MethodHandle filter(final MethodHandle mh, final MethodHandle filter) {
-        return MH.filterArguments(mh, 0, filter);
+        return MH.filterArguments(mh, 0, filter.asType(filter.type().changeReturnType(mh.type().parameterType(0))));
     }
 
     /**
@@ -288,9 +291,9 @@
         return fn.makeBoundFunction(withFilterExpression(receiver), new Object[0]);
     }
 
-    private MethodHandle expressionGuard(final String name) {
+    private MethodHandle expressionGuard(final String name, final ScriptObject owner) {
         final PropertyMap map = expression.getMap();
-        final SwitchPoint sp = map.getProtoGetSwitchPoint(expression.getProto(), name);
+        final SwitchPoint sp = expression.getProtoSwitchPoint(name, owner);
         return MH.insertArguments(WITHEXPRESSIONGUARD, 1, map, sp);
     }
 
--- a/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java	Mon Mar 24 13:51:59 2014 -0700
@@ -26,7 +26,8 @@
 package jdk.nashorn.internal.runtime.arrays;
 
 import java.lang.invoke.MethodHandle;
-import jdk.nashorn.internal.runtime.GlobalObject;
+import java.nio.ByteBuffer;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.PropertyDescriptor;
 
@@ -144,6 +145,16 @@
     }
 
     /**
+     * Allocate an ArrayData wrapping a given nio ByteBuffer
+     *
+     * @param buf the nio ByteBuffer to wrap
+     * @return the ArrayData
+     */
+    public static ArrayData allocate(final ByteBuffer buf) {
+        return new ByteBufferArrayData((ByteBuffer)buf);
+    }
+
+    /**
      * Apply a freeze filter to an ArrayData.
      *
      * @param underlying  the underlying ArrayData to wrap in the freeze filter
@@ -388,7 +399,7 @@
      *
      * @return property descriptor for element
      */
-    public PropertyDescriptor getDescriptor(final GlobalObject global, final int index) {
+    public PropertyDescriptor getDescriptor(final Global global, final int index) {
         return global.newDataDescriptor(getObject(index), true, true, true);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk/nashorn/internal/runtime/arrays/ByteBufferArrayData.java	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2014, 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.arrays;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+
+import java.nio.ByteBuffer;
+import jdk.nashorn.internal.objects.Global;
+import jdk.nashorn.internal.runtime.PropertyDescriptor;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * Implementation of {@link ArrayData} that wraps a nio ByteBuffer
+ */
+final class ByteBufferArrayData extends ArrayData {
+    private final ByteBuffer buf;
+
+    ByteBufferArrayData(final int length) {
+        super(length);
+        this.buf = ByteBuffer.allocateDirect(length);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param buf ByteBuffer to create array data with.
+     */
+    ByteBufferArrayData(final ByteBuffer buf) {
+        super(buf.capacity());
+        this.buf = buf;
+    }
+
+    /**
+     * Returns property descriptor for element at a given index
+     *
+     * @param global the global object
+     * @param index  the index
+     *
+     * @return property descriptor for element
+     */
+    @Override
+    public PropertyDescriptor getDescriptor(final Global global, final int index) {
+        // make the index properties not configurable
+        return global.newDataDescriptor(getObject(index), false, true, true);
+    }
+
+    @Override
+    public ArrayData copy() {
+        throw unsupported("copy");
+    }
+
+    @Override
+    public Object[] asObjectArray() {
+        throw unsupported("asObjectArray");
+    }
+
+    @Override
+    public void setLength(final long length) {
+        throw new UnsupportedOperationException("setLength");
+    }
+
+    @Override
+    public void shiftLeft(int by) {
+        throw unsupported("shiftLeft");
+    }
+
+    @Override
+    public ArrayData shiftRight(int by) {
+        throw unsupported("shiftRight");
+    }
+
+    @Override
+    public ArrayData ensure(long safeIndex) {
+        if (safeIndex < buf.capacity()) {
+            return this;
+        }
+
+        throw unsupported("ensure");
+    }
+
+    @Override
+    public ArrayData shrink(long newLength) {
+        throw unsupported("shrink");
+    }
+
+    @Override
+    public ArrayData set(int index, Object value, boolean strict) {
+        if (value instanceof Number) {
+            buf.put(index, ((Number)value).byteValue());
+            return this;
+        }
+
+        throw typeError("not.a.number", ScriptRuntime.safeToString(value));
+    }
+
+    @Override
+    public ArrayData set(int index, int value, boolean strict) {
+        buf.put(index, (byte)value);
+        return this;
+    }
+
+    @Override
+    public ArrayData set(int index, long value, boolean strict) {
+        buf.put(index, (byte)value);
+        return this;
+    }
+
+    @Override
+    public ArrayData set(int index, double value, boolean strict) {
+        buf.put(index, (byte)value);
+        return this;
+    }
+
+    @Override
+    public int getInt(int index) {
+        return 0x0ff & buf.get(index);
+    }
+
+    @Override
+    public long getLong(int index) {
+        return 0x0ff & buf.get(index);
+    }
+
+    @Override
+    public double getDouble(int index) {
+        return 0x0ff & buf.get(index);
+    }
+
+    @Override
+    public Object getObject(int index) {
+        return (int)(0x0ff & buf.get(index));
+    }
+
+    @Override
+    public boolean has(int index) {
+        return index > -1 && index < buf.capacity();
+    }
+
+    @Override
+    public boolean canDelete(final int index, final boolean strict) {
+        return false;
+    }
+
+    @Override
+    public boolean canDelete(final long fromIndex, final long toIndex, final boolean strict) {
+        return false;
+    }
+
+    @Override
+    public ArrayData delete(int index) {
+        throw unsupported("delete");
+    }
+
+    @Override
+    public ArrayData delete(long fromIndex, long toIndex) {
+        throw unsupported("delete");
+    }
+
+    @Override
+    public ArrayData push(final boolean strict, final Object... items) {
+        throw unsupported("push");
+    }
+
+    @Override
+    public Object pop() {
+        throw unsupported("pop");
+    }
+
+    @Override
+    public ArrayData slice(long from, long to) {
+        throw unsupported("slice");
+    }
+
+    @Override
+    public ArrayData convert(final Class<?> type) {
+        throw unsupported("convert");
+    }
+
+    private UnsupportedOperationException unsupported(final String method) {
+        return new UnsupportedOperationException(method);
+    }
+}
--- a/src/jdk/nashorn/internal/runtime/arrays/FrozenArrayFilter.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/arrays/FrozenArrayFilter.java	Mon Mar 24 13:51:59 2014 -0700
@@ -25,9 +25,9 @@
 
 package jdk.nashorn.internal.runtime.arrays;
 
+import jdk.nashorn.internal.objects.Global;
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 
-import jdk.nashorn.internal.runtime.GlobalObject;
 import jdk.nashorn.internal.runtime.PropertyDescriptor;
 
 /**
@@ -44,7 +44,7 @@
     }
 
     @Override
-    public PropertyDescriptor getDescriptor(final GlobalObject global, final int index) {
+    public PropertyDescriptor getDescriptor(final Global global, final int index) {
         return global.newDataDescriptor(getObject(index), false, true, false);
     }
 
--- a/src/jdk/nashorn/internal/runtime/arrays/SealedArrayFilter.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/arrays/SealedArrayFilter.java	Mon Mar 24 13:51:59 2014 -0700
@@ -25,9 +25,9 @@
 
 package jdk.nashorn.internal.runtime.arrays;
 
+import jdk.nashorn.internal.objects.Global;
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 
-import jdk.nashorn.internal.runtime.GlobalObject;
 import jdk.nashorn.internal.runtime.PropertyDescriptor;
 
 /**
@@ -62,7 +62,7 @@
     }
 
     @Override
-    public PropertyDescriptor getDescriptor(final GlobalObject global, final int index) {
+    public PropertyDescriptor getDescriptor(final Global global, final int index) {
         return global.newDataDescriptor(getObject(index), false, true, true);
     }
 }
--- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java	Mon Mar 24 13:51:59 2014 -0700
@@ -64,6 +64,7 @@
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.Type;
 import jdk.internal.org.objectweb.asm.commons.InstructionAdapter;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
@@ -134,6 +135,7 @@
     static final Type CONTEXT_TYPE       = Type.getType(Context.class);
     static final Type OBJECT_TYPE        = Type.getType(Object.class);
     static final Type SCRIPT_OBJECT_TYPE = Type.getType(ScriptObject.class);
+    static final Type GLOBAL_TYPE        = Type.getType(Global.class);
 
     static final String CONTEXT_TYPE_NAME = CONTEXT_TYPE.getInternalName();
     static final String OBJECT_TYPE_NAME  = OBJECT_TYPE.getInternalName();
@@ -143,8 +145,10 @@
     static final String GLOBAL_FIELD_NAME = "global";
 
     static final String SCRIPT_OBJECT_TYPE_DESCRIPTOR = SCRIPT_OBJECT_TYPE.getDescriptor();
+    static final String GLOBAL_TYPE_DESCRIPTOR = GLOBAL_TYPE.getDescriptor();
 
-    static final String SET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE, SCRIPT_OBJECT_TYPE);
+
+    static final String SET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE, GLOBAL_TYPE);
     static final String VOID_NOARG_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE);
 
     private static final Type SCRIPT_FUNCTION_TYPE = Type.getType(ScriptFunction.class);
@@ -167,7 +171,7 @@
     private static final String UNSUPPORTED_OPERATION_TYPE_NAME = UNSUPPORTED_OPERATION_TYPE.getInternalName();
 
     private static final String METHOD_HANDLE_TYPE_DESCRIPTOR = METHOD_HANDLE_TYPE.getDescriptor();
-    private static final String GET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(SCRIPT_OBJECT_TYPE);
+    private static final String GET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(GLOBAL_TYPE);
     private static final String GET_CLASS_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.getType(Class.class));
 
     // Package used when the adapter can't be defined in the adaptee's package (either because it's sealed, or because
@@ -259,7 +263,7 @@
     }
 
     private void generateGlobalFields() {
-        cw.visitField(ACC_PRIVATE | ACC_FINAL | (classOverride ? ACC_STATIC : 0), GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR, null, null).visitEnd();
+        cw.visitField(ACC_PRIVATE | ACC_FINAL | (classOverride ? ACC_STATIC : 0), GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR, null, null).visitEnd();
         usedFieldNames.add(GLOBAL_FIELD_NAME);
     }
 
@@ -321,7 +325,7 @@
         final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_STATIC, CLASS_INIT,
                 Type.getMethodDescriptor(Type.VOID_TYPE), null, null));
 
-        mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getClassOverrides", GET_CLASS_INITIALIZER_DESCRIPTOR);
+        mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getClassOverrides", GET_CLASS_INITIALIZER_DESCRIPTOR, false);
         final Label initGlobal;
         if(samName != null) {
             // If the class is a SAM, allow having a ScriptFunction passed as class overrides
@@ -337,7 +341,7 @@
                 if(mi.getName().equals(samName)) {
                     mv.dup();
                     mv.aconst(Type.getMethodType(mi.type.toMethodDescriptorString()));
-                    mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getHandle", GET_HANDLE_FUNCTION_DESCRIPTOR);
+                    mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getHandle", GET_HANDLE_FUNCTION_DESCRIPTOR, false);
                 } else {
                     mv.visitInsn(ACONST_NULL);
                 }
@@ -354,7 +358,7 @@
             mv.dup();
             mv.aconst(mi.getName());
             mv.aconst(Type.getMethodType(mi.type.toMethodDescriptorString()));
-            mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getHandle", GET_HANDLE_OBJECT_DESCRIPTOR);
+            mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getHandle", GET_HANDLE_OBJECT_DESCRIPTOR, false);
             mv.putstatic(generatedClassName, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
         }
 
@@ -363,7 +367,7 @@
         }
         // Assign "global = Context.getGlobal()"
         invokeGetGlobalWithNullCheck(mv);
-        mv.putstatic(generatedClassName, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
+        mv.putstatic(generatedClassName, GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR);
 
         endInitMethod(mv);
     }
@@ -371,7 +375,7 @@
     private static void invokeGetGlobalWithNullCheck(final InstructionAdapter mv) {
         invokeGetGlobal(mv);
         mv.dup();
-        mv.invokevirtual(OBJECT_TYPE_NAME, "getClass", GET_CLASS_METHOD_DESCRIPTOR); // check against null Context
+        mv.invokevirtual(OBJECT_TYPE_NAME, "getClass", GET_CLASS_METHOD_DESCRIPTOR, false); // check against null Context
         mv.pop();
     }
 
@@ -428,7 +432,7 @@
             mv.load(offset, argType);
             offset += argType.getSize();
         }
-        mv.invokespecial(superClassName, INIT, originalCtorType.getDescriptor());
+        mv.invokespecial(superClassName, INIT, originalCtorType.getDescriptor(), false);
 
         endInitMethod(mv);
     }
@@ -481,7 +485,7 @@
             mv.load(offset, argType);
             offset += argType.getSize();
         }
-        mv.invokespecial(superClassName, INIT, originalCtorType.getDescriptor());
+        mv.invokespecial(superClassName, INIT, originalCtorType.getDescriptor(), false);
 
         // Get a descriptor to the appropriate "JavaAdapterFactory.getHandle" method.
         final String getHandleDescriptor = fromFunction ? GET_HANDLE_FUNCTION_DESCRIPTOR : GET_HANDLE_OBJECT_DESCRIPTOR;
@@ -500,7 +504,7 @@
                     mv.aconst(mi.getName());
                 }
                 mv.aconst(Type.getMethodType(mi.type.toMethodDescriptorString()));
-                mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getHandle", getHandleDescriptor);
+                mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getHandle", getHandleDescriptor, false);
             }
             mv.putfield(generatedClassName, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
         }
@@ -508,7 +512,7 @@
         // Assign "this.global = Context.getGlobal()"
         mv.visitVarInsn(ALOAD, 0);
         invokeGetGlobalWithNullCheck(mv);
-        mv.putfield(generatedClassName, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
+        mv.putfield(generatedClassName, GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR);
 
         endInitMethod(mv);
     }
@@ -524,11 +528,11 @@
     }
 
     private static void invokeGetGlobal(final InstructionAdapter mv) {
-        mv.invokestatic(CONTEXT_TYPE_NAME, "getGlobal", GET_GLOBAL_METHOD_DESCRIPTOR);
+        mv.invokestatic(CONTEXT_TYPE_NAME, "getGlobal", GET_GLOBAL_METHOD_DESCRIPTOR, false);
     }
 
     private static void invokeSetGlobal(final InstructionAdapter mv) {
-        mv.invokestatic(CONTEXT_TYPE_NAME, "setGlobal", SET_GLOBAL_METHOD_DESCRIPTOR);
+        mv.invokestatic(CONTEXT_TYPE_NAME, "setGlobal", SET_GLOBAL_METHOD_DESCRIPTOR, false);
     }
 
     /**
@@ -641,21 +645,21 @@
             // If the super method is abstract, throw an exception
             mv.anew(UNSUPPORTED_OPERATION_TYPE);
             mv.dup();
-            mv.invokespecial(UNSUPPORTED_OPERATION_TYPE_NAME, INIT, VOID_NOARG_METHOD_DESCRIPTOR);
+            mv.invokespecial(UNSUPPORTED_OPERATION_TYPE_NAME, INIT, VOID_NOARG_METHOD_DESCRIPTOR, false);
             mv.athrow();
         } else {
             // If the super method is not abstract, delegate to it.
-            emitSuperCall(mv, name, methodDesc);
+            emitSuperCall(mv, method.getDeclaringClass(), name, methodDesc);
         }
 
         mv.visitLabel(handleDefined);
         // Load the creatingGlobal object
         if(classOverride) {
             // If class handle is defined, load the static defining global
-            mv.getstatic(generatedClassName, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
+            mv.getstatic(generatedClassName, GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR);
         } else {
             mv.visitVarInsn(ALOAD, 0);
-            mv.getfield(generatedClassName, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
+            mv.getfield(generatedClassName, GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR);
         }
         // stack: [creatingGlobal, handle]
         final Label setupGlobal = new Label();
@@ -674,7 +678,7 @@
         // stack: [creatingGlobal, creatingGlobal, handle]
 
         // Emit code for switching to the creating global
-        // ScriptObject currentGlobal = Context.getGlobal();
+        // Global currentGlobal = Context.getGlobal();
         invokeGetGlobal(mv);
         mv.dup();
 
@@ -715,7 +719,7 @@
         // Invoke the target method handle
         final Label tryBlockStart = new Label();
         mv.visitLabel(tryBlockStart);
-        mv.invokevirtual(METHOD_HANDLE_TYPE.getInternalName(), "invokeExact", type.toMethodDescriptorString());
+        mv.invokevirtual(METHOD_HANDLE_TYPE.getInternalName(), "invokeExact", type.toMethodDescriptorString(), false);
         final Label tryBlockEnd = new Label();
         mv.visitLabel(tryBlockEnd);
         emitFinally(mv, currentGlobalVar, globalsDifferVar);
@@ -731,7 +735,7 @@
             mv.anew(RUNTIME_EXCEPTION_TYPE);
             mv.dupX1();
             mv.swap();
-            mv.invokespecial(RUNTIME_EXCEPTION_TYPE_NAME, INIT, Type.getMethodDescriptor(Type.VOID_TYPE, THROWABLE_TYPE));
+            mv.invokespecial(RUNTIME_EXCEPTION_TYPE_NAME, INIT, Type.getMethodDescriptor(Type.VOID_TYPE, THROWABLE_TYPE), false);
             // Fall through to rethrow handler
         } else {
             throwableHandler = null;
@@ -744,7 +748,7 @@
         final Label methodEnd = new Label();
         mv.visitLabel(methodEnd);
 
-        mv.visitLocalVariable("currentGlobal", SCRIPT_OBJECT_TYPE_DESCRIPTOR, null, setupGlobal, methodEnd, currentGlobalVar);
+        mv.visitLocalVariable("currentGlobal", GLOBAL_TYPE_DESCRIPTOR, null, setupGlobal, methodEnd, currentGlobalVar);
         mv.visitLocalVariable("globalsDiffer", Type.INT_TYPE.getDescriptor(), null, setupGlobal, methodEnd, globalsDifferVar);
 
         if(throwableDeclared) {
@@ -817,12 +821,12 @@
                 SUPER_PREFIX + name, methodDesc, null, getExceptionNames(method.getExceptionTypes())));
         mv.visitCode();
 
-        emitSuperCall(mv, name, methodDesc);
+        emitSuperCall(mv, method.getDeclaringClass(), name, methodDesc);
 
         endMethod(mv);
     }
 
-    private void emitSuperCall(final InstructionAdapter mv, final String name, final String methodDesc) {
+    private void emitSuperCall(final InstructionAdapter mv, final Class owner, final String name, final String methodDesc) {
         mv.visitVarInsn(ALOAD, 0);
         int nextParam = 1;
         final Type methodType = Type.getMethodType(methodDesc);
@@ -830,7 +834,13 @@
             mv.load(nextParam, t);
             nextParam += t.getSize();
         }
-        mv.invokespecial(superClassName, name, methodDesc);
+
+        // default method - non-abstract, interface method
+        if (Modifier.isInterface(owner.getModifiers())) {
+            mv.invokespecial(Type.getInternalName(owner), name, methodDesc, false);
+        } else {
+            mv.invokespecial(superClassName, name, methodDesc, false);
+        }
         mv.areturn(methodType.getReturnType());
     }
 
--- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Mon Mar 24 13:51:59 2014 -0700
@@ -48,7 +48,6 @@
 import java.util.concurrent.ConcurrentHashMap;
 import jdk.internal.dynalink.beans.StaticClass;
 import jdk.internal.dynalink.support.LinkRequestImpl;
-import jdk.nashorn.internal.objects.NativeJava;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ECMAException;
 import jdk.nashorn.internal.runtime.ScriptFunction;
@@ -68,8 +67,8 @@
  * generate the adapter class itself; see its documentation for details about the generated class.
  * </p><p>
  * You normally don't use this class directly, but rather either create adapters from script using
- * {@link NativeJava#extend(Object, Object...)}, using the {@code new} operator on abstract classes and interfaces (see
- * {@link NativeJava#type(Object, Object)}), or implicitly when passing script functions to Java methods expecting SAM
+ * {@link jdk.nashorn.internal.objects.NativeJava#extend(Object, Object...)}, using the {@code new} operator on abstract classes and interfaces (see
+ * {@link jdk.nashorn.internal.objects.NativeJava#type(Object, Object)}), or implicitly when passing script functions to Java methods expecting SAM
  * types.
  * </p>
  */
@@ -337,6 +336,7 @@
     private static ProtectionDomain createMinimalPermissionDomain() {
         // Generated classes need to have at least the permission to access Nashorn runtime and runtime.linker packages.
         final Permissions permissions = new Permissions();
+        permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.objects"));
         permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime"));
         permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime.linker"));
         return new ProtectionDomain(new CodeSource(null, (CodeSigner[])null), permissions);
--- a/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java	Mon Mar 24 13:51:59 2014 -0700
@@ -29,6 +29,11 @@
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
+import java.lang.ref.WeakReference;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+import jdk.nashorn.internal.objects.Global;
+import jdk.nashorn.internal.runtime.Property;
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
@@ -37,10 +42,11 @@
  * Constructor of method handles used to guard call sites.
  */
 public final class NashornGuards {
-    private static final MethodHandle IS_SCRIPTOBJECT          = findOwnMH("isScriptObject", boolean.class, Object.class);
-    private static final MethodHandle IS_SCRIPTFUNCTION        = findOwnMH("isScriptFunction", boolean.class, Object.class);
-    private static final MethodHandle IS_MAP                   = findOwnMH("isMap", boolean.class, Object.class, PropertyMap.class);
-    private static final MethodHandle IS_INSTANCEOF_2          = findOwnMH("isInstanceOf2", boolean.class, Object.class, Class.class, Class.class);
+    private static final MethodHandle IS_SCRIPTOBJECT   = findOwnMH("isScriptObject", boolean.class, Object.class);
+    private static final MethodHandle IS_SCRIPTFUNCTION = findOwnMH("isScriptFunction", boolean.class, Object.class);
+    private static final MethodHandle IS_MAP            = findOwnMH("isMap", boolean.class, Object.class, PropertyMap.class);
+    private static final MethodHandle SAME_OBJECT       = findOwnMH("sameObject", boolean.class, Object.class, WeakReference.class);
+    private static final MethodHandle IS_INSTANCEOF_2   = findOwnMH("isInstanceOf2", boolean.class, Object.class, Class.class, Class.class);
 
     // don't create me!
     private NashornGuards() {
@@ -75,6 +81,55 @@
     }
 
     /**
+     * Determine whether the given callsite needs a guard.
+     * @param property the property, or null
+     * @param desc the callsite descriptor
+     * @return true if a guard should be used for this callsite
+     */
+    static boolean needsGuard(final Property property, final CallSiteDescriptor desc) {
+        return property == null || property.isConfigurable()
+                || property.isBound() || !ObjectClassGenerator.OBJECT_FIELDS_ONLY
+                || !NashornCallSiteDescriptor.isFastScope(desc) || property.canChangeType();
+    }
+
+    /**
+     * Get the guard for a property access. This returns an identity guard for non-configurable global properties
+     * and a map guard for everything else.
+     *
+     * @param sobj the first object in the prototype chain
+     * @param property the property
+     * @param desc the callsite descriptor
+     * @return method handle for guard
+     */
+    public static MethodHandle getGuard(final ScriptObject sobj, final Property property, final CallSiteDescriptor desc) {
+        if (!needsGuard(property, desc)) {
+            return null;
+        }
+        if (NashornCallSiteDescriptor.isScope(desc)) {
+            if (property != null && property.isBound()) {
+                // This is a declared top level variables in main script or eval, use identity guard.
+                return getIdentityGuard(sobj);
+            }
+            if (!(sobj instanceof Global) && (property == null || property.isConfigurable())) {
+                // Undeclared variables in nested evals need stronger guards
+                return combineGuards(getIdentityGuard(sobj), getMapGuard(sobj.getMap()));
+            }
+        }
+        return getMapGuard(sobj.getMap());
+    }
+
+
+    /**
+     * Get a guard that checks referential identity of the current object.
+     *
+     * @param sobj the self object
+     * @return true if same self object instance
+     */
+    public static MethodHandle getIdentityGuard(final ScriptObject sobj) {
+        return MH.insertArguments(SAME_OBJECT, 1, new WeakReference<>(sobj));
+    }
+
+    /**
      * Get a guard that checks if in item is an instance of either of two classes.
      *
      * @param class1 the first class
@@ -85,6 +140,17 @@
         return MH.insertArguments(IS_INSTANCEOF_2, 1, class1, class2);
     }
 
+    /**
+     * Combine two method handles of type {@code (Object)boolean} using logical AND.
+     *
+     * @param guard1 the first guard
+     * @param guard2 the second guard, only invoked if guard1 returns true
+     * @return true if both guard1 and guard2 returned true
+     */
+    public static MethodHandle combineGuards(final MethodHandle guard1, final MethodHandle guard2) {
+        return MH.guardWithTest(guard1, guard2, MH.dropArguments(MH.constant(boolean.class, false), 0, Object.class));
+    }
+
     @SuppressWarnings("unused")
     private static boolean isScriptObject(final Object self) {
         return self instanceof ScriptObject;
@@ -101,6 +167,11 @@
     }
 
     @SuppressWarnings("unused")
+    private static boolean sameObject(final Object self, final WeakReference<ScriptObject> ref) {
+        return self == ref.get();
+    }
+
+    @SuppressWarnings("unused")
     private static boolean isInstanceOf2(final Object self, final Class<?> class1, final Class<?> class2) {
         return class1.isInstance(self) || class2.isInstance(self);
     }
--- a/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java	Mon Mar 24 13:51:59 2014 -0700
@@ -37,9 +37,9 @@
 import jdk.internal.dynalink.linker.LinkerServices;
 import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
 import jdk.internal.dynalink.support.TypeUtilities;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.ConsString;
 import jdk.nashorn.internal.runtime.Context;
-import jdk.nashorn.internal.runtime.GlobalObject;
 
 /**
  * Internal linker for String, Boolean, and Number objects, only ever used by Nashorn engine and not exposed to other
@@ -62,7 +62,7 @@
         final LinkRequest request = origRequest.withoutRuntimeContext(); // Nashorn has no runtime context
 
         final Object self = request.getReceiver();
-        final GlobalObject global = (GlobalObject) Context.getGlobal();
+        final Global global = Context.getGlobal();
         final NashornCallSiteDescriptor desc = (NashornCallSiteDescriptor) request.getCallSiteDescriptor();
 
         return Bootstrap.asType(global.primitiveLookup(request, self), linkerServices, desc);
--- a/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java	Mon Mar 24 13:51:59 2014 -0700
@@ -35,6 +35,7 @@
 import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
 import jdk.internal.dynalink.support.Guards;
 import jdk.nashorn.internal.lookup.Lookup;
+import jdk.nashorn.internal.runtime.FindProperty;
 import jdk.nashorn.internal.runtime.ScriptObject;
 
 /**
@@ -61,8 +62,9 @@
      * type {@code receiverClass}.
      */
     public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Class<?> receiverClass,
-                                                    final ScriptObject wrappedReceiver, final MethodHandle wrapFilter) {
-        return lookupPrimitive(request, Guards.getInstanceOfGuard(receiverClass), wrappedReceiver, wrapFilter);
+                                                    final ScriptObject wrappedReceiver, final MethodHandle wrapFilter,
+                                                    final MethodHandle protoFilter) {
+        return lookupPrimitive(request, Guards.getInstanceOfGuard(receiverClass), wrappedReceiver, wrapFilter, protoFilter);
     }
 
     /**
@@ -79,7 +81,8 @@
      * type (that is implied by both {@code guard} and {@code wrappedReceiver}).
      */
     public static GuardedInvocation lookupPrimitive(final LinkRequest request, final MethodHandle guard,
-                                                    final ScriptObject wrappedReceiver, final MethodHandle wrapFilter) {
+                                                    final ScriptObject wrappedReceiver, final MethodHandle wrapFilter,
+                                                    final MethodHandle protoFilter) {
         final CallSiteDescriptor desc = request.getCallSiteDescriptor();
         final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
         if ("setProp".equals(operator) || "setElem".equals(operator)) {
@@ -93,9 +96,23 @@
 
         if(desc.getNameTokenCount() > 2) {
             final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
-            if(wrappedReceiver.findProperty(name, true) == null) {
+            final FindProperty find = wrappedReceiver.findProperty(name, true);
+            if(find == null) {
                 // Give up early, give chance to BeanLinker and NashornBottomLinker to deal with it.
                 return null;
+            } else if (find.isInherited() && !find.getProperty().hasGetterFunction(find.getOwner())) {
+                // If property is found in the prototype object bind the method handle directly to
+                // the proto filter instead of going through wrapper instantiation below.
+                final ScriptObject proto = wrappedReceiver.getProto();
+                final GuardedInvocation link = proto.lookup(desc, request);
+
+                if (link != null) {
+                    final MethodHandle invocation = link.getInvocation();
+                    final MethodHandle adaptedInvocation = MH.asType(invocation, invocation.type().changeParameterType(0, Object.class));
+                    final MethodHandle method = MH.filterArguments(adaptedInvocation, 0, protoFilter);
+                    final MethodHandle protoGuard = MH.filterArguments(link.getGuard(), 0, protoFilter);
+                    return new GuardedInvocation(method, NashornGuards.combineGuards(guard, protoGuard));
+                }
             }
         }
         final GuardedInvocation link = wrappedReceiver.lookup(desc, request);
--- a/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java	Mon Mar 24 13:51:59 2014 -0700
@@ -93,7 +93,8 @@
             if ((self instanceof Class) && Modifier.isPublic(((Class<?>)self).getModifiers())) {
                 final CallSiteDescriptor desc = requestWithoutContext.getCallSiteDescriptor();
                 if(CallSiteDescriptorFactory.tokenizeOperators(desc).contains("getProp")) {
-                    if ("static".equals(desc.getNameToken(CallSiteDescriptor.NAME_OPERAND))) {
+                    if (desc.getNameTokenCount() > CallSiteDescriptor.NAME_OPERAND &&
+                        "static".equals(desc.getNameToken(CallSiteDescriptor.NAME_OPERAND))) {
                         if (Context.isAccessibleClass((Class<?>)self) && !isReflectionClass((Class<?>)self)) {
 
                             // If "getProp:static" passes access checks, allow access.
--- a/src/jdk/nashorn/internal/runtime/resources/Messages.properties	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/runtime/resources/Messages.properties	Mon Mar 24 13:51:59 2014 -0700
@@ -78,6 +78,8 @@
 type.error.not.a.function={0} is not a function
 type.error.not.a.constructor={0} is not a constructor function
 type.error.not.a.file={0} is not a File
+type.error.not.a.bytebuffer={0} is not a java.nio.ByteBuffer
+type.error.not.an.arraybuffer.in.dataview=First arg to DataView constructor must be an ArrayBuffer
 
 # operations not permitted on undefined
 type.error.cant.call.undefined=Cannot call undefined
@@ -136,6 +138,9 @@
 type.error.method.not.constructor=Java method {0} can't be used as a constructor.
 type.error.env.not.object=$ENV must be an Object.
 type.error.unsupported.java.to.type=Unsupported Java.to target type {0}.
+
+range.error.dataview.constructor.offset=Wrong offset or length in DataView constructor
+range.error.dataview.offset=Offset is outside the bounds of the DataView
 range.error.inappropriate.array.length=inappropriate array length: {0}
 range.error.inappropriate.array.buffer.length=inappropriate array buffer length: {0}
 range.error.invalid.fraction.digits=fractionDigits argument to {0} must be in [0, 20]
--- a/src/jdk/nashorn/internal/scripts/JO.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/internal/scripts/JO.java	Mon Mar 24 13:51:59 2014 -0700
@@ -33,7 +33,7 @@
  */
 public class JO extends ScriptObject {
 
-    private static final PropertyMap map$ = PropertyMap.newMap().setIsShared();
+    private static final PropertyMap map$ = PropertyMap.newMap();
 
     /**
      * Returns the initial property map to be used.
--- a/src/jdk/nashorn/tools/Shell.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/src/jdk/nashorn/tools/Shell.java	Mon Mar 24 13:51:59 2014 -0700
@@ -42,6 +42,7 @@
 import jdk.nashorn.internal.ir.FunctionNode;
 import jdk.nashorn.internal.ir.debug.ASTWriter;
 import jdk.nashorn.internal.ir.debug.PrintVisitor;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.parser.Parser;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ErrorManager;
@@ -148,7 +149,7 @@
             return COMMANDLINE_ERROR;
         }
 
-        final ScriptObject global = context.createGlobal();
+        final Global global = context.createGlobal();
         final ScriptEnvironment env = context.getEnv();
         final List<String> files = env.getFiles();
         if (files.isEmpty()) {
@@ -231,8 +232,8 @@
      * @return error code
      * @throws IOException when any script file read results in I/O error
      */
-    private static int compileScripts(final Context context, final ScriptObject global, final List<String> files) throws IOException {
-        final ScriptObject oldGlobal = Context.getGlobal();
+    private static int compileScripts(final Context context, final Global global, final List<String> files) throws IOException {
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
         final ScriptEnvironment env = context.getEnv();
         try {
@@ -281,8 +282,8 @@
      * @return error code
      * @throws IOException when any script file read results in I/O error
      */
-    private int runScripts(final Context context, final ScriptObject global, final List<String> files) throws IOException {
-        final ScriptObject oldGlobal = Context.getGlobal();
+    private int runScripts(final Context context, final Global global, final List<String> files) throws IOException {
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
         try {
             if (globalChanged) {
@@ -339,8 +340,8 @@
      * @return error code
      * @throws IOException when any script file read results in I/O error
      */
-    private static int runFXScripts(final Context context, final ScriptObject global, final List<String> files) throws IOException {
-        final ScriptObject oldGlobal = Context.getGlobal();
+    private static int runFXScripts(final Context context, final Global global, final List<String> files) throws IOException {
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
         try {
             if (globalChanged) {
@@ -389,11 +390,11 @@
      * @return return code
      */
     @SuppressWarnings("resource")
-    private static int readEvalPrint(final Context context, final ScriptObject global) {
+    private static int readEvalPrint(final Context context, final Global global) {
         final String prompt = bundle.getString("shell.prompt");
         final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
         final PrintWriter err = context.getErr();
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
         final ScriptEnvironment env = context.getEnv();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8011964.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014, 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.
+ * 
+ * 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.
+ */
+
+/**
+ * JDK-8011964: need indexed access to externally-managed ByteBuffer
+ *
+ * @test
+ * @run
+ */
+
+
+var ByteBuffer = Java.type("java.nio.ByteBuffer");
+var buf = ByteBuffer.allocate(5);
+
+var obj = {}
+Object.setIndexedPropertiesToExternalArrayData(obj, buf);
+
+obj[0] = 'A'.charCodeAt(0);
+obj[1] = 'B'.charCodeAt(0);
+obj[2] = 'C'.charCodeAt(0);
+obj[3] = 'D'.charCodeAt(0);
+obj[4] = 'E'.charCodeAt(0);
+
+for (var i = 0; i < buf.capacity(); i++) {
+    print("obj[" + i + "] = " + obj[i]);
+    print("buf.get(" + i + ") = " + buf.get(i));
+}
+
+var arr = [];
+Object.setIndexedPropertiesToExternalArrayData(arr, buf);
+obj[0] = 'a'.charCodeAt(0);
+obj[1] = 'b'.charCodeAt(0);
+obj[2] = 'c'.charCodeAt(0);
+obj[3] = 'd'.charCodeAt(0);
+obj[4] = 'e'.charCodeAt(0);
+
+for (var i in arr) {
+    print("arr[" + i + "] = " + arr[i]);
+    print("buf.get(" + i + ") = " + buf.get(i));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8011964.js.EXPECTED	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,20 @@
+obj[0] = 65
+buf.get(0) = 65
+obj[1] = 66
+buf.get(1) = 66
+obj[2] = 67
+buf.get(2) = 67
+obj[3] = 68
+buf.get(3) = 68
+obj[4] = 69
+buf.get(4) = 69
+arr[0] = 97
+buf.get(0) = 97
+arr[1] = 98
+buf.get(1) = 98
+arr[2] = 99
+buf.get(2) = 99
+arr[3] = 100
+buf.get(3) = 100
+arr[4] = 101
+buf.get(4) = 101
--- a/test/script/basic/JDK-8025515.js	Mon Mar 24 13:16:11 2014 -0700
+++ b/test/script/basic/JDK-8025515.js	Mon Mar 24 13:51:59 2014 -0700
@@ -30,13 +30,23 @@
 
 // Make sure synthetic names of anonymous functions have correct line numbers
 
+function getFirstScriptFrame(stack) {
+    for (frameNum in stack) {
+        var frame = stack[frameNum];
+        if (frame.className.startsWith("jdk.nashorn.internal.scripts.Script$")) {
+            return frame;
+        }
+    }
+}
+
 function testMethodName(f, expected) {
     try {
         f();
         fail("expected error");
     } catch (e) {
-        var stack = e.getStackTrace();
-        if (stack[0].methodName !== expected) {
+        var stack = e.nashornException.getStackTrace();
+        var name = getFirstScriptFrame(stack).methodName;
+        if (name !== expected) {
             fail("got " + stack[0].methodName + ", expected " + expected);
         }
     }
@@ -44,15 +54,15 @@
 
 testMethodName(function() {
     return a.b.c;
-}, "_L45");
+}, "L:55");
 
-testMethodName(function() { throw new Error() }, "_L49");
+testMethodName(function() { throw new Error() }, "L:59");
 
 var f = (function() {
     return function() { a.b.c; };
 })();
-testMethodName(f, "_L51$_L52");
+testMethodName(f, "L:61$L:62");
 
 testMethodName((function() {
     return function() { return a.b.c; };
-})(), "_L56$_L57");
+})(), "L:66$L:67");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8029364.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ * 
+ * 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.
+ */
+
+/**
+ * JDK-8029364: NashornException to expose thrown object
+ *
+ * @test
+ * @run
+ */
+
+var m = new javax.script.ScriptEngineManager();
+var e = m.getEngineByName("nashorn");
+var g = e.eval("this");
+try {
+    e.eval("var e = new Error('foo'); e.bar = 33; throw e");
+} catch (se) {
+    // ScriptException instance's cause is a NashornException
+    print(se.getClass());
+    var cause = se.cause;
+    print(cause.getClass());
+    // NashornException instance has 'ecmaError' bean getter
+    print(cause.ecmaError);
+    // access to underlying ECMA Error object
+    print(cause.ecmaError instanceof g.Error);
+    print(cause.ecmaError.name);
+    print(cause.ecmaError.message);
+    print(cause.ecmaError.bar);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8029364.js.EXPECTED	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,7 @@
+class javax.script.ScriptException
+class jdk.nashorn.internal.runtime.ECMAException
+Error: foo
+true
+Error
+foo
+33
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8029667.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ * 
+ * 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.
+ */
+
+/**
+ * JDK-8029667: Prototype linking is incorrect
+ *
+ * @test
+ * @run
+ */
+
+function f(x) {
+  return (function inner() { 
+      var y; (function dummy() { return y })() // force own scope for the inner function
+      with({}) { // 'with' block turns off fast scopes
+          return x
+      }
+  })();
+}
+print(f(1));
+print(f(2));
+
+function g(x) { 
+  (function inner() { 
+      var y; (function dummy() { return y })() // force own scope for the inner function
+      with({}) { // 'with' block turns off fast scopes
+          // Test setter as well as getter
+          x = x + 2;
+      }
+  })();
+  print(x);
+}
+
+g(1);
+g(2);
+
+var withScopes = [{ func: function() { print("called 1");} }, { func: function() { print("called 2");} }];
+
+for(var i in withScopes) {
+    with (withScopes[i]) {
+        var main = function() {
+            var frame; // <---- this local variable caused scope to be not set properly prior to fix
+
+            function callFunc() {
+                frame = func();
+            }
+
+            callFunc();
+        }
+    }
+    main();
+}
+
+for(var i in withScopes) {
+    with (withScopes[i]) {
+        var main = function() {
+            var frame; // <---- this local variable caused scope to be not set properly prior to fix
+
+            function callFunc() {
+                frame = func = i;
+            }
+
+            callFunc();
+        }
+    }
+    main();
+} 
+
+print(withScopes[0].func);
+print(withScopes[1].func);
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8029667.js.EXPECTED	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,8 @@
+1
+2
+3
+4
+called 1
+called 2
+0
+1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8030182.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ * 
+ * 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.
+ */
+
+/**
+ * JDK-8030182: scopeCall with -1 as line number
+ *
+ * @test
+ * @run
+ */
+
+function func() {
+    throw new Error("Strange...");
+}
+
+var f2 = func;
+var f3 = func;
+var f4 = func;
+var f5 = func;
+
+// check that "scopeCall" or some such internal method
+// does not appear in script stack trace.
+try {
+    func();
+} catch(err) {
+    print(err.stack.replace(/\\/g, '/'));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8030182.js.EXPECTED	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,3 @@
+Error: Strange...
+	at func (test/script/basic/JDK-8030182.js:32)
+	at <program> (test/script/basic/JDK-8030182.js:43)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8030182_2.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ * 
+ * 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.
+ */
+
+/**
+ * JDK-8030182: scopeCall with -1 as line number
+ *
+ * @test
+ * @run
+ */
+
+var str = ""; 
+
+// large code to force splitting
+for (i = 0; i < 1000; ++i) 
+    str +="o = new Object()\n";
+
+str +="g()"; 
+
+// check that "$split" or some such internal method
+// does not appear in script stack trace!!
+try {
+    eval(str);
+} catch (e) {
+    print(e.stack.replace(/\\/g, '/'));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8030182_2.js.EXPECTED	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,3 @@
+ReferenceError: "g" is not defined
+	at <program> (test/script/basic/JDK-8030182_2.js#42:4<eval>@0:-1)
+	at <program> (test/script/basic/JDK-8030182_2.js:42)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8030197.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014, 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.
+ * 
+ * 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.
+ */
+
+
+/**
+ * JDK-8030197: Nashorn: Object.defineProperty() can be lured to change fixed NaN property
+ *
+ * @test
+ * @run
+ */
+
+function str(n) {
+    var a = new Uint8Array(new Float64Array([n]).buffer);
+    return Array.apply(null, a).reduceRight(
+        function(acc, v){
+            return acc + (v < 10 ? "0" : "") + v.toString(16);
+        }, "");
+}
+
+var o = Object.defineProperty({}, "NaN", { value: NaN })
+var str1 = str(o.NaN);
+Object.defineProperty(o, "NaN", { value: 0/0 })
+var str2 = str(o.NaN);
+if (str1 != str2) {
+    fail("NaN bit pattern changed");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8030809.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ * 
+ * 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.
+ */
+
+/**
+ * JDK-8030809: Anonymous functions should not be shown with internal names in script stack trace
+ *
+ * @test
+ * @run
+ */
+
+function func() {
+    (function() { 
+        throw new Error();
+    })();
+}
+
+try {
+    func();
+} catch (e) {
+    print(e.stack.replace(/\\/g, '/'));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8030809.js.EXPECTED	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,4 @@
+Error
+	at <anonymous> (test/script/basic/JDK-8030809.js:33)
+	at func (test/script/basic/JDK-8030809.js:32)
+	at <program> (test/script/basic/JDK-8030809.js:38)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8031317.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ * 
+ * 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.
+ */
+
+/**
+ * JDK-8031317: SyntaxError when property setter has no parameter
+ *
+ * @test
+ * @run
+ */
+
+var obj = {
+  get toto() {
+      print("in getter for 'toto'");
+  },
+  set toto() {
+      print("in setter for 'toto'");
+  }
+}
+
+obj.toto;
+obj.toto = 344;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8031317.js.EXPECTED	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,2 @@
+in getter for 'toto'
+in setter for 'toto'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8031359.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010, 2014, 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.
+ * 
+ * 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.
+ */
+
+/**
+ * JDK-8031359: Invocable.getInterface() works incorrectly if interface has default methods
+ *
+ * @test
+ * @run
+ */
+
+var func = new java.util.function.Function() {
+    apply: function(arg) {
+        print("func called with " + arg);
+        return arg.toUpperCase();
+    }
+};
+
+// Function.andThen is a default method
+func.andThen(func)("hello");
+
+// Function.compose is another default method
+func.compose(new java.util.function.Function() {
+    apply: function(arg) {
+        print("compose called with " + arg);
+        return arg.charAt(0);
+    }
+})("hello");
+
+var func2 = new java.util.function.Function() {
+    apply: function(arg) {
+        print("I am func2: " + arg);
+        return arg;
+    },
+
+    andThen: function(func) {
+        print("This is my andThen!");
+        return func;
+    }
+};
+
+func2.apply("hello");
+func2.andThen(func);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8031359.js.EXPECTED	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,6 @@
+func called with hello
+func called with HELLO
+compose called with hello
+func called with h
+I am func2: hello
+This is my andThen!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8031715.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ * 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.
+ */
+
+/**
+ * JDK-8031715: Indexed access to java package not working
+ * @test
+ * @run
+ */
+
+print(java["net"]);
+print(java["net"]["URL"]);
+print(java["net"].URL);
+print(java.net["URL"]);
+
+var is = "InputStream";
+var io = "io";
+
+print(java.io[is]);
+print(java[io]);
+print(java[io][is]);
+
+var ji = new JavaImporter(java.util, java.io);
+print(ji["InputStream"]);
+print(ji['Vector']);
+
+var hash = "Hashtable";
+var printStream = "PrintStream";
+print(ji[hash]);
+print(ji[printStream]);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8031715.js.EXPECTED	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,11 @@
+[JavaPackage java.net]
+[JavaClass java.net.URL]
+[JavaClass java.net.URL]
+[JavaClass java.net.URL]
+[JavaClass java.io.InputStream]
+[JavaPackage java.io]
+[JavaClass java.io.InputStream]
+[JavaClass java.io.InputStream]
+[JavaClass java.util.Vector]
+[JavaClass java.util.Hashtable]
+[JavaClass java.io.PrintStream]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8031983.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, 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.
+ * 
+ * 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.
+ */
+
+/**
+ * JDK-8031983: Error objects should capture stack at the constructor 
+ *
+ * @test
+ * @run
+ */
+
+var e = new Error();
+print("hello");
+
+try {
+    throw e;
+} catch (e) {
+    print(e.lineNumber);
+    print(e.stack.replace(/\\/g, '/'));
+}
+
+Error.captureStackTrace(e);
+try {
+    throw e;
+} catch (e) {
+    print(e.lineNumber);
+    print(e.stack.replace(/\\/g, '/'));
+}
+
+var obj = {};
+Error.captureStackTrace(obj);
+try {
+    throw obj;
+} catch (e) {
+    print(e.stack.replace(/\\/g, '/'));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8031983.js.EXPECTED	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,9 @@
+hello
+35
+Error
+	at <program> (test/script/basic/JDK-8031983.js:31)
+43
+Error
+	at <program> (test/script/basic/JDK-8031983.js:41)
+[object Object]
+	at <program> (test/script/basic/JDK-8031983.js:50)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8032004.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014, 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.
+ * 
+ * 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.
+ */
+
+/**
+ * JDK-8032004: instance property "message" of Error objects should be non-enumerable 
+ *
+ * @test
+ * @run
+ */
+
+function check(obj) {
+    if (obj.propertyIsEnumerable("message")) {
+        fail(obj.name + " object's message property is enumerable!");
+    }
+}
+
+check(new Error("test"));
+check(new EvalError("test"));
+check(new RangeError("test"));
+check(new ReferenceError("test"));
+check(new SyntaxError("test"));
+check(new TypeError("test"));
+check(new URIError("test"));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8032068.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014, 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.
+ * 
+ * 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.
+ */
+
+/**
+ * JDK-8032068: implement @sourceURL and #sourceURL directives.
+ *
+ * @test
+ * @run
+ */
+
+
+try {
+    Function("throw new Error();\n//# sourceURL=foo.js")();
+} catch (e) {
+    print(e.stack.replace(/\\/g, '/'));
+}
+
+try {
+    eval("function g() { throw Error('x');\n } g();\n//# sourceURL=bar.js");
+} catch (e) {
+    print(e.stack.replace(/\\/g, '/'));
+}
+
+// check @sourceURL for compatibility
+try {
+    Function("throw new Error();\n//@ sourceURL=foo2.js")();
+} catch (e) {
+    print(e.stack.replace(/\\/g, '/'));
+}
+
+try {
+    eval("function g() { throw Error('x');\n } g();\n//@ sourceURL=bar2.js");
+} catch (e) {
+    print(e.stack.replace(/\\/g, '/'));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8032068.js.EXPECTED	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,14 @@
+Error
+	at <anonymous> (foo.js:2)
+	at <program> (test/script/basic/JDK-8032068.js:33)
+Error: x
+	at g (bar.js:1)
+	at <program> (bar.js:2)
+	at <program> (test/script/basic/JDK-8032068.js:39)
+Error
+	at <anonymous> (foo2.js:2)
+	at <program> (test/script/basic/JDK-8032068.js:46)
+Error: x
+	at g (bar2.js:1)
+	at <program> (bar2.js:2)
+	at <program> (test/script/basic/JDK-8032068.js:52)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8034055.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010, 2014, 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.
+ * 
+ * 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.
+ */
+
+/**
+ * JDK-8034055: delete on global object not properly guarded
+ *
+ * @test
+ * @run
+ */
+
+
+var global = this;
+var x;
+
+function test(defineGlobals) {
+    if (defineGlobals) {
+        global.x = 1;
+        global.y = 2;
+    }
+    try {
+        print(x);
+        print(y);
+    } catch (e) {
+        print(e);
+    } finally {
+        print(delete global.x);
+        print(delete global.y);
+    }
+}
+
+// Repeatedly set and delete global variables
+test(true);
+test(false);
+test(true);
+test(false);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8034055.js.EXPECTED	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,16 @@
+1
+2
+false
+true
+1
+ReferenceError: "y" is not defined
+false
+true
+1
+2
+false
+true
+1
+ReferenceError: "y" is not defined
+false
+true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8037562.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014, 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.
+ * 
+ * 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.
+ */
+
+
+/**
+ * JDK-8037562: Nashorn: JSON.parse comes up with nonexistent entries if there are gaps between the keys
+ *
+ * @test
+ * @run
+ */
+
+var strs = [
+    '{ "0":0, "2":2       }',
+    '{ "0":"", "2":""     }',
+    '{ "0":0,  "5":"hello" }',
+    '{ "0":"", "15":3234   }',
+]
+
+for (var i in strs) {
+    print(JSON.stringify(JSON.parse(strs[i])));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8037562.js.EXPECTED	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,4 @@
+{"0":0,"2":2}
+{"0":"","2":""}
+{"0":0,"5":"hello"}
+{"0":"","15":3234}
--- a/test/script/basic/NASHORN-111.js.EXPECTED	Mon Mar 24 13:16:11 2014 -0700
+++ b/test/script/basic/NASHORN-111.js.EXPECTED	Mon Mar 24 13:51:59 2014 -0700
@@ -1,1 +1,1 @@
-{"message":"type error"}
+{}
--- a/test/script/basic/NASHORN-441.js.EXPECTED	Mon Mar 24 13:16:11 2014 -0700
+++ b/test/script/basic/NASHORN-441.js.EXPECTED	Mon Mar 24 13:51:59 2014 -0700
@@ -12,6 +12,6 @@
 try 5
 rethrow 5
 finally 5
-Error: try 5 thrown in line 71
+Error: try 5 thrown in line 74
 try 6
 finally 6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/dataview_endian.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014, 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.
+ * 
+ * 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.
+ */
+
+/**
+ * JDK-8015958: DataView constructor is not defined
+ *
+ * @test
+ * @run
+ */
+
+// set/get endianess checks
+
+var buffer = new ArrayBuffer(4);
+var dv = new DataView(buffer);
+
+// write (default) big endian, read big/little endian
+dv.setUint16(0, 0xABCD);
+Assert.assertEquals(dv.getUint16(0), 0xABCD);
+Assert.assertEquals(dv.getUint16(0, false), 0xABCD);
+Assert.assertEquals(dv.getUint16(0, true), 0xCDAB);
+
+// write little endian, read big/little endian
+dv.setUint16(0, 0xABCD, true);
+Assert.assertEquals(dv.getUint16(0), 0xCDAB);
+Assert.assertEquals(dv.getUint16(0, false), 0xCDAB);
+Assert.assertEquals(dv.getUint16(0, true), 0xABCD);
+
+// write explicit big endian, read big/little endian
+dv.setUint16(0, 0xABCD, false);
+Assert.assertEquals(dv.getUint16(0), 0xABCD);
+Assert.assertEquals(dv.getUint16(0, false), 0xABCD);
+Assert.assertEquals(dv.getUint16(0, true), 0xCDAB);
+
+// write (default) big endian, read big/little endian
+dv.setUint32(0, 0xABCDEF89);
+Assert.assertEquals(dv.getUint32(0), 0xABCDEF89);
+Assert.assertEquals(dv.getUint32(0, false), 0xABCDEF89);
+Assert.assertEquals(dv.getUint32(0, true), 0x89EFCDAB);
+
+// write little endian, read big/little endian
+dv.setUint32(0, 0xABCDEF89, true);
+Assert.assertEquals(dv.getUint32(0), 0x89EFCDAB);
+Assert.assertEquals(dv.getUint32(0, false), 0x89EFCDAB);
+Assert.assertEquals(dv.getUint32(0, true), 0xABCDEF89);
+
+// write explicit big endian, read big/little endian
+dv.setUint32(0, 0xABCDEF89, false);
+Assert.assertEquals(dv.getUint32(0), 0xABCDEF89);
+Assert.assertEquals(dv.getUint32(0, false), 0xABCDEF89);
+Assert.assertEquals(dv.getUint32(0, true), 0x89EFCDAB);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/dataview_getset.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014, 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.
+ * 
+ * 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.
+ */
+
+/**
+ * JDK-8015958: DataView constructor is not defined
+ *
+ * @test
+ * @run
+ */
+
+// checking get/set of values of various types
+// Also basic endianess check.
+
+var Float = Java.type("java.lang.Float");
+var Double = Java.type("java.lang.Double");
+
+var DOUBLE_MIN = Double.MIN_VALUE;
+var DOUBLE_MIN_NORMAL = Double.MIN_NORMAL;
+var FLOAT_MIN = Float.MIN_VALUE;
+var FLOAT_MIN_NORMAL = Float.MIN_NORMAL;
+
+var buffer = new ArrayBuffer(12);
+var dv = new DataView(buffer);
+
+dv.setInt8(1, 123);
+Assert.assertEquals(dv.getInt8(1), 123);
+dv.setInt8(1, 123, true);
+Assert.assertEquals(dv.getInt8(1, true), 123);
+
+dv.setUint8(1, 255);
+Assert.assertEquals(dv.getUint8(1), 255);
+dv.setUint8(1, 255, true);
+Assert.assertEquals(dv.getUint8(1, true), 255);
+
+dv.setInt16(1, 1234);
+Assert.assertEquals(dv.getInt16(1), 1234);
+dv.setInt16(1, 1234, true);
+Assert.assertEquals(dv.getInt16(1, true), 1234);
+
+dv.setUint16(1, 65535);
+Assert.assertEquals(dv.getUint16(1), 65535);
+dv.setUint16(1, 65535, true);
+Assert.assertEquals(dv.getUint16(1, true), 65535);
+
+dv.setInt32(1, 1234);
+Assert.assertEquals(dv.getInt32(1), 1234);
+dv.setInt32(1, 1234, true);
+Assert.assertEquals(dv.getInt32(1, true), 1234);
+
+dv.setUint32(1, 4294967295);
+Assert.assertEquals(dv.getUint32(1), 4294967295);
+dv.setUint32(1, 4294967295, true);
+Assert.assertEquals(dv.getUint32(1, true), 4294967295);
+
+dv.setFloat64(1, Math.PI);
+Assert.assertEquals(dv.getFloat64(1), Math.PI, DOUBLE_MIN);
+dv.setFloat64(1, Math.PI, true);
+Assert.assertEquals(dv.getFloat64(1, true), Math.PI, DOUBLE_MIN);
+
+dv.setFloat64(1, DOUBLE_MIN_NORMAL);
+Assert.assertEquals(dv.getFloat64(1), DOUBLE_MIN_NORMAL, DOUBLE_MIN);
+dv.setFloat64(1, DOUBLE_MIN_NORMAL, true);
+Assert.assertEquals(dv.getFloat64(1, true), DOUBLE_MIN_NORMAL, DOUBLE_MIN);
+
+dv.setFloat32(1, 1.414);
+Assert["assertEquals(float, float, float)"](dv.getFloat32(1), 1.414, FLOAT_MIN);
+dv.setFloat32(1, 1.414, true);
+Assert["assertEquals(float, float, float)"](dv.getFloat32(1, true), 1.414, FLOAT_MIN);
+
+dv.setFloat32(1, FLOAT_MIN_NORMAL);
+Assert["assertEquals(float, float, float)"](dv.getFloat32(1), FLOAT_MIN_NORMAL, FLOAT_MIN);
+dv.setFloat32(1, FLOAT_MIN_NORMAL, true);
+Assert["assertEquals(float, float, float)"](dv.getFloat32(1, true), FLOAT_MIN_NORMAL, FLOAT_MIN);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/dataview_new.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014, 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.
+ * 
+ * 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.
+ */
+
+/**
+ * JDK-8015958: DataView constructor is not defined
+ *
+ * @test
+ * @run
+ */
+
+// basic DataView constructor checks.
+
+// check ArrayBufferView property values of DataView instance
+function check(dv, buf, offset, length) {
+    if (dv.buffer !== buf) {
+        fail("DataView.buffer is wrong");
+    }
+
+    if (dv.byteOffset != offset) {
+        fail("DataView.byteOffset = " + dv.byteOffset + ", expected " + offset);
+    }
+
+    if (dv.byteLength != length) {
+        fail("DataView.byteLength = " + dv.byteLength + ", expected " + length);
+    }
+}
+
+var buffer = new ArrayBuffer(12);
+check(new DataView(buffer), buffer, 0, 12);
+check(new DataView(buffer, 2), buffer, 2, 10);
+check(new DataView(buffer, 4, 8), buffer, 4, 8);
+
+// make sure expected error is thrown
+function checkError(callback, ErrorType) {
+    try {
+        callback();
+        fail("Should have thrown " + ErrorType.name);
+    } catch (e) {
+        if (! (e instanceof ErrorType)) {
+            fail("Expected " + ErrorType.name + " got " + e);
+        }
+    }
+}
+
+// non ArrayBuffer as first arg
+checkError(function() { new DataView(344) }, TypeError);
+
+// illegal offset/length values
+checkError(function() { new DataView(buffer, -1) }, RangeError);
+checkError(function() { new DataView(buffer, 15) }, RangeError);
+checkError(function() { new DataView(buffer, 1, 32) }, RangeError);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/currently-failing/gettersetter.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014 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.
+ * 
+ * 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.
+ */
+
+/**
+ * @test
+ * @option -Dnashorn.debug=true
+ * @fork
+ */
+
+load(__DIR__ + "maputil.js");
+
+function Foo() {
+    return {
+       get foo() { return 42; },
+       set foo(x) {}
+    }
+}
+
+var obj1 = Foo();
+var obj2 = Foo();
+
+assertSameMap(obj1, obj2, "Object literals before change");
+
+Object.defineProperty(obj2, "foo", { get: function() { return 'hello' } });
+assertSameMap(obj1, obj2);
+
+Object.defineProperty(obj2, "foo", { set: function(x) { print(x) } });
+assertSameMap(obj1, obj2);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/maptests/builtins.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2014 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.
+ * 
+ * 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.
+ */
+
+/**
+ * @test
+ * @option -Dnashorn.debug=true
+ * @fork
+ */
+
+load(__DIR__ + "maputil.js");
+
+// check that builtin objects share property map
+
+assertSameMap(new Boolean(true), new Boolean(false));
+assertSameMap(new Number(3), new Number(Math.PI));
+assertSameMap(new String('hello'), new String('world'));
+assertSameMap(new Object(), new Object());
+assertSameMap(/hello/, /world/);
+// try w/without regexp flags
+assertSameMap(/hello/i, /world/g);
+assertSameMap(new Date(), new Date());
+assertSameMap(new Date(2000, 1, 1), new Date(1972, 5, 6));
+assertSameMap(Function(), Function());
+assertSameMap(Function("x", "return x"), Function("x", "return x*x"));
+assertSameMap(new Error(), new Error());
+assertSameMap(new Error('foo'), new Error('bar'));
+assertSameMap(new EvalError(), new EvalError());
+assertSameMap(new EvalError('foo'), new EvalError('bar'));
+assertSameMap(new RangeError(), new RangeError());
+assertSameMap(new RangeError('foo'), new RangeError('bar'));
+assertSameMap(new ReferenceError(), new ReferenceError());
+assertSameMap(new ReferenceError('foo'), new ReferenceError('bar'));
+assertSameMap(new SyntaxError(), new SyntaxError());
+assertSameMap(new SyntaxError('foo'), new SyntaxError('bar'));
+assertSameMap(new TypeError(), new TypeError());
+assertSameMap(new TypeError('foo'), new TypeError('bar'));
+assertSameMap(new URIError(), new URIError());
+assertSameMap(new URIError('foo'), new URIError('bar'));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/maptests/constructor.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014 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.
+ * 
+ * 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.
+ */
+
+/**
+ * @test
+ * @option -Dnashorn.debug=true
+ * @fork
+ */
+
+load(__DIR__ + "point.js");
+
+// use constructor defined in a different script file
+// These objects should share the map
+assertSameMap(new Point(2, 3), new Point(43, 23));
+assertSameMap(new Point(), new Point());
+assertSameMap(new Point(), new Point(3, 1));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/maptests/maputil.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014 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.
+ * 
+ * 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.
+ */
+
+/**
+ * @subtest
+ */
+
+function assertSameMap(obj1, obj2, msg) {
+    if (! Debug.identical(Debug.map(obj1), Debug.map(obj2))) {
+        fail(obj1.constructor + " instances don't share map");
+    }
+}
+
+function assertNotSameMap(obj1, obj2, msg) {
+    if (Debug.identical(Debug.map(obj1), Debug.map(obj2))) {
+        fail(obj1.constructor + " and " + obj2.constructor + " instances share map");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/maptests/object_create.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014 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.
+ * 
+ * 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.
+ */
+
+/**
+ * @test
+ * @option -Dnashorn.debug=true
+ * @fork
+ */
+
+load(__DIR__ + "maputil.js");
+
+// Objects created by Object.create
+var obj1 = Object.create(Object.prototype);
+var obj2 = Object.create(Object.prototype);
+assertSameMap(obj1, obj2);
+
+var proto = { foo: 233 };
+obj1 = Object.create(proto);
+obj2 = Object.create(proto);
+assertSameMap(obj1, obj2);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/maptests/object_literals.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014 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.
+ * 
+ * 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.
+ */
+
+/**
+ * @test
+ * @option -Dnashorn.debug=true
+ * @fork
+ */
+
+load(__DIR__ + "maputil.js");
+
+// Object literals created at the same callsite
+function makeObject() {
+    return { foo: 34 }
+}
+assertSameMap(makeObject(), makeObject());
+
+function makeObject2() {
+    return { foo: 42, bar: 'hello' }
+}
+assertSameMap(makeObject2(), makeObject2());
+
+// Object literals created at different callsites
+assertSameMap({}, {});
+assertSameMap({foo: 4}, {foo: 'hello'});
+assertSameMap({foo: 34, bar: 'fdgd'}, {foo: 'world', bar: 54});
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/maptests/point.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014 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.
+ * 
+ * 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.
+ */
+
+
+/**
+ * @subtest
+ */
+
+function Point(x, y) {
+   this.x =x; this.y =y;
+}
+
+Point.prototype.toString = function() {
+    return "(" + this.x + "," + this.y + ")";
+}
+
+Point.prototype.modulus = function() {
+    return Math.sqrt(this.x*this.x + this.y*this.y);
+}
+
+Point.prototype.argument = function() {
+    return Math.atan2(this.y, this.x);
+}
+
+load(__DIR__ + "maputil.js");
+
+assertSameMap(new Point(2, 3), new Point(43, 23));
+assertSameMap(new Point(), new Point());
+assertSameMap(new Point(), new Point(3, 1));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/maptests/property_add.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014 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.
+ * 
+ * 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.
+ */
+
+/**
+ * @test
+ * @option -Dnashorn.debug=true
+ * @fork
+ */
+
+load(__DIR__ + "maputil.js");
+
+function Foo() {}
+
+var obj1 = new Foo();
+var obj2 = new Foo();
+
+assertSameMap(obj1, obj2);
+
+// property addition at same callsite
+function addX(obj, val) {
+   obj.x = val;
+}
+addX(obj1, 3);
+addX(obj2, 'hello');
+
+assertSameMap(obj1, obj2);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/maptests/property_delete.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014 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.
+ * 
+ * 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.
+ */
+
+/**
+ * @test
+ * @option -Dnashorn.debug=true
+ * @fork
+ */
+
+load(__DIR__ + "maputil.js");
+
+function Foo() {
+    this.x = 33;
+}
+
+var obj1 = new Foo();
+var obj2 = new Foo();
+
+assertSameMap(obj1, obj2);
+
+// property deletion at same callsite
+function deleteX(obj) {
+   delete obj.x;
+}
+deleteX(obj1);
+deleteX(obj2);
+
+assertSameMap(obj1, obj2);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/maptests/proto.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014 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.
+ * 
+ * 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.
+ */
+
+/**
+ * @test
+ * @option -Dnashorn.debug=true
+ * @fork
+ */
+
+load(__DIR__ + "maputil.js");
+
+// add/delete property to proto (direct/indirect) should
+// not affect the property map of the objects
+
+var proto2 = { foo: 334 }
+var proto  = Object.create(proto2);
+proto.bar = "hello";
+
+var obj1 = Object.create(proto);
+var obj2 = Object.create(proto);
+
+assertSameMap(obj1, obj2);
+
+proto.newX = 'world';
+assertSameMap(obj1, obj2);
+
+delete proto.newX;
+assertSameMap(obj1, obj2);
+
+proto2.newX = "foo";
+assertSameMap(obj1, obj2);
+
+delete proto2.newX;
+assertSameMap(obj1, obj2);
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/sandbox/JDK-8031106.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010, 2014, 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.
+ * 
+ * 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.
+ */
+
+/**
+ * JDK-8031106: Nashorn: IndexOutOfBoundsException in NashornCallSiteDescriptor.getNameToken()
+ *
+ * @test
+ * @run
+ */
+
+var cl = new java.lang.Object().getClass();
+try {
+   cl["forName"];
+   fail("Should have thrown exception!");
+} catch (e) {
+   if (! (e instanceof java.lang.SecurityException)) {
+       fail("SecurityException expected, got " + e);
+   }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/sandbox/safeprops.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2014 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.
+ *
+ * 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.
+ */
+
+/**
+ * Try to access System properties safe to read for any code.
+ * No security exception expected.
+ *
+ * @test
+ * @security
+ * @run
+ * @bug 8033924: Default permissions are not given for eval code
+ */
+
+var propNames = [
+   "java.version",
+   "java.vendor",
+   "java.vendor.url",
+   "java.class.version",
+   "os.name",
+   "os.version",
+   "os.arch",
+   "file.separator",
+   "path.separator",
+   "line.separator",
+   "java.specification.version",
+   "java.specification.vendor",
+   "java.specification.name",
+   "java.vm.specification.version",
+   "java.vm.specification.vendor",
+   "java.vm.specification.name",
+   "java.vm.version",
+   "java.vm.vendor",
+   "java.vm.name"
+];
+
+// no security exception expected
+for (var p in propNames) {
+    java.lang.System.getProperty(propNames[p]);
+}
+
+// no security exception expected
+for (var p in propNames) {
+    var name = propNames[p];
+    eval('java.lang.System.getProperty(name)');
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/trusted/JDK-8032060.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2014, 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.
+ * 
+ * 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.
+ */
+
+/**
+ * JDK-8032060: PropertyMap of Error objects is not stable
+ *
+ * @test
+ * @option -Dnashorn.debug=true
+ * @fork
+ * @run
+ */
+
+function checkMap(e1, e2) {
+    if (! Debug.identical(Debug.map(e1), Debug.map(e2))) {
+        fail("e1 and e2 have different maps");
+    }
+
+    var m1, m2;
+
+    try {
+        throw e1
+    } catch (e) {
+        m1 = Debug.map(e)
+    }
+
+    try {
+        throw e2
+    } catch (e) {
+        m2 = Debug.map(e)
+    }
+
+    if (! Debug.identical(m1, m2)) {
+        fail("e1 and e2 have different maps after being thrown");
+    }
+}
+
+checkMap(new Error(), new Error());
+checkMap(new EvalError(), new EvalError());
+checkMap(new RangeError(), new RangeError());
+checkMap(new ReferenceError(), new ReferenceError());
+checkMap(new SyntaxError(), new SyntaxError());
+checkMap(new TypeError(), new TypeError());
+checkMap(new URIError(), new URIError());
+
+// now try with message param
+checkMap(new Error("x"), new Error("y"));
+checkMap(new EvalError("x"), new EvalError("y"));
+checkMap(new RangeError("x"), new RangeError("y"));
+checkMap(new ReferenceError("x"), new ReferenceError("y"));
+checkMap(new SyntaxError("x"), new SyntaxError("y"));
+checkMap(new TypeError("x"), new TypeError("y"));
+checkMap(new URIError("x"), new URIError("y"));
--- a/test/src/jdk/nashorn/api/scripting/InvocableTest.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/test/src/jdk/nashorn/api/scripting/InvocableTest.java	Mon Mar 24 13:51:59 2014 -0700
@@ -26,6 +26,7 @@
 package jdk.nashorn.api.scripting;
 
 import java.util.Objects;
+import java.util.function.Function;
 import javax.script.Invocable;
 import javax.script.ScriptContext;
 import javax.script.ScriptEngine;
@@ -522,4 +523,16 @@
         Assert.assertEquals(itf.test1(42, "a", "b"), "i == 42, strings instanceof java.lang.String[] == true, strings == [a, b]");
         Assert.assertEquals(itf.test2(44, "c", "d", "e"), "arguments[0] == 44, arguments[1] instanceof java.lang.String[] == true, arguments[1] == [c, d, e]");
     }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void defaultMethodTest() throws ScriptException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Invocable inv = (Invocable) e;
+
+        Object obj = e.eval("({ apply: function(arg) { return arg.toUpperCase(); }})");
+        Function<String, String> func = inv.getInterface(obj, Function.class);
+        assertEquals(func.apply("hello"), "HELLO");
+    }
 }
--- a/test/src/jdk/nashorn/api/scripting/ScopeTest.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/test/src/jdk/nashorn/api/scripting/ScopeTest.java	Mon Mar 24 13:51:59 2014 -0700
@@ -245,4 +245,320 @@
         sb.put("x", "newX");
         assertTrue(e.eval("x", ctx).equals("newX"));
     }
+
+    /**
+     * Test multi-threaded access to defined global variables for shared script classes with multiple globals.
+     */
+    @Test
+    public static void multiThreadedVarTest() throws ScriptException, InterruptedException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Bindings b = e.createBindings();
+        final ScriptContext origContext = e.getContext();
+        final ScriptContext newCtxt = new SimpleScriptContext();
+        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+        final String sharedScript = "foo";
+
+        assertEquals(e.eval("var foo = 'original context';", origContext), null);
+        assertEquals(e.eval("var foo = 'new context';", newCtxt), null);
+
+        final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+        final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
+
+        assertEquals(e.eval("var foo = 'newer context';", newCtxt), null);
+        final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+        final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
+
+        t3.start();
+        t4.start();
+        t3.join();
+        t4.join();
+
+        assertEquals(e.eval(sharedScript), "original context");
+        assertEquals(e.eval(sharedScript, newCtxt), "newer context");
+    }
+
+    /**
+     * Test multi-threaded access to undefined global variables for shared script classes with multiple globals.
+     */
+    @Test
+    public static void multiThreadedGlobalTest() throws ScriptException, InterruptedException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Bindings b = e.createBindings();
+        final ScriptContext origContext = e.getContext();
+        final ScriptContext newCtxt = new SimpleScriptContext();
+        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+        assertEquals(e.eval("foo = 'original context';", origContext), "original context");
+        assertEquals(e.eval("foo = 'new context';", newCtxt), "new context");
+        final String sharedScript = "foo";
+
+        final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+        final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
+
+        Object obj3 = e.eval("delete foo; foo = 'newer context';", newCtxt);
+        assertEquals(obj3, "newer context");
+        final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+        final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
+
+        t3.start();
+        t4.start();
+        t3.join();
+        t4.join();
+
+        Assert.assertEquals(e.eval(sharedScript), "original context");
+        Assert.assertEquals(e.eval(sharedScript, newCtxt), "newer context");
+    }
+
+    /**
+     * Test multi-threaded access using the postfix ++ operator for shared script classes with multiple globals.
+     */
+    @Test
+    public static void multiThreadedIncTest() throws ScriptException, InterruptedException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Bindings b = e.createBindings();
+        final ScriptContext origContext = e.getContext();
+        final ScriptContext newCtxt = new SimpleScriptContext();
+        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+        assertEquals(e.eval("var x = 0;", origContext), null);
+        assertEquals(e.eval("var x = 2;", newCtxt), null);
+        final String sharedScript = "x++;";
+
+        final Thread t1 = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    for (int i = 0; i < 1000; i++) {
+                        assertEquals(e.eval(sharedScript, origContext), (double)i);
+                    }
+                } catch (ScriptException se) {
+                    fail(se.toString());
+                }
+            }
+        });
+        final Thread t2 = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    for (int i = 2; i < 1000; i++) {
+                        assertEquals(e.eval(sharedScript, newCtxt), (double)i);
+                    }
+                } catch (ScriptException se) {
+                    fail(se.toString());
+                }
+            }
+        });
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
+    }
+
+    /**
+     * Test multi-threaded access to primitive prototype properties for shared script classes with multiple globals.
+     */
+    @Test
+    public static void multiThreadedPrimitiveTest() throws ScriptException, InterruptedException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Bindings b = e.createBindings();
+        final ScriptContext origContext = e.getContext();
+        final ScriptContext newCtxt = new SimpleScriptContext();
+        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+        Object obj1 = e.eval("String.prototype.foo = 'original context';", origContext);
+        Object obj2 = e.eval("String.prototype.foo = 'new context';", newCtxt);
+        assertEquals(obj1, "original context");
+        assertEquals(obj2, "new context");
+        final String sharedScript = "''.foo";
+
+        final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+        final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
+
+        Object obj3 = e.eval("delete String.prototype.foo; Object.prototype.foo = 'newer context';", newCtxt);
+        assertEquals(obj3, "newer context");
+        final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+        final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
+
+        t3.start();
+        t4.start();
+        t3.join();
+        t4.join();
+
+        Assert.assertEquals(e.eval(sharedScript), "original context");
+        Assert.assertEquals(e.eval(sharedScript, newCtxt), "newer context");
+    }
+
+    /**
+     * Test multi-threaded scope function invocation for shared script classes with multiple globals.
+     */
+    @Test
+    public static void multiThreadedFunctionTest() throws ScriptException, InterruptedException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Bindings b = e.createBindings();
+        final ScriptContext origContext = e.getContext();
+        final ScriptContext newCtxt = new SimpleScriptContext();
+        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+        e.eval(new URLReader(ScopeTest.class.getResource("resources/func.js")), origContext);
+        assertEquals(origContext.getAttribute("scopeVar"), 1);
+        assertEquals(e.eval("scopeTest()"), 1);
+
+        e.eval(new URLReader(ScopeTest.class.getResource("resources/func.js")), newCtxt);
+        assertEquals(newCtxt.getAttribute("scopeVar"), 1);
+        assertEquals(e.eval("scopeTest();", newCtxt), 1);
+
+        assertEquals(e.eval("scopeVar = 3;", newCtxt), 3);
+        assertEquals(newCtxt.getAttribute("scopeVar"), 3);
+
+
+        final Thread t1 = new Thread(new ScriptRunner(e, origContext, "scopeTest()", 1, 1000));
+        final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, "scopeTest()", 3, 1000));
+
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
+
+    }
+
+    /**
+     * Test multi-threaded access to global getters and setters for shared script classes with multiple globals.
+     */
+    @Test
+    public static void getterSetterTest() throws ScriptException, InterruptedException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Bindings b = e.createBindings();
+        final ScriptContext origContext = e.getContext();
+        final ScriptContext newCtxt = new SimpleScriptContext();
+        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+        final String sharedScript = "accessor1";
+
+        e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), origContext);
+        assertEquals(e.eval("accessor1 = 1;"), 1);
+        assertEquals(e.eval(sharedScript), 1);
+
+        e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), newCtxt);
+        assertEquals(e.eval("accessor1 = 2;", newCtxt), 2);
+        assertEquals(e.eval(sharedScript, newCtxt), 2);
+
+
+        final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, 1, 1000));
+        final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, 2, 1000));
+
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
+
+        assertEquals(e.eval(sharedScript), 1);
+        assertEquals(e.eval(sharedScript, newCtxt), 2);
+        assertEquals(e.eval("v"), 1);
+        assertEquals(e.eval("v", newCtxt), 2);
+    }
+
+    /**
+     * Test multi-threaded access to global getters and setters for shared script classes with multiple globals.
+     */
+    @Test
+    public static void getterSetter2Test() throws ScriptException, InterruptedException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Bindings b = e.createBindings();
+        final ScriptContext origContext = e.getContext();
+        final ScriptContext newCtxt = new SimpleScriptContext();
+        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+        final String sharedScript = "accessor2";
+
+        e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), origContext);
+        assertEquals(e.eval("accessor2 = 1;"), 1);
+        assertEquals(e.eval(sharedScript), 1);
+
+        e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), newCtxt);
+        assertEquals(e.eval("accessor2 = 2;", newCtxt), 2);
+        assertEquals(e.eval(sharedScript, newCtxt), 2);
+
+
+        final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, 1, 1000));
+        final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, 2, 1000));
+
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
+
+        assertEquals(e.eval(sharedScript), 1);
+        assertEquals(e.eval(sharedScript, newCtxt), 2);
+        assertEquals(e.eval("x"), 1);
+        assertEquals(e.eval("x", newCtxt), 2);
+    }
+
+    /**
+     * Test "slow" scopes involving {@code with} and {@code eval} statements for shared script classes with multiple globals.
+     */
+    @Test
+    public static void testSlowScope() throws ScriptException, InterruptedException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+
+        for (int i = 0; i < 100; i++) {
+            final Bindings b = e.createBindings();
+            final ScriptContext ctxt = new SimpleScriptContext();
+            ctxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+            e.eval(new URLReader(ScopeTest.class.getResource("resources/witheval.js")), ctxt);
+            assertEquals(e.eval("a", ctxt), 1);
+            assertEquals(b.get("a"), 1);
+            assertEquals(e.eval("b", ctxt), 3);
+            assertEquals(b.get("b"), 3);
+            assertEquals(e.eval("c", ctxt), 10);
+            assertEquals(b.get("c"), 10);
+        }
+    }
+
+    private static class ScriptRunner implements Runnable {
+
+        final ScriptEngine engine;
+        final ScriptContext context;
+        final String source;
+        final Object expected;
+        final int iterations;
+
+        ScriptRunner(final ScriptEngine engine, final ScriptContext context, final String source, final Object expected, final int iterations) {
+            this.engine = engine;
+            this.context = context;
+            this.source = source;
+            this.expected = expected;
+            this.iterations = iterations;
+        }
+
+        @Override
+        public void run() {
+            try {
+                for (int i = 0; i < iterations; i++) {
+                    assertEquals(engine.eval(source, context), expected);
+                }
+            } catch (ScriptException se) {
+                throw new RuntimeException(se);
+            }
+        }
+    }
+
 }
--- a/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java	Mon Mar 24 13:51:59 2014 -0700
@@ -560,6 +560,47 @@
         assertTrue(reached[0]);
     }
 
+    // properties that can be read by any code
+    private static String[] propNames = {
+        "java.version",
+        "java.vendor",
+        "java.vendor.url",
+        "java.class.version",
+        "os.name",
+        "os.version",
+        "os.arch",
+        "file.separator",
+        "path.separator",
+        "line.separator",
+        "java.specification.version",
+        "java.specification.vendor",
+        "java.specification.name",
+        "java.vm.specification.version",
+        "java.vm.specification.vendor",
+        "java.vm.specification.name",
+        "java.vm.version",
+        "java.vm.vendor",
+        "java.vm.name"
+    };
+
+    // @bug 8033924: Default permissions are not given for eval code
+    @Test
+    public void checkPropertyReadPermissions() throws ScriptException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+
+        for (final String name : propNames) {
+            checkProperty(e, name);
+        }
+    }
+
+    private static void checkProperty(final ScriptEngine e, final String name)
+        throws ScriptException {
+        String value = System.getProperty(name);
+        e.put("name", name);
+        assertEquals(value, e.eval("java.lang.System.getProperty(name)"));
+    }
+
     private static final String LINE_SEPARATOR = System.getProperty("line.separator");
 
     // Returns String that would be the result of calling PrintWriter.println
--- a/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java	Mon Mar 24 13:51:59 2014 -0700
@@ -25,6 +25,7 @@
 
 package jdk.nashorn.api.scripting;
 
+import java.nio.ByteBuffer;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -230,6 +231,29 @@
     }
 
     @Test
+    public void indexPropertiesExternalBufferTest() throws ScriptException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final ScriptObjectMirror obj = (ScriptObjectMirror)e.eval("var obj = {}; obj");
+        final ByteBuffer buf = ByteBuffer.allocate(5);
+        int i;
+        for (i = 0; i < 5; i++) {
+            buf.put(i, (byte)(i+10));
+        }
+        obj.setIndexedPropertiesToExternalArrayData(buf);
+
+        for (i = 0; i < 5; i++) {
+            assertEquals((byte)(i+10), ((Number)e.eval("obj[" + i + "]")).byteValue());
+        }
+
+        e.eval("for (i = 0; i < 5; i++) obj[i] = 0");
+        for (i = 0; i < 5; i++) {
+            assertEquals((byte)0, ((Number)e.eval("obj[" + i + "]")).byteValue());
+            assertEquals((byte)0, buf.get(i));
+        }
+    }
+
+    @Test
     public void conversionTest() throws ScriptException {
         final ScriptEngineManager m = new ScriptEngineManager();
         final ScriptEngine e = m.getEngineByName("nashorn");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/src/jdk/nashorn/api/scripting/resources/func.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010, 2014, 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.
+ */
+
+// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse.
+
+var scopeVar = 1;
+var global = this;
+undefGlobal = this;
+
+function scopeTest() {
+    if (this !== global) {
+        throw new Error("this !== global");
+    }
+    if (this !== undefGlobal) {
+        throw new Error("this !== undefinedGlobal")
+    }
+    return scopeVar;
+}
+
+scopeTest();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/src/jdk/nashorn/api/scripting/resources/gettersetter.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010, 2014, 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.
+ */
+
+// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse.
+
+var v;
+
+Object.defineProperty(this, "accessor1", {
+    get: function() { return v; },
+    set: function(n) { v = n; }
+});
+
+Object.defineProperty(this, "accessor2", {
+    get: function() { return x; },
+    set: function(n) { x = n; }
+});
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/src/jdk/nashorn/api/scripting/resources/witheval.js	Mon Mar 24 13:51:59 2014 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2010, 2014, 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.
+ */
+
+// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse.
+
+var a;
+
+function outer(p, e) {
+    eval(e);
+    with(p) {
+        function inner() {
+            a = 1;
+            c = 10;
+            if (a !== 1) {
+                throw new Error("a !== 1");
+            }
+            if (b !== 3) {
+                throw new Error("b !== 3");
+            }
+            if (c !== 10) {
+                throw new Error("c !== 10");
+            }
+        }
+        inner();
+    }
+}
+
+outer({}, "b = 3;");
+
+if (a !== 1) {
+    throw new Error("a !== 1");
+}
+if (b !== 3) {
+    throw new Error("b !== 3");
+}
+if (c !== 10) {
+    throw new Error("c !== 10");
+}
--- a/test/src/jdk/nashorn/internal/codegen/CompilerTest.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/test/src/jdk/nashorn/internal/codegen/CompilerTest.java	Mon Mar 24 13:51:59 2014 -0700
@@ -28,6 +28,7 @@
 import java.io.File;
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ErrorManager;
 import jdk.nashorn.internal.runtime.ScriptFunction;
@@ -58,7 +59,7 @@
     }
 
     private Context context;
-    private ScriptObject global;
+    private Global  global;
 
     @BeforeClass
     public void setupTest() {
@@ -146,7 +147,7 @@
             log("Begin compiling " + file.getAbsolutePath());
         }
 
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
 
         try {
--- a/test/src/jdk/nashorn/internal/performance/PerformanceWrapper.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/test/src/jdk/nashorn/internal/performance/PerformanceWrapper.java	Mon Mar 24 13:51:59 2014 -0700
@@ -31,9 +31,9 @@
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ScriptFunction;
-import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 
 /**
@@ -89,7 +89,7 @@
     @Override
     protected Object apply(final ScriptFunction target, final Object self) {
         if (_runsPerIteration == 0 && _numberOfIterations == 0) {
-            final ScriptObject global = jdk.nashorn.internal.runtime.Context.getGlobal();
+            final Global global = jdk.nashorn.internal.runtime.Context.getGlobal();
             final ScriptFunction _target = target;
             final Object _self = self;
 
--- a/test/src/jdk/nashorn/internal/runtime/ContextTest.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/test/src/jdk/nashorn/internal/runtime/ContextTest.java	Mon Mar 24 13:51:59 2014 -0700
@@ -29,6 +29,7 @@
 import static org.testng.Assert.assertTrue;
 
 import java.util.Map;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.options.Options;
 import org.testng.annotations.Test;
 
@@ -45,7 +46,7 @@
         final Options options = new Options("");
         final ErrorManager errors = new ErrorManager();
         final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader());
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         Context.setGlobal(cx.createGlobal());
         try {
             String code = "22 + 10";
@@ -65,7 +66,7 @@
         final ErrorManager errors = new ErrorManager();
         final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader());
         final boolean strict = cx.getEnv()._strict;
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         Context.setGlobal(cx.createGlobal());
 
         try {
--- a/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java	Mon Mar 24 13:16:11 2014 -0700
+++ b/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java	Mon Mar 24 13:51:59 2014 -0700
@@ -34,10 +34,10 @@
 import java.io.OutputStream;
 import java.io.PrintWriter;
 import jdk.nashorn.api.scripting.NashornException;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ErrorManager;
 import jdk.nashorn.internal.runtime.ScriptFunction;
-import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.Source;
 import jdk.nashorn.internal.runtime.options.Options;
@@ -110,12 +110,12 @@
 
     @Override
     public int run(final OutputStream out, final OutputStream err, final String[] args) throws IOException {
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         try {
             ctxOut.setDelegatee(out);
             ctxErr.setDelegatee(err);
             final ErrorManager errors = context.getErrorManager();
-            final ScriptObject global = context.createGlobal();
+            final Global global = context.createGlobal();
             Context.setGlobal(global);
 
             // For each file on the command line.