changeset 1338:0fddb652c2bb

Merge
author prr
date Mon, 22 Jun 2015 13:29:27 -0700
parents 4c0edd9f9342 (current diff) 3379235149c0 (diff)
children 0b60cae91ec6
files
diffstat 19 files changed, 311 insertions(+), 180 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Wed May 27 17:35:21 2015 +0200
+++ b/.hgtags	Mon Jun 22 13:29:27 2015 -0700
@@ -302,3 +302,4 @@
 9dd95cff9dae897e8dee712f1f0303c460262288 jdk9-b66
 f822b749821e364cae0b7bd7c8f667d9437e6d83 jdk9-b67
 dd6dd848b854dbd3f3cc422668276b1ae0834179 jdk9-b68
+194b74467afcab3ca0096f04570def424977215d jdk9-b69
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java	Wed May 27 17:35:21 2015 +0200
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java	Mon Jun 22 13:29:27 2015 -0700
@@ -152,6 +152,7 @@
         }
 
         if (constructor != null) {
+            initPrototype(mi);
             final int arity = constructor.getArity();
             if (arity != MemberInfo.DEFAULT_ARITY) {
                 mi.loadThis();
@@ -193,6 +194,7 @@
     }
 
     private void initFunctionFields(final MethodGenerator mi) {
+        assert memberCount > 0;
         for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
             if (!memInfo.isConstructorFunction()) {
                 continue;
@@ -204,37 +206,39 @@
     }
 
     private void initDataFields(final MethodGenerator mi) {
-         for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
-            if (!memInfo.isConstructorProperty() || memInfo.isFinal()) {
-                continue;
-            }
-            final Object value = memInfo.getValue();
-            if (value != null) {
-                mi.loadThis();
-                mi.loadLiteral(value);
-                mi.putField(className, memInfo.getJavaName(), memInfo.getJavaDesc());
-            } else if (!memInfo.getInitClass().isEmpty()) {
-                final String clazz = memInfo.getInitClass();
-                mi.loadThis();
-                mi.newObject(clazz);
-                mi.dup();
-                mi.invokeSpecial(clazz, INIT, DEFAULT_INIT_DESC);
-                mi.putField(className, memInfo.getJavaName(), memInfo.getJavaDesc());
-            }
+        assert memberCount > 0;
+        for (final MemberInfo memInfo : scriptClassInfo.getMembers()) {
+           if (!memInfo.isConstructorProperty() || memInfo.isFinal()) {
+               continue;
+           }
+           final Object value = memInfo.getValue();
+           if (value != null) {
+               mi.loadThis();
+               mi.loadLiteral(value);
+               mi.putField(className, memInfo.getJavaName(), memInfo.getJavaDesc());
+           } else if (!memInfo.getInitClass().isEmpty()) {
+               final String clazz = memInfo.getInitClass();
+               mi.loadThis();
+               mi.newObject(clazz);
+               mi.dup();
+               mi.invokeSpecial(clazz, INIT, DEFAULT_INIT_DESC);
+               mi.putField(className, memInfo.getJavaName(), memInfo.getJavaDesc());
+           }
         }
+    }
 
-        if (constructor != null) {
-            mi.loadThis();
-            final String protoName = scriptClassInfo.getPrototypeClassName();
-            mi.newObject(protoName);
-            mi.dup();
-            mi.invokeSpecial(protoName, INIT, DEFAULT_INIT_DESC);
-            mi.dup();
-            mi.loadThis();
-            mi.invokeStatic(PROTOTYPEOBJECT_TYPE, PROTOTYPEOBJECT_SETCONSTRUCTOR,
-                    PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC);
-            mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETPROTOTYPE, SCRIPTFUNCTION_SETPROTOTYPE_DESC);
-        }
+    private void initPrototype(final MethodGenerator mi) {
+        assert constructor != null;
+        mi.loadThis();
+        final String protoName = scriptClassInfo.getPrototypeClassName();
+        mi.newObject(protoName);
+        mi.dup();
+        mi.invokeSpecial(protoName, INIT, DEFAULT_INIT_DESC);
+        mi.dup();
+        mi.loadThis();
+        mi.invokeStatic(PROTOTYPEOBJECT_TYPE, PROTOTYPEOBJECT_SETCONSTRUCTOR,
+                PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC);
+        mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETPROTOTYPE, SCRIPTFUNCTION_SETPROTOTYPE_DESC);
     }
 
     /**
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/Main.java	Wed May 27 17:35:21 2015 +0200
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/Main.java	Mon Jun 22 13:29:27 2015 -0700
@@ -140,7 +140,7 @@
                 String simpleName = inFile.getName();
                 simpleName = simpleName.substring(0, simpleName.indexOf(".class"));
 
-                if (sci.getPrototypeMemberCount() > 0) {
+                if (sci.isPrototypeNeeded()) {
                     // generate prototype class
                     final PrototypeGenerator protGen = new PrototypeGenerator(sci);
                     buf = protGen.getClassBytes();
@@ -152,7 +152,7 @@
                     }
                 }
 
-                if (sci.getConstructorMemberCount() > 0 || sci.getConstructor() != null) {
+                if (sci.isConstructorNeeded()) {
                     // generate constructor class
                     final ConstructorGenerator consGen = new ConstructorGenerator(sci);
                     buf = consGen.getClassBytes();
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java	Wed May 27 17:35:21 2015 +0200
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java	Mon Jun 22 13:29:27 2015 -0700
@@ -126,10 +126,42 @@
         return Collections.unmodifiableList(res);
     }
 
+    boolean isConstructorNeeded() {
+        // Constructor class generation is needed if we one or
+        // more constructor properties are defined or @Constructor
+        // is defined in the class.
+        for (final MemberInfo memInfo : members) {
+            if (memInfo.getKind() == Kind.CONSTRUCTOR ||
+                memInfo.getWhere() == Where.CONSTRUCTOR) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    boolean isPrototypeNeeded() {
+        // Prototype class generation is needed if we have atleast one
+        // prototype property or @Constructor defined in the class.
+        for (final MemberInfo memInfo : members) {
+            if (memInfo.getWhere() == Where.PROTOTYPE || memInfo.isConstructor()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     int getPrototypeMemberCount() {
         int count = 0;
         for (final MemberInfo memInfo : members) {
-            if (memInfo.getWhere() == Where.PROTOTYPE || memInfo.isConstructor()) {
+            switch (memInfo.getKind()) {
+                case SETTER:
+                case SPECIALIZED_FUNCTION:
+                    // SETTER was counted when GETTER was encountered.
+                    // SPECIALIZED_FUNCTION was counted as FUNCTION already.
+                    continue;
+            }
+
+            if (memInfo.getWhere() == Where.PROTOTYPE) {
                 count++;
             }
         }
@@ -139,6 +171,16 @@
     int getConstructorMemberCount() {
         int count = 0;
         for (final MemberInfo memInfo : members) {
+            switch (memInfo.getKind()) {
+                case CONSTRUCTOR:
+                case SETTER:
+                case SPECIALIZED_FUNCTION:
+                    // SETTER was counted when GETTER was encountered.
+                    // Constructor and constructor SpecializedFunctions
+                    // are not added as members and so not counted.
+                    continue;
+            }
+
             if (memInfo.getWhere() == Where.CONSTRUCTOR) {
                 count++;
             }
@@ -149,6 +191,14 @@
     int getInstancePropertyCount() {
         int count = 0;
         for (final MemberInfo memInfo : members) {
+            switch (memInfo.getKind()) {
+                case SETTER:
+                case SPECIALIZED_FUNCTION:
+                    // SETTER was counted when GETTER was encountered.
+                    // SPECIALIZED_FUNCTION was counted as FUNCTION already.
+                    continue;
+            }
+
             if (memInfo.getWhere() == Where.INSTANCE) {
                 count++;
             }
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java	Wed May 27 17:35:21 2015 +0200
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java	Mon Jun 22 13:29:27 2015 -0700
@@ -288,9 +288,7 @@
                                         where = Where.PROTOTYPE;
                                         break;
                                     case SPECIALIZED_FUNCTION:
-                                        if (isSpecializedConstructor) {
-                                            where = Where.CONSTRUCTOR;
-                                        }
+                                        where = isSpecializedConstructor? Where.CONSTRUCTOR : Where.PROTOTYPE;
                                         //fallthru
                                     default:
                                         break;
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ConstantData.java	Wed May 27 17:35:21 2015 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ConstantData.java	Mon Jun 22 13:29:27 2015 -0700
@@ -30,6 +30,8 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
+
 import jdk.nashorn.internal.runtime.PropertyMap;
 
 /**
@@ -120,7 +122,7 @@
         private final int hashCode;
 
         public PropertyMapWrapper(final PropertyMap map) {
-            this.hashCode = Arrays.hashCode(map.getProperties());
+            this.hashCode = Arrays.hashCode(map.getProperties()) + 31 * Objects.hashCode(map.getClassName());
             this.propertyMap = map;
         }
 
@@ -131,8 +133,13 @@
 
         @Override
         public boolean equals(final Object other) {
-            return other instanceof PropertyMapWrapper &&
-                    Arrays.equals(propertyMap.getProperties(), ((PropertyMapWrapper) other).propertyMap.getProperties());
+            if (!(other instanceof PropertyMapWrapper)) {
+                return false;
+            }
+            final PropertyMap otherMap = ((PropertyMapWrapper) other).propertyMap;
+            return propertyMap == otherMap
+                    || (Arrays.equals(propertyMap.getProperties(), otherMap.getProperties())
+                        && Objects.equals(propertyMap.getClassName(), otherMap.getClassName()));
         }
     }
 
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/types/BooleanType.java	Wed May 27 17:35:21 2015 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/types/BooleanType.java	Mon Jun 22 13:29:27 2015 -0700
@@ -1,28 +1,3 @@
-/*
- * 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.
- */
-
 /*
  * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java	Wed May 27 17:35:21 2015 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java	Mon Jun 22 13:29:27 2015 -0700
@@ -87,7 +87,7 @@
  * Representation of global scope.
  */
 @ScriptClass("Global")
-public final class Global extends ScriptObject implements Scope {
+public final class Global extends Scope {
     // Placeholder value used in place of a location property (__FILE__, __DIR__, __LINE__)
     private static final Object LOCATION_PROPERTY_PLACEHOLDER = new Object();
     private final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
@@ -906,9 +906,6 @@
      */
     private ScriptFunction typeErrorThrower;
 
-    // Flag to indicate that a split method issued a return statement
-    private int splitState = -1;
-
     // Used to store the last RegExp result to support deprecated RegExp constructor properties
     private RegExpResult lastRegExpResult;
 
@@ -995,7 +992,6 @@
     public Global(final Context context) {
         super(checkAndGetMap(context));
         this.context = context;
-        this.setIsScope();
         this.lexicalScope = context.getEnv()._es6 ? new LexicalScope(this) : null;
     }
 
@@ -2355,26 +2351,6 @@
     }
 
     /**
-     * Get the current split state.
-     *
-     * @return current split state
-     */
-    @Override
-    public int getSplitState() {
-        return splitState;
-    }
-
-    /**
-     * Set the current split state.
-     *
-     * @param state current split state
-     */
-    @Override
-    public void setSplitState(final int state) {
-        splitState = state;
-    }
-
-    /**
      * Return the ES6 global scope for lexically declared bindings.
      * @return the ES6 lexical global scope.
      */
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeDebug.java	Wed May 27 17:35:21 2015 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeDebug.java	Mon Jun 22 13:29:27 2015 -0700
@@ -37,6 +37,7 @@
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.PropertyListeners;
 import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.Scope;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
@@ -245,7 +246,7 @@
         final PrintWriter out = Context.getCurrentErr();
 
         out.println("ScriptObject count " + ScriptObject.getCount());
-        out.println("Scope count " + ScriptObject.getScopeCount());
+        out.println("Scope count " + Scope.getCount());
         out.println("ScriptObject listeners added " + PropertyListeners.getListenersAdded());
         out.println("ScriptObject listeners removed " + PropertyListeners.getListenersRemoved());
         out.println("ScriptFunction constructor calls " + ScriptFunction.getConstructorCount());
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/AbstractParser.java	Wed May 27 17:35:21 2015 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/AbstractParser.java	Mon Jun 22 13:29:27 2015 -0700
@@ -459,6 +459,19 @@
         if (kind == TokenKind.KEYWORD || kind == TokenKind.FUTURE || kind == TokenKind.FUTURESTRICT) {
             return true;
         }
+
+        // only literals allowed are null, false and true
+        if (kind == TokenKind.LITERAL) {
+            switch (type) {
+                case FALSE:
+                case NULL:
+                case TRUE:
+                    return true;
+                default:
+                    return false;
+            }
+        }
+
         // Fake out identifier.
         final long identToken = Token.recast(token, IDENT);
         // Get IDENT.
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java	Wed May 27 17:35:21 2015 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java	Mon Jun 22 13:29:27 2015 -0700
@@ -741,7 +741,7 @@
     }
 
     private static ScriptObject newScope(final ScriptObject callerScope) {
-        return new FunctionScope(PropertyMap.newMap(FunctionScope.class), callerScope);
+        return new Scope(callerScope, PropertyMap.newMap(Scope.class));
     }
 
     private static Source loadInternal(final String srcStr, final String prefix, final String resourcePath) {
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/FunctionScope.java	Wed May 27 17:35:21 2015 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/FunctionScope.java	Mon Jun 22 13:29:27 2015 -0700
@@ -35,17 +35,12 @@
  *
  * The constructor of this class is responsible for any function prologue
  * involving the scope.
- *
- * TODO see NASHORN-715.
  */
-public class FunctionScope extends ScriptObject implements Scope {
+public class FunctionScope extends Scope {
 
     /** Area to store scope arguments. (public for access from scripts.) */
     public final ScriptObject arguments;
 
-    /** Flag to indicate that a split method issued a return statement */
-    private int splitState = -1;
-
     /**
      * Constructor
      *
@@ -56,7 +51,6 @@
     public FunctionScope(final PropertyMap map, final ScriptObject callerScope, final ScriptObject arguments) {
         super(callerScope, map);
         this.arguments = arguments;
-        setIsScope();
     }
 
     /**
@@ -68,7 +62,6 @@
     public FunctionScope(final PropertyMap map, final ScriptObject callerScope) {
         super(callerScope, map);
         this.arguments = null;
-        setIsScope();
     }
 
     /**
@@ -82,23 +75,4 @@
         super(map, primitiveSpill, objectSpill);
         this.arguments = null;
     }
-
-
-    /**
-     * Get the current split state.
-     * @return current split state
-     */
-    @Override
-    public int getSplitState() {
-        return splitState;
-    }
-
-    /**
-     * Set the current split state.
-     * @param state current split state
-     */
-    @Override
-    public void setSplitState(final int state) {
-        splitState = state;
-    }
 }
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java	Wed May 27 17:35:21 2015 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java	Mon Jun 22 13:29:27 2015 -0700
@@ -597,6 +597,15 @@
     }
 
     /**
+     * Return the name of the class of objects using this property map.
+     *
+     * @return class name of owner objects.
+     */
+    public String getClassName() {
+        return className;
+    }
+
+    /**
      * Prevents the map from having additional properties.
      *
      * @return New map with {@link #NOT_EXTENSIBLE} flag set.
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Scope.java	Wed May 27 17:35:21 2015 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Scope.java	Mon Jun 22 13:29:27 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, 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
@@ -25,30 +25,105 @@
 
 package jdk.nashorn.internal.runtime;
 
-import static jdk.nashorn.internal.codegen.CompilerConstants.interfaceCallNoLookup;
+import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
 
 import jdk.nashorn.internal.codegen.CompilerConstants;
 
 /**
- * Interface implemented by {@link ScriptObject}s that act as scope.
+ * A {@link ScriptObject} subclass for objects that act as scope.
  */
-public interface Scope {
+public class Scope extends ScriptObject {
+
+    /* This is used to store return state of split functions. */
+    private int splitState = -1;
+
+    /** This is updated only in debug mode - counts number of {@code ScriptObject} instances created that are scope */
+    private static int count;
 
     /** Method handle that points to {@link Scope#getSplitState}. */
-    public static final CompilerConstants.Call GET_SPLIT_STATE = interfaceCallNoLookup(Scope.class, "getSplitState", int.class);
+    public static final CompilerConstants.Call GET_SPLIT_STATE = virtualCallNoLookup(Scope.class, "getSplitState", int.class);
+    /** Method handle that points to {@link Scope#setSplitState(int)}. */
+    public static final CompilerConstants.Call SET_SPLIT_STATE = virtualCallNoLookup(Scope.class, "setSplitState", void.class, int.class);
+
+    /**
+     * Constructor
+     *
+     * @param map initial property map
+     */
+    public Scope(final PropertyMap map) {
+        super(map);
+        if (Context.DEBUG) {
+            count++;
+        }
+    }
+
+    /**
+     * Constructor
+     *
+     * @param proto parent scope
+     * @param map   initial property map
+     */
+    public Scope(final ScriptObject proto, final PropertyMap map) {
+        super(proto, map);
+        if (Context.DEBUG) {
+            count++;
+        }
+    }
 
-    /** Method handle that points to {@link Scope#setSplitState(int)}. */
-    public static final CompilerConstants.Call SET_SPLIT_STATE = interfaceCallNoLookup(Scope.class, "setSplitState", void.class, int.class);
+    /**
+     * Constructor
+     *
+     * @param map            property map
+     * @param primitiveSpill primitive spill array
+     * @param objectSpill    reference spill array
+     */
+    public Scope(final PropertyMap map, final long[] primitiveSpill, final Object[] objectSpill) {
+        super(map, primitiveSpill, objectSpill);
+        if (Context.DEBUG) {
+            count++;
+        }
+    }
+
+    @Override
+    public boolean isScope() {
+        return true;
+    }
+
+    @Override
+    boolean hasWithScope() {
+        for (ScriptObject obj = this; obj != null; obj = obj.getProto()) {
+            if (obj instanceof WithObject) {
+                return true;
+            }
+        }
+        return false;
+    }
 
     /**
      * Get the scope's split method state.
-     * @return the current state
+     *
+     * @return current split state
      */
-    public int getSplitState();
+    public int getSplitState() {
+        return splitState;
+    }
 
     /**
      * Set the scope's split method state.
-     * @param state the new state.
+     *
+     * @param state current split state
      */
-    public void setSplitState(int state);
+    public void setSplitState(final int state) {
+        splitState = state;
+    }
+
+    /**
+     * Get number of {@code Scope} instances created. If not running in debug
+     * mode this is always 0.
+     *
+     * @return number of scope ScriptObjects created
+     */
+    public static int getScopeCount() {
+        return count;
+    }
 }
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java	Wed May 27 17:35:21 2015 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java	Mon Jun 22 13:29:27 2015 -0700
@@ -109,20 +109,17 @@
     /** Search fall back routine name for "no such property" */
     public static final String NO_SUCH_PROPERTY_NAME = "__noSuchProperty__";
 
-    /** Per ScriptObject flag - is this a scope object? */
-    public static final int IS_SCOPE       = 1 << 0;
-
     /** Per ScriptObject flag - is this an array object? */
-    public static final int IS_ARRAY       = 1 << 1;
+    public static final int IS_ARRAY               = 1 << 0;
 
     /** Per ScriptObject flag - is this an arguments object? */
-    public static final int IS_ARGUMENTS   = 1 << 2;
+    public static final int IS_ARGUMENTS           = 1 << 1;
 
     /** Is length property not-writable? */
-    public static final int IS_LENGTH_NOT_WRITABLE = 1 << 3;
+    public static final int IS_LENGTH_NOT_WRITABLE = 1 << 2;
 
     /** Is this a builtin object? */
-    public static final int IS_BUILTIN = 1 << 4;
+    public static final int IS_BUILTIN             = 1 << 3;
 
     /**
      * Spill growth rate - by how many elements does {@link ScriptObject#primitiveSpill} and
@@ -396,14 +393,6 @@
     }
 
     /**
-     * ECMA 8.10.3 IsGenericDescriptor ( Desc )
-     * @return true if this has a descriptor describing an {@link AccessorPropertyDescriptor} or {@link DataPropertyDescriptor}
-     */
-    public final boolean isGenericDescriptor() {
-        return isAccessorDescriptor() || isDataDescriptor();
-    }
-
-    /**
       * ECMA 8.10.5 ToPropertyDescriptor ( Obj )
       *
       * @return property descriptor
@@ -1630,23 +1619,12 @@
         return getMap().isFrozen();
     }
 
-
-    /**
-     * Flag this ScriptObject as scope
-     */
-    public final void setIsScope() {
-        if (Context.DEBUG) {
-            scopeCount++;
-        }
-        flags |= IS_SCOPE;
-    }
-
     /**
      * Check whether this ScriptObject is scope
      * @return true if scope
      */
-    public final boolean isScope() {
-        return (flags & IS_SCOPE) != 0;
+    public boolean isScope() {
+        return false;
     }
 
     /**
@@ -1921,14 +1899,7 @@
      * 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;
-                }
-            }
-        }
+    boolean hasWithScope() {
         return false;
     }
 
@@ -3817,9 +3788,6 @@
     /** This is updated only in debug mode - counts number of {@code ScriptObject} instances created */
     private static int count;
 
-    /** This is updated only in debug mode - counts number of {@code ScriptObject} instances created that are scope */
-    private static int scopeCount;
-
     /**
      * Get number of {@code ScriptObject} instances created. If not running in debug
      * mode this is always 0
@@ -3829,15 +3797,4 @@
     public static int getCount() {
         return count;
     }
-
-    /**
-     * Get number of scope {@code ScriptObject} instances created. If not running in debug
-     * mode this is always 0
-     *
-     * @return number of scope ScriptObjects created
-     */
-    public static int getScopeCount() {
-        return scopeCount;
-    }
-
 }
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/WithObject.java	Wed May 27 17:35:21 2015 +0200
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/WithObject.java	Mon Jun 22 13:29:27 2015 -0700
@@ -44,7 +44,7 @@
  * This class supports the handling of scope in a with body.
  *
  */
-public final class WithObject extends ScriptObject implements Scope {
+public final class WithObject extends Scope {
     private static final MethodHandle WITHEXPRESSIONGUARD    = findOwnMH("withExpressionGuard",  boolean.class, Object.class, PropertyMap.class, SwitchPoint.class);
     private static final MethodHandle WITHEXPRESSIONFILTER   = findOwnMH("withFilterExpression", Object.class, Object.class);
     private static final MethodHandle WITHSCOPEFILTER        = findOwnMH("withFilterScope",      Object.class, Object.class);
@@ -62,7 +62,6 @@
      */
     WithObject(final ScriptObject scope, final ScriptObject expression) {
         super(scope, null);
-        setIsScope();
         this.expression = expression;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8087312.js	Mon Jun 22 13:29:27 2015 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2015, 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-8087312: PropertyMapWrapper.equals should compare className
+ *
+ * @test
+ * @run
+ * @fork
+ * @option -Dnashorn.debug=true
+ */
+
+function createObject(type) {
+    // we want to make sure two different object literals with the same keys and types share the same property map.
+    if (type) {
+        return {
+            a: "a",
+            b: 1,
+            c: 0.1
+        }
+    } else {
+        return {
+            a: "x",
+            b: 10,
+            c: 3.4
+        }
+    }
+}
+
+var o1 = createObject(false);
+var o2 = createObject(true);
+Assert.assertTrue(Debug.map(o1) === Debug.map(o2));
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/error/JDK-8098847.js	Mon Jun 22 13:29:27 2015 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015, 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-8098847: obj."prop" and obj.'prop' should result in SyntaxError
+ *
+ * @test/compile-error
+ */
+
+var obj = { "prop": 45 };
+
+obj."prop" = "hello";
+obj.'prop' = "hello";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/error/JDK-8098847.js.EXPECTED	Mon Jun 22 13:29:27 2015 -0700
@@ -0,0 +1,6 @@
+test/script/error/JDK-8098847.js:32:5 Expected ident but found prop
+obj."prop" = "hello";
+     ^
+test/script/error/JDK-8098847.js:33:5 Expected ident but found prop
+obj.'prop' = "hello";
+     ^