8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
authorsundar
Mon, 11 Aug 2014 20:35:21 +0530
changeset 26058 17acdbe290b2
parent 26057 1ca8a16f4edc
child 26059 ff5b8d49be95
8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip Reviewed-by: jlaskey, hannesw, attila
nashorn/make/project.properties
nashorn/src/jdk/nashorn/internal/objects/NativeString.java
nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
nashorn/test/script/basic/JDK-8054503.js
--- a/nashorn/make/project.properties	Sat Aug 09 21:27:44 2014 -0700
+++ b/nashorn/make/project.properties	Mon Aug 11 20:35:21 2014 +0530
@@ -201,7 +201,6 @@
 
 # list of test262 test dirs to be excluded
 test262-test-sys-prop.test.js.exclude.dir=\
-    ${test262.suite.dir}/ch12/12.6/12.6.4/12.6.4-2.js \
     ${test262.suite.dir}/intl402/ \
     ${test262.suite.dir}/bestPractice/
 
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java	Sat Aug 09 21:27:44 2014 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java	Mon Aug 11 20:35:21 2014 +0530
@@ -39,6 +39,7 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
+import java.util.Set;
 import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.linker.GuardedInvocation;
 import jdk.internal.dynalink.linker.LinkRequest;
@@ -391,10 +392,12 @@
     /**
      * return a List of own keys associated with the object.
      * @param all True if to include non-enumerable keys.
+     * @param nonEnumerable set of non-enumerable properties seen already.Used
+     * to filter out shadowed, but enumerable properties from proto children.
      * @return Array of keys.
      */
     @Override
-    public String[] getOwnKeys(final boolean all) {
+    protected String[] getOwnKeys(final boolean all, final Set<String> nonEnumerable) {
         final List<Object> keys = new ArrayList<>();
 
         // add string index keys
@@ -403,7 +406,7 @@
         }
 
         // add super class properties
-        keys.addAll(Arrays.asList(super.getOwnKeys(all)));
+        keys.addAll(Arrays.asList(super.getOwnKeys(all, nonEnumerable)));
         return keys.toArray(new String[keys.size()]);
     }
 
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java	Sat Aug 09 21:27:44 2014 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java	Mon Aug 11 20:35:21 2014 +0530
@@ -1324,7 +1324,19 @@
      * @param all True if to include non-enumerable keys.
      * @return Array of keys.
      */
-    public String[] getOwnKeys(final boolean all) {
+    public final String[] getOwnKeys(final boolean all) {
+        return getOwnKeys(all, null);
+    }
+
+    /**
+     * return an array of own property keys associated with the object.
+     *
+     * @param all True if to include non-enumerable keys.
+     * @param nonEnumerable set of non-enumerable properties seen already.Used
+       to filter out shadowed, but enumerable properties from proto children.
+     * @return Array of keys.
+     */
+    protected String[] getOwnKeys(final boolean all, final Set<String> nonEnumerable) {
         final List<Object> keys    = new ArrayList<>();
         final PropertyMap  selfMap = this.getMap();
 
@@ -1338,8 +1350,21 @@
         }
 
         for (final Property property : selfMap.getProperties()) {
-            if (all || property.isEnumerable()) {
-                keys.add(property.getKey());
+            final boolean enumerable = property.isEnumerable();
+            final String key = property.getKey();
+            if (all) {
+                keys.add(key);
+            } else if (enumerable) {
+                // either we don't have non-enumerable filter set or filter set
+                // does not contain the current property.
+                if (nonEnumerable == null || !nonEnumerable.contains(key)) {
+                    keys.add(key);
+                }
+            } else {
+                // store this non-enumerable property for later proto walk
+                if (nonEnumerable != null) {
+                    nonEnumerable.add(key);
+                }
             }
         }
 
@@ -2398,8 +2423,9 @@
         @Override
         protected void init() {
             final Set<String> keys = new LinkedHashSet<>();
+            final Set<String> nonEnumerable = new HashSet<>();
             for (ScriptObject self = object; self != null; self = self.getProto()) {
-                keys.addAll(Arrays.asList(self.getOwnKeys(false)));
+                keys.addAll(Arrays.asList(self.getOwnKeys(false, nonEnumerable)));
             }
             this.values = keys.toArray(new String[keys.size()]);
         }
@@ -2413,8 +2439,9 @@
         @Override
         protected void init() {
             final ArrayList<Object> valueList = new ArrayList<>();
+            final Set<String> nonEnumerable = new HashSet<>();
             for (ScriptObject self = object; self != null; self = self.getProto()) {
-                for (final String key : self.getOwnKeys(false)) {
+                for (final String key : self.getOwnKeys(false, nonEnumerable)) {
                     valueList.add(self.get(key));
                 }
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8054503.js	Mon Aug 11 20:35:21 2014 +0530
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+/**
+ * 8054503: test/script/external/test262/test/suite/ch12/12.6/12.6.4/12.6.4-2.js fails with tip
+ *
+ * @test
+ * @run
+ */
+
+function MyFunc() {}
+
+MyFunc.prototype.foo = 42;
+var obj = new MyFunc();
+Object.defineProperty(obj, "foo", {
+    value: "hello",
+    enumerable: false
+});
+
+for (var p in obj) {
+    if (p == "foo") {
+        fail("'foo' is not expected here!");
+    }
+}
+
+for each (var p in obj) {
+    if (p == "hello" || p == 42) {
+        fail("'foo' value is not expected here");
+    }
+}