Tue, 04 Jun 2013 22:31:48 +0530
8015830: Javascript mapping of ScriptEngine bindings does not expose keys
Reviewed-by: jlaskey, lagergren
1.1 --- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Tue Jun 04 17:33:14 2013 +0530 1.2 +++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Tue Jun 04 22:31:48 2013 +0530 1.3 @@ -31,7 +31,7 @@ 1.4 import java.util.ArrayList; 1.5 import java.util.Collection; 1.6 import java.util.Collections; 1.7 -import java.util.HashSet; 1.8 +import java.util.LinkedHashSet; 1.9 import java.util.Iterator; 1.10 import java.util.List; 1.11 import java.util.Map; 1.12 @@ -48,7 +48,7 @@ 1.13 * access ScriptObject via the javax.script.Bindings interface or 1.14 * netscape.javascript.JSObject interface. 1.15 */ 1.16 -final class ScriptObjectMirror extends JSObject implements Bindings { 1.17 +public final class ScriptObjectMirror extends JSObject implements Bindings { 1.18 private final ScriptObject sobj; 1.19 private final ScriptObject global; 1.20 1.21 @@ -217,7 +217,7 @@ 1.22 return inGlobal(new Callable<Set<Map.Entry<String, Object>>>() { 1.23 @Override public Set<Map.Entry<String, Object>> call() { 1.24 final Iterator<String> iter = sobj.propertyIterator(); 1.25 - final Set<Map.Entry<String, Object>> entries = new HashSet<>(); 1.26 + final Set<Map.Entry<String, Object>> entries = new LinkedHashSet<>(); 1.27 1.28 while (iter.hasNext()) { 1.29 final String key = iter.next(); 1.30 @@ -253,7 +253,7 @@ 1.31 return inGlobal(new Callable<Set<String>>() { 1.32 @Override public Set<String> call() { 1.33 final Iterator<String> iter = sobj.propertyIterator(); 1.34 - final Set<String> keySet = new HashSet<>(); 1.35 + final Set<String> keySet = new LinkedHashSet<>(); 1.36 1.37 while (iter.hasNext()) { 1.38 keySet.add(iter.next()); 1.39 @@ -302,6 +302,21 @@ 1.40 }); 1.41 } 1.42 1.43 + /** 1.44 + * Delete a property from this object. 1.45 + * 1.46 + * @param key the property to be deleted 1.47 + * 1.48 + * @return if the delete was successful or not 1.49 + */ 1.50 + public boolean delete(final Object key) { 1.51 + return inGlobal(new Callable<Boolean>() { 1.52 + @Override public Boolean call() { 1.53 + return sobj.delete(unwrap(key, global)); 1.54 + } 1.55 + }); 1.56 + } 1.57 + 1.58 @Override 1.59 public int size() { 1.60 return inGlobal(new Callable<Integer>() {
2.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Tue Jun 04 17:33:14 2013 +0530 2.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Tue Jun 04 22:31:48 2013 +0530 2.3 @@ -1512,6 +1512,17 @@ 2.4 } 2.5 2.6 /** 2.7 + * Delete a property from the ScriptObject. 2.8 + * (to help ScriptObjectMirror implementation) 2.9 + * 2.10 + * @param key the key of the property 2.11 + * @return if the delete was successful or not 2.12 + */ 2.13 + public boolean delete(final Object key) { 2.14 + return delete(key, getContext()._strict); 2.15 + } 2.16 + 2.17 + /** 2.18 * Return the size of the ScriptObject - i.e. the number of properties 2.19 * it contains 2.20 * (java.util.Map-like method to help ScriptObjectMirror implementation)
3.1 --- a/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Tue Jun 04 17:33:14 2013 +0530 3.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Tue Jun 04 22:31:48 2013 +0530 3.3 @@ -40,6 +40,7 @@ 3.4 import java.util.NoSuchElementException; 3.5 import java.util.Objects; 3.6 import jdk.internal.dynalink.beans.StaticClass; 3.7 +import jdk.nashorn.api.scripting.ScriptObjectMirror; 3.8 import jdk.nashorn.internal.codegen.CompilerConstants.Call; 3.9 import jdk.nashorn.internal.ir.debug.JSONWriter; 3.10 import jdk.nashorn.internal.parser.Lexer; 3.11 @@ -240,6 +241,10 @@ 3.12 }; 3.13 } 3.14 3.15 + if (obj instanceof ScriptObjectMirror) { 3.16 + return ((ScriptObjectMirror)obj).keySet().iterator(); 3.17 + } 3.18 + 3.19 return Collections.emptyIterator(); 3.20 } 3.21 3.22 @@ -280,6 +285,10 @@ 3.23 }; 3.24 } 3.25 3.26 + if (obj instanceof ScriptObjectMirror) { 3.27 + return ((ScriptObjectMirror)obj).values().iterator(); 3.28 + } 3.29 + 3.30 if (obj instanceof Iterable) { 3.31 return ((Iterable<?>)obj).iterator(); 3.32 } 3.33 @@ -591,6 +600,10 @@ 3.34 throw typeError("cant.delete.property", safeToString(property), "null"); 3.35 } 3.36 3.37 + if (obj instanceof ScriptObjectMirror) { 3.38 + return ((ScriptObjectMirror)obj).delete(property); 3.39 + } 3.40 + 3.41 if (JSType.isPrimitive(obj)) { 3.42 return ((ScriptObject) JSType.toScriptObject(obj)).delete(property, Boolean.TRUE.equals(strict)); 3.43 }
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/script/basic/JDK-8015830.js Tue Jun 04 22:31:48 2013 +0530 4.3 @@ -0,0 +1,56 @@ 4.4 +/* 4.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. 4.11 + * 4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.15 + * version 2 for more details (a copy is included in the LICENSE file that 4.16 + * accompanied this code). 4.17 + * 4.18 + * You should have received a copy of the GNU General Public License version 4.19 + * 2 along with this work; if not, write to the Free Software Foundation, 4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.21 + * 4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.23 + * or visit www.oracle.com if you need additional information or have any 4.24 + * questions. 4.25 + */ 4.26 + 4.27 +/** 4.28 + * JDK-8015830: Javascript mapping of ScriptEngine bindings does not expose keys 4.29 + * 4.30 + * @test 4.31 + * @run 4.32 + */ 4.33 + 4.34 +var m = new javax.script.ScriptEngineManager(); 4.35 +var engine = m.getEngineByName("nashorn"); 4.36 + 4.37 +engine.eval("x = 100; doit = function () { }"); 4.38 + 4.39 +var global = engine.getBindings(javax.script.ScriptContext.ENGINE_SCOPE); 4.40 + 4.41 +for(k in global){ 4.42 + print(k + " = " + global[k]); 4.43 +} 4.44 + 4.45 +for each (k in global) { 4.46 + print(k); 4.47 +} 4.48 + 4.49 +for(k in global) { 4.50 + delete global[k]; 4.51 +} 4.52 + 4.53 +for(k in global){ 4.54 + print(k + " = " + global[k]); 4.55 +} 4.56 + 4.57 +for each(k in global) { 4.58 + print(k); 4.59 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/script/basic/JDK-8015830.js.EXPECTED Tue Jun 04 22:31:48 2013 +0530 5.3 @@ -0,0 +1,4 @@ 5.4 +x = 100 5.5 +doit = function () { } 5.6 +100 5.7 +function () { }