Fri, 14 Jun 2013 21:16:14 +0530
8016618: script mirror object access should be improved
Reviewed-by: jlaskey, lagergren
1.1 --- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Fri Jun 14 13:53:40 2013 +0200 1.2 +++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Fri Jun 14 21:16:14 2013 +0530 1.3 @@ -342,6 +342,184 @@ 1.4 }); 1.5 } 1.6 1.7 + // Support for ECMAScript Object API on mirrors 1.8 + 1.9 + /** 1.10 + * Return the __proto__ of this object. 1.11 + * @return __proto__ object. 1.12 + */ 1.13 + public Object getProto() { 1.14 + return inGlobal(new Callable<Object>() { 1.15 + @Override public Object call() { 1.16 + return wrap(getScriptObject().getProto(), global); 1.17 + } 1.18 + }); 1.19 + } 1.20 + 1.21 + /** 1.22 + * ECMA 8.12.1 [[GetOwnProperty]] (P) 1.23 + * 1.24 + * @param key property key 1.25 + * 1.26 + * @return Returns the Property Descriptor of the named own property of this 1.27 + * object, or undefined if absent. 1.28 + */ 1.29 + public Object getOwnPropertyDescriptor(final String key) { 1.30 + return inGlobal(new Callable<Object>() { 1.31 + @Override public Object call() { 1.32 + return wrap(getScriptObject().getOwnPropertyDescriptor(key), global); 1.33 + } 1.34 + }); 1.35 + } 1.36 + 1.37 + /** 1.38 + * return an array of own property keys associated with the object. 1.39 + * 1.40 + * @param all True if to include non-enumerable keys. 1.41 + * @return Array of keys. 1.42 + */ 1.43 + public String[] getOwnKeys(final boolean all) { 1.44 + return inGlobal(new Callable<String[]>() { 1.45 + @Override public String[] call() { 1.46 + return getScriptObject().getOwnKeys(all); 1.47 + } 1.48 + }); 1.49 + } 1.50 + 1.51 + /** 1.52 + * Flag this script object as non extensible 1.53 + * 1.54 + * @return the object after being made non extensible 1.55 + */ 1.56 + public ScriptObjectMirror preventExtensions() { 1.57 + return inGlobal(new Callable<ScriptObjectMirror>() { 1.58 + @Override public ScriptObjectMirror call() { 1.59 + getScriptObject().preventExtensions(); 1.60 + return ScriptObjectMirror.this; 1.61 + } 1.62 + }); 1.63 + } 1.64 + 1.65 + /** 1.66 + * Check if this script object is extensible 1.67 + * @return true if extensible 1.68 + */ 1.69 + public boolean isExtensible() { 1.70 + return inGlobal(new Callable<Boolean>() { 1.71 + @Override public Boolean call() { 1.72 + return getScriptObject().isExtensible(); 1.73 + } 1.74 + }); 1.75 + } 1.76 + 1.77 + /** 1.78 + * ECMAScript 15.2.3.8 - seal implementation 1.79 + * @return the sealed script object 1.80 + */ 1.81 + public ScriptObjectMirror seal() { 1.82 + return inGlobal(new Callable<ScriptObjectMirror>() { 1.83 + @Override public ScriptObjectMirror call() { 1.84 + getScriptObject().seal(); 1.85 + return ScriptObjectMirror.this; 1.86 + } 1.87 + }); 1.88 + } 1.89 + 1.90 + /** 1.91 + * Check whether this script object is sealed 1.92 + * @return true if sealed 1.93 + */ 1.94 + public boolean isSealed() { 1.95 + return inGlobal(new Callable<Boolean>() { 1.96 + @Override public Boolean call() { 1.97 + return getScriptObject().isSealed(); 1.98 + } 1.99 + }); 1.100 + } 1.101 + 1.102 + /** 1.103 + * ECMA 15.2.39 - freeze implementation. Freeze this script object 1.104 + * @return the frozen script object 1.105 + */ 1.106 + public ScriptObjectMirror freeze() { 1.107 + return inGlobal(new Callable<ScriptObjectMirror>() { 1.108 + @Override public ScriptObjectMirror call() { 1.109 + getScriptObject().freeze(); 1.110 + return ScriptObjectMirror.this; 1.111 + } 1.112 + }); 1.113 + } 1.114 + 1.115 + /** 1.116 + * Check whether this script object is frozen 1.117 + * @return true if frozen 1.118 + */ 1.119 + public boolean isFrozen() { 1.120 + return inGlobal(new Callable<Boolean>() { 1.121 + @Override public Boolean call() { 1.122 + return getScriptObject().isFrozen(); 1.123 + } 1.124 + }); 1.125 + } 1.126 + 1.127 + // ECMAScript instanceof check 1.128 + 1.129 + /** 1.130 + * Checking whether a script object is an instance of another by 1.131 + * walking the proto chain 1.132 + * 1.133 + * @param instance instace to check 1.134 + * @return true if 'instance' is an instance of this object 1.135 + */ 1.136 + public boolean isInstance(final ScriptObjectMirror instance) { 1.137 + // if not belongs to my global scope, return false 1.138 + if (instance == null || global != instance.global) { 1.139 + return false; 1.140 + } 1.141 + 1.142 + return inGlobal(new Callable<Boolean>() { 1.143 + @Override public Boolean call() { 1.144 + return getScriptObject().isInstance(instance.getScriptObject()); 1.145 + } 1.146 + }); 1.147 + } 1.148 + 1.149 + /** 1.150 + * Utility to check if given object is ECMAScript undefined value 1.151 + * 1.152 + * @param obj object to check 1.153 + * @return true if 'obj' is ECMAScript undefined value 1.154 + */ 1.155 + public static boolean isUndefined(final Object obj) { 1.156 + return obj == ScriptRuntime.UNDEFINED; 1.157 + } 1.158 + 1.159 + /** 1.160 + * is this a function object? 1.161 + * 1.162 + * @return if this mirror wraps a ECMAScript function instance 1.163 + */ 1.164 + public boolean isFunction() { 1.165 + return getScriptObject() instanceof ScriptFunction; 1.166 + } 1.167 + 1.168 + /** 1.169 + * is this a 'use strict' function object? 1.170 + * 1.171 + * @return true if this mirror represents a ECMAScript 'use strict' function 1.172 + */ 1.173 + public boolean isStrictFunction() { 1.174 + return isFunction() && ((ScriptFunction)getScriptObject()).isStrict(); 1.175 + } 1.176 + 1.177 + /** 1.178 + * is this an array object? 1.179 + * 1.180 + * @return if this mirror wraps a ECMAScript array object 1.181 + */ 1.182 + public boolean isArray() { 1.183 + return getScriptObject().isArray(); 1.184 + } 1.185 1.186 // These are public only so that Context can access these. 1.187
2.1 --- a/src/jdk/nashorn/internal/ir/BreakableNode.java Fri Jun 14 13:53:40 2013 +0200 2.2 +++ b/src/jdk/nashorn/internal/ir/BreakableNode.java Fri Jun 14 21:16:14 2013 +0530 2.3 @@ -86,7 +86,7 @@ 2.4 2.5 /** 2.6 * Return the labels associated with this node. Breakable nodes that 2.7 - * aren't LoopNodes only have a break label -> the location immediately 2.8 + * aren't LoopNodes only have a break label - the location immediately 2.9 * afterwards the node in code 2.10 * @return list of labels representing locations around this node 2.11 */
3.1 --- a/src/jdk/nashorn/internal/objects/NativeArray.java Fri Jun 14 13:53:40 2013 +0200 3.2 +++ b/src/jdk/nashorn/internal/objects/NativeArray.java Fri Jun 14 21:16:14 2013 +0530 3.3 @@ -39,6 +39,7 @@ 3.4 import java.util.Comparator; 3.5 import java.util.Iterator; 3.6 import java.util.List; 3.7 +import jdk.nashorn.api.scripting.ScriptObjectMirror; 3.8 import jdk.nashorn.internal.objects.annotations.Attribute; 3.9 import jdk.nashorn.internal.objects.annotations.Constructor; 3.10 import jdk.nashorn.internal.objects.annotations.Function; 3.11 @@ -291,7 +292,8 @@ 3.12 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 3.13 public static Object isArray(final Object self, final Object arg) { 3.14 return isArray(arg) || (arg == Global.instance().getArrayPrototype()) 3.15 - || (arg instanceof NativeRegExpExecResult); 3.16 + || (arg instanceof NativeRegExpExecResult) 3.17 + || (arg instanceof ScriptObjectMirror && ((ScriptObjectMirror)arg).isArray()); 3.18 } 3.19 3.20 /**
4.1 --- a/src/jdk/nashorn/internal/objects/NativeFunction.java Fri Jun 14 13:53:40 2013 +0200 4.2 +++ b/src/jdk/nashorn/internal/objects/NativeFunction.java Fri Jun 14 21:16:14 2013 +0530 4.3 @@ -29,6 +29,7 @@ 4.4 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; 4.5 4.6 import java.util.List; 4.7 +import jdk.nashorn.api.scripting.ScriptObjectMirror; 4.8 import jdk.nashorn.internal.objects.annotations.Attribute; 4.9 import jdk.nashorn.internal.objects.annotations.Constructor; 4.10 import jdk.nashorn.internal.objects.annotations.Function; 4.11 @@ -102,6 +103,16 @@ 4.12 list.toArray(args = new Object[list.size()]); 4.13 } else if (array == null || array == UNDEFINED) { 4.14 args = ScriptRuntime.EMPTY_ARRAY; 4.15 + } else if (array instanceof ScriptObjectMirror) { 4.16 + // look for array-like ScriptObjectMirror object 4.17 + final ScriptObjectMirror mirror = (ScriptObjectMirror)array; 4.18 + final Object len = mirror.containsKey("length")? mirror.getMember("length") : Integer.valueOf(0); 4.19 + final int n = (int)JSType.toUint32(len); 4.20 + 4.21 + args = new Object[n]; 4.22 + for (int i = 0; i < args.length; i++) { 4.23 + args[i] = mirror.containsKey(i)? mirror.getSlot(i) : UNDEFINED; 4.24 + } 4.25 } else { 4.26 throw typeError("function.apply.expects.array"); 4.27 }
5.1 --- a/src/jdk/nashorn/internal/objects/NativeObject.java Fri Jun 14 13:53:40 2013 +0200 5.2 +++ b/src/jdk/nashorn/internal/objects/NativeObject.java Fri Jun 14 21:16:14 2013 +0530 5.3 @@ -28,11 +28,13 @@ 5.4 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; 5.5 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; 5.6 5.7 +import jdk.nashorn.api.scripting.ScriptObjectMirror; 5.8 import jdk.nashorn.internal.objects.annotations.Attribute; 5.9 import jdk.nashorn.internal.objects.annotations.Constructor; 5.10 import jdk.nashorn.internal.objects.annotations.Function; 5.11 import jdk.nashorn.internal.objects.annotations.ScriptClass; 5.12 import jdk.nashorn.internal.objects.annotations.Where; 5.13 +import jdk.nashorn.internal.runtime.ECMAException; 5.14 import jdk.nashorn.internal.runtime.JSType; 5.15 import jdk.nashorn.internal.runtime.ScriptFunction; 5.16 import jdk.nashorn.internal.runtime.ScriptObject; 5.17 @@ -54,6 +56,10 @@ 5.18 private NativeObject() { 5.19 } 5.20 5.21 + private static ECMAException notAnObject(final Object obj) { 5.22 + return typeError("not.an.object", ScriptRuntime.safeToString(obj)); 5.23 + } 5.24 + 5.25 /** 5.26 * ECMA 15.2.3.2 Object.getPrototypeOf ( O ) 5.27 * 5.28 @@ -63,9 +69,13 @@ 5.29 */ 5.30 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 5.31 public static Object getPrototypeOf(final Object self, final Object obj) { 5.32 - Global.checkObject(obj); 5.33 - 5.34 - return ((ScriptObject)obj).getProto(); 5.35 + if (obj instanceof ScriptObject) { 5.36 + return ((ScriptObject)obj).getProto(); 5.37 + } else if (obj instanceof ScriptObjectMirror) { 5.38 + return ((ScriptObjectMirror)obj).getProto(); 5.39 + } else { 5.40 + throw notAnObject(obj); 5.41 + } 5.42 } 5.43 5.44 /** 5.45 @@ -78,12 +88,19 @@ 5.46 */ 5.47 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 5.48 public static Object getOwnPropertyDescriptor(final Object self, final Object obj, final Object prop) { 5.49 - Global.checkObject(obj); 5.50 + if (obj instanceof ScriptObject) { 5.51 + final String key = JSType.toString(prop); 5.52 + final ScriptObject sobj = (ScriptObject)obj; 5.53 5.54 - final String key = JSType.toString(prop); 5.55 - final ScriptObject sobj = (ScriptObject)obj; 5.56 + return sobj.getOwnPropertyDescriptor(key); 5.57 + } else if (obj instanceof ScriptObjectMirror) { 5.58 + final String key = JSType.toString(prop); 5.59 + final ScriptObjectMirror sobjMirror = (ScriptObjectMirror)obj; 5.60 5.61 - return sobj.getOwnPropertyDescriptor(key); 5.62 + return sobjMirror.getOwnPropertyDescriptor(key); 5.63 + } else { 5.64 + throw notAnObject(obj); 5.65 + } 5.66 } 5.67 5.68 /** 5.69 @@ -95,9 +112,13 @@ 5.70 */ 5.71 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 5.72 public static Object getOwnPropertyNames(final Object self, final Object obj) { 5.73 - Global.checkObject(obj); 5.74 - 5.75 - return new NativeArray(((ScriptObject)obj).getOwnKeys(true)); 5.76 + if (obj instanceof ScriptObject) { 5.77 + return new NativeArray(((ScriptObject)obj).getOwnKeys(true)); 5.78 + } else if (obj instanceof ScriptObjectMirror) { 5.79 + return new NativeArray(((ScriptObjectMirror)obj).getOwnKeys(true)); 5.80 + } else { 5.81 + throw notAnObject(obj); 5.82 + } 5.83 } 5.84 5.85 /** 5.86 @@ -175,8 +196,13 @@ 5.87 */ 5.88 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 5.89 public static Object seal(final Object self, final Object obj) { 5.90 - Global.checkObject(obj); 5.91 - return ((ScriptObject)obj).seal(); 5.92 + if (obj instanceof ScriptObject) { 5.93 + return ((ScriptObject)obj).seal(); 5.94 + } else if (obj instanceof ScriptObjectMirror) { 5.95 + return ((ScriptObjectMirror)obj).seal(); 5.96 + } else { 5.97 + throw notAnObject(obj); 5.98 + } 5.99 } 5.100 5.101 5.102 @@ -189,8 +215,13 @@ 5.103 */ 5.104 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 5.105 public static Object freeze(final Object self, final Object obj) { 5.106 - Global.checkObject(obj); 5.107 - return ((ScriptObject)obj).freeze(); 5.108 + if (obj instanceof ScriptObject) { 5.109 + return ((ScriptObject)obj).freeze(); 5.110 + } else if (obj instanceof ScriptObjectMirror) { 5.111 + return ((ScriptObjectMirror)obj).freeze(); 5.112 + } else { 5.113 + throw notAnObject(obj); 5.114 + } 5.115 } 5.116 5.117 /** 5.118 @@ -202,8 +233,13 @@ 5.119 */ 5.120 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 5.121 public static Object preventExtensions(final Object self, final Object obj) { 5.122 - Global.checkObject(obj); 5.123 - return ((ScriptObject)obj).preventExtensions(); 5.124 + if (obj instanceof ScriptObject) { 5.125 + return ((ScriptObject)obj).preventExtensions(); 5.126 + } else if (obj instanceof ScriptObjectMirror) { 5.127 + return ((ScriptObjectMirror)obj).preventExtensions(); 5.128 + } else { 5.129 + throw notAnObject(obj); 5.130 + } 5.131 } 5.132 5.133 /** 5.134 @@ -215,8 +251,13 @@ 5.135 */ 5.136 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 5.137 public static Object isSealed(final Object self, final Object obj) { 5.138 - Global.checkObject(obj); 5.139 - return ((ScriptObject)obj).isSealed(); 5.140 + if (obj instanceof ScriptObject) { 5.141 + return ((ScriptObject)obj).isSealed(); 5.142 + } else if (obj instanceof ScriptObjectMirror) { 5.143 + return ((ScriptObjectMirror)obj).isSealed(); 5.144 + } else { 5.145 + throw notAnObject(obj); 5.146 + } 5.147 } 5.148 5.149 /** 5.150 @@ -228,8 +269,13 @@ 5.151 */ 5.152 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 5.153 public static Object isFrozen(final Object self, final Object obj) { 5.154 - Global.checkObject(obj); 5.155 - return ((ScriptObject)obj).isFrozen(); 5.156 + if (obj instanceof ScriptObject) { 5.157 + return ((ScriptObject)obj).isFrozen(); 5.158 + } else if (obj instanceof ScriptObjectMirror) { 5.159 + return ((ScriptObjectMirror)obj).isFrozen(); 5.160 + } else { 5.161 + throw notAnObject(obj); 5.162 + } 5.163 } 5.164 5.165 /** 5.166 @@ -241,8 +287,13 @@ 5.167 */ 5.168 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 5.169 public static Object isExtensible(final Object self, final Object obj) { 5.170 - Global.checkObject(obj); 5.171 - return ((ScriptObject)obj).isExtensible(); 5.172 + if (obj instanceof ScriptObject) { 5.173 + return ((ScriptObject)obj).isExtensible(); 5.174 + } else if (obj instanceof ScriptObjectMirror) { 5.175 + return ((ScriptObjectMirror)obj).isExtensible(); 5.176 + } else { 5.177 + throw notAnObject(obj); 5.178 + } 5.179 } 5.180 5.181 /** 5.182 @@ -254,9 +305,15 @@ 5.183 */ 5.184 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 5.185 public static Object keys(final Object self, final Object obj) { 5.186 - Global.checkObject(obj); 5.187 - final ScriptObject sobj = (ScriptObject)obj; 5.188 - return new NativeArray(sobj.getOwnKeys(false)); 5.189 + if (obj instanceof ScriptObject) { 5.190 + final ScriptObject sobj = (ScriptObject)obj; 5.191 + return new NativeArray(sobj.getOwnKeys(false)); 5.192 + } else if (obj instanceof ScriptObjectMirror) { 5.193 + final ScriptObjectMirror sobjMirror = (ScriptObjectMirror)obj; 5.194 + return new NativeArray(sobjMirror.getOwnKeys(false)); 5.195 + } else { 5.196 + throw notAnObject(obj); 5.197 + } 5.198 } 5.199 5.200 /**
6.1 --- a/src/jdk/nashorn/internal/runtime/Context.java Fri Jun 14 13:53:40 2013 +0200 6.2 +++ b/src/jdk/nashorn/internal/runtime/Context.java Fri Jun 14 21:16:14 2013 +0530 6.3 @@ -46,6 +46,7 @@ 6.4 import java.security.Permissions; 6.5 import java.security.PrivilegedAction; 6.6 import java.security.ProtectionDomain; 6.7 +import java.util.Map; 6.8 import jdk.internal.org.objectweb.asm.ClassReader; 6.9 import jdk.internal.org.objectweb.asm.util.CheckClassAdapter; 6.10 import jdk.nashorn.api.scripting.ScriptObjectMirror; 6.11 @@ -482,6 +483,13 @@ 6.12 final String name = JSType.toString(sobj.get("name")); 6.13 source = new Source(name, script); 6.14 } 6.15 + } else if (src instanceof Map) { 6.16 + final Map map = (Map)src; 6.17 + if (map.containsKey("script") && map.containsKey("name")) { 6.18 + final String script = JSType.toString(map.get("script")); 6.19 + final String name = JSType.toString(map.get("name")); 6.20 + source = new Source(name, script); 6.21 + } 6.22 } 6.23 6.24 if (source != null) {
7.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Jun 14 13:53:40 2013 +0200 7.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Jun 14 21:16:14 2013 +0530 7.3 @@ -1108,7 +1108,8 @@ 7.4 } 7.5 7.6 /** 7.7 - * return a List of own keys associated with the object. 7.8 + * return an array of own property keys associated with the object. 7.9 + * 7.10 * @param all True if to include non-enumerable keys. 7.11 * @return Array of keys. 7.12 */ 7.13 @@ -1209,7 +1210,7 @@ 7.14 * the proto chain 7.15 * 7.16 * @param instance instace to check 7.17 - * @return true if instance of instance 7.18 + * @return true if 'instance' is an instance of this object 7.19 */ 7.20 public boolean isInstance(final ScriptObject instance) { 7.21 return false; 7.22 @@ -1382,7 +1383,7 @@ 7.23 7.24 /** 7.25 * Check whether this ScriptObject is frozen 7.26 - * @return true if frozed 7.27 + * @return true if frozen 7.28 */ 7.29 public boolean isFrozen() { 7.30 return getMap().isFrozen();
8.1 --- a/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Fri Jun 14 13:53:40 2013 +0200 8.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Fri Jun 14 21:16:14 2013 +0530 8.3 @@ -825,6 +825,13 @@ 8.4 return ((StaticClass)clazz).getRepresentedClass().isInstance(obj); 8.5 } 8.6 8.7 + if (clazz instanceof ScriptObjectMirror) { 8.8 + if (obj instanceof ScriptObjectMirror) { 8.9 + return ((ScriptObjectMirror)clazz).isInstance((ScriptObjectMirror)obj); 8.10 + } 8.11 + return false; 8.12 + } 8.13 + 8.14 throw typeError("instanceof.on.non.object"); 8.15 } 8.16
9.1 --- a/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java Fri Jun 14 13:53:40 2013 +0200 9.2 +++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java Fri Jun 14 21:16:14 2013 +0530 9.3 @@ -26,6 +26,7 @@ 9.4 package jdk.nashorn.internal.runtime.arrays; 9.5 9.6 import java.util.Iterator; 9.7 +import jdk.nashorn.api.scripting.ScriptObjectMirror; 9.8 import jdk.nashorn.internal.runtime.JSType; 9.9 import jdk.nashorn.internal.runtime.ScriptObject; 9.10 9.11 @@ -125,6 +126,10 @@ 9.12 return new MapIterator((ScriptObject)obj, includeUndefined); 9.13 } 9.14 9.15 + if (obj instanceof ScriptObjectMirror) { 9.16 + return new ScriptObjectMirrorIterator((ScriptObjectMirror)obj, includeUndefined); 9.17 + } 9.18 + 9.19 return new EmptyArrayLikeIterator(); 9.20 } 9.21 9.22 @@ -146,6 +151,10 @@ 9.23 return new ReverseMapIterator((ScriptObject)obj, includeUndefined); 9.24 } 9.25 9.26 + if (obj instanceof ScriptObjectMirror) { 9.27 + return new ReverseScriptObjectMirrorIterator((ScriptObjectMirror)obj, includeUndefined); 9.28 + } 9.29 + 9.30 assert !obj.getClass().isArray(); 9.31 9.32 return new EmptyArrayLikeIterator();
10.1 --- a/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java Fri Jun 14 13:53:40 2013 +0200 10.2 +++ b/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java Fri Jun 14 21:16:14 2013 +0530 10.3 @@ -27,6 +27,7 @@ 10.4 10.5 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; 10.6 10.7 +import jdk.nashorn.api.scripting.ScriptObjectMirror; 10.8 import jdk.nashorn.internal.runtime.Context; 10.9 import jdk.nashorn.internal.runtime.ScriptFunction; 10.10 import jdk.nashorn.internal.runtime.ScriptRuntime; 10.11 @@ -96,12 +97,18 @@ 10.12 * @return result of apply 10.13 */ 10.14 public final T apply() { 10.15 - if (!(callbackfn instanceof ScriptFunction)) { 10.16 + final boolean strict; 10.17 + if (callbackfn instanceof ScriptFunction) { 10.18 + strict = ((ScriptFunction)callbackfn).isStrict(); 10.19 + } else if (callbackfn instanceof ScriptObjectMirror && 10.20 + ((ScriptObjectMirror)callbackfn).isFunction()) { 10.21 + strict = ((ScriptObjectMirror)callbackfn).isStrictFunction(); 10.22 + } else { 10.23 throw typeError("not.a.function", ScriptRuntime.safeToString(callbackfn)); 10.24 } 10.25 - final ScriptFunction func = ((ScriptFunction)callbackfn); 10.26 + 10.27 // for non-strict callback, need to translate undefined thisArg to be global object 10.28 - thisArg = (thisArg == ScriptRuntime.UNDEFINED && !func.isStrict()) ? Context.getGlobal() : thisArg; 10.29 + thisArg = (thisArg == ScriptRuntime.UNDEFINED && !strict)? Context.getGlobal() : thisArg; 10.30 10.31 applyLoopBegin(iter); 10.32 final boolean reverse = iter.isReverse();
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/src/jdk/nashorn/internal/runtime/arrays/ReverseScriptObjectMirrorIterator.java Fri Jun 14 21:16:14 2013 +0530 11.3 @@ -0,0 +1,56 @@ 11.4 +/* 11.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.7 + * 11.8 + * This code is free software; you can redistribute it and/or modify it 11.9 + * under the terms of the GNU General Public License version 2 only, as 11.10 + * published by the Free Software Foundation. Oracle designates this 11.11 + * particular file as subject to the "Classpath" exception as provided 11.12 + * by Oracle in the LICENSE file that accompanied this code. 11.13 + * 11.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 11.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11.17 + * version 2 for more details (a copy is included in the LICENSE file that 11.18 + * accompanied this code). 11.19 + * 11.20 + * You should have received a copy of the GNU General Public License version 11.21 + * 2 along with this work; if not, write to the Free Software Foundation, 11.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 11.23 + * 11.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 11.25 + * or visit www.oracle.com if you need additional information or have any 11.26 + * questions. 11.27 + */ 11.28 + 11.29 +package jdk.nashorn.internal.runtime.arrays; 11.30 + 11.31 +import jdk.nashorn.api.scripting.ScriptObjectMirror; 11.32 +import jdk.nashorn.internal.runtime.JSType; 11.33 + 11.34 +/** 11.35 + * Reverse iterator over a ScriptObjectMirror 11.36 + */ 11.37 +final class ReverseScriptObjectMirrorIterator extends ScriptObjectMirrorIterator { 11.38 + 11.39 + ReverseScriptObjectMirrorIterator(final ScriptObjectMirror obj, final boolean includeUndefined) { 11.40 + super(obj, includeUndefined); 11.41 + this.index = JSType.toUint32(obj.containsKey("length")? obj.getMember("length") : 0) - 1; 11.42 + } 11.43 + 11.44 + @Override 11.45 + public boolean isReverse() { 11.46 + return true; 11.47 + } 11.48 + 11.49 + @Override 11.50 + protected boolean indexInArray() { 11.51 + return index >= 0; 11.52 + } 11.53 + 11.54 + @Override 11.55 + protected long bumpIndex() { 11.56 + return index--; 11.57 + } 11.58 +} 11.59 +
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/src/jdk/nashorn/internal/runtime/arrays/ScriptObjectMirrorIterator.java Fri Jun 14 21:16:14 2013 +0530 12.3 @@ -0,0 +1,81 @@ 12.4 +/* 12.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 12.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.7 + * 12.8 + * This code is free software; you can redistribute it and/or modify it 12.9 + * under the terms of the GNU General Public License version 2 only, as 12.10 + * published by the Free Software Foundation. Oracle designates this 12.11 + * particular file as subject to the "Classpath" exception as provided 12.12 + * by Oracle in the LICENSE file that accompanied this code. 12.13 + * 12.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 12.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12.17 + * version 2 for more details (a copy is included in the LICENSE file that 12.18 + * accompanied this code). 12.19 + * 12.20 + * You should have received a copy of the GNU General Public License version 12.21 + * 2 along with this work; if not, write to the Free Software Foundation, 12.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 12.23 + * 12.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 12.25 + * or visit www.oracle.com if you need additional information or have any 12.26 + * questions. 12.27 + */ 12.28 + 12.29 +package jdk.nashorn.internal.runtime.arrays; 12.30 + 12.31 +import java.util.NoSuchElementException; 12.32 +import jdk.nashorn.api.scripting.ScriptObjectMirror; 12.33 +import jdk.nashorn.internal.runtime.JSType; 12.34 + 12.35 +/** 12.36 + * Iterator over a ScriptObjectMirror 12.37 + */ 12.38 +class ScriptObjectMirrorIterator extends ArrayLikeIterator<Object> { 12.39 + 12.40 + protected final ScriptObjectMirror obj; 12.41 + private final long length; 12.42 + 12.43 + ScriptObjectMirrorIterator(final ScriptObjectMirror obj, final boolean includeUndefined) { 12.44 + super(includeUndefined); 12.45 + this.obj = obj; 12.46 + this.length = JSType.toUint32(obj.containsKey("length")? obj.getMember("length") : 0); 12.47 + this.index = 0; 12.48 + } 12.49 + 12.50 + protected boolean indexInArray() { 12.51 + return index < length; 12.52 + } 12.53 + 12.54 + @Override 12.55 + public long getLength() { 12.56 + return length; 12.57 + } 12.58 + 12.59 + @Override 12.60 + public boolean hasNext() { 12.61 + if (length == 0L) { 12.62 + return false; //return empty string if toUint32(length) == 0 12.63 + } 12.64 + 12.65 + while (indexInArray()) { 12.66 + if (obj.containsKey(index) || includeUndefined) { 12.67 + break; 12.68 + } 12.69 + bumpIndex(); 12.70 + } 12.71 + 12.72 + return indexInArray(); 12.73 + } 12.74 + 12.75 + @Override 12.76 + public Object next() { 12.77 + if (indexInArray()) { 12.78 + return obj.get(bumpIndex()); 12.79 + } 12.80 + 12.81 + throw new NoSuchElementException(); 12.82 + } 12.83 +} 12.84 +
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/test/script/basic/JDK-8016618.js Fri Jun 14 21:16:14 2013 +0530 13.3 @@ -0,0 +1,132 @@ 13.4 +/* 13.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 13.7 + * 13.8 + * This code is free software; you can redistribute it and/or modify it 13.9 + * under the terms of the GNU General Public License version 2 only, as 13.10 + * published by the Free Software Foundation. 13.11 + * 13.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 13.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13.15 + * version 2 for more details (a copy is included in the LICENSE file that 13.16 + * accompanied this code). 13.17 + * 13.18 + * You should have received a copy of the GNU General Public License version 13.19 + * 2 along with this work; if not, write to the Free Software Foundation, 13.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 13.21 + * 13.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 13.23 + * or visit www.oracle.com if you need additional information or have any 13.24 + * questions. 13.25 + */ 13.26 + 13.27 +/** 13.28 + * JDK-8016618: script mirror object access should be improved 13.29 + * 13.30 + * @test 13.31 + * @option -scripting 13.32 + * @option -strict 13.33 + * @run 13.34 + */ 13.35 + 13.36 +var global = loadWithNewGlobal({ 13.37 + name: "code", 13.38 + script: <<EOF 13.39 +var x = 33; 13.40 + 13.41 +function func(x, y) { 13.42 + print('func.x = ' + x); 13.43 + print('func.x = ' + y) 13.44 +}; 13.45 + 13.46 +var obj = { 13.47 + foo: 'hello', 13.48 + bar: 42 13.49 +}; 13.50 + 13.51 +Object.defineProperty(obj, "bar", 13.52 + { enumerable: false, writable: false }); 13.53 + 13.54 +// return global 13.55 +this; 13.56 +EOF 13.57 +}); 13.58 + 13.59 +// load on mirror with local object as argument 13.60 +global.load({ 13.61 + name: "code", 13.62 + script: "print('x = ' + x)" 13.63 +}); 13.64 + 13.65 +function f() { 13.66 + // mirror function called with local arguments 13.67 + global.func.apply(obj, arguments); 13.68 +} 13.69 + 13.70 +f(23, "hello"); 13.71 + 13.72 +var fObject = global.eval("Object"); 13.73 + 13.74 +// instanceof on mirrors 13.75 +print("global instanceof fObject? " + (global instanceof fObject)); 13.76 + 13.77 +// Object API on mirrors 13.78 + 13.79 +var desc = Object.getOwnPropertyDescriptor(global, "x"); 13.80 +print("x is wriable ? " + desc.writable); 13.81 +print("x value = " + desc.value); 13.82 + 13.83 +var proto = Object.getPrototypeOf(global); 13.84 +print("global's __proto__ " + proto); 13.85 + 13.86 +var obj = global.obj; 13.87 +var keys = Object.keys(obj); 13.88 +print("Object.keys on obj"); 13.89 +for (var i in keys) { 13.90 + print(keys[i]); 13.91 +} 13.92 + 13.93 +print("Object.getOwnProperties on obj"); 13.94 +var keys = Object.getOwnPropertyNames(obj); 13.95 +for (var i in keys) { 13.96 + print(keys[i]); 13.97 +} 13.98 + 13.99 +// mirror array access 13.100 +var array = global.eval("[334, 55, 65]"); 13.101 +Array.prototype.forEach.call(array, function(elem) { 13.102 + print("forEach " + elem) 13.103 +}); 13.104 + 13.105 +print("reduceRight " + Array.prototype.reduceRight.call(array, 13.106 + function(previousValue, currentValue, index, array) { 13.107 + print("reduceRight cur value " + currentValue); 13.108 + return previousValue + currentValue; 13.109 +}, 0)); 13.110 + 13.111 +print("reduce " + Array.prototype.reduce.call(array, 13.112 + function(previousValue, currentValue, index, array) { 13.113 + print("reduce cur value " + currentValue); 13.114 + return previousValue + currentValue; 13.115 +}, 0)); 13.116 + 13.117 +print("forEach"); 13.118 +Array.prototype.forEach.call(array, function(o) { 13.119 + print(o); 13.120 +}); 13.121 + 13.122 +print("Array.isArray(array)? " + Array.isArray(array)); 13.123 + 13.124 +// try to write to a non-writable property of mirror 13.125 +try { 13.126 + obj.bar = 33; 13.127 +} catch (e) { 13.128 + print(e); 13.129 +} 13.130 + 13.131 +// mirror function called with local callback 13.132 +print("forEach on mirror"); 13.133 +array.forEach(function(toto) { 13.134 + print(toto); 13.135 +});
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/test/script/basic/JDK-8016618.js.EXPECTED Fri Jun 14 21:16:14 2013 +0530 14.3 @@ -0,0 +1,33 @@ 14.4 +x = 33 14.5 +func.x = 23 14.6 +func.x = hello 14.7 +global instanceof fObject? true 14.8 +x is wriable ? true 14.9 +x value = 33 14.10 +global's __proto__ [object Object] 14.11 +Object.keys on obj 14.12 +foo 14.13 +Object.getOwnProperties on obj 14.14 +foo 14.15 +bar 14.16 +forEach 334 14.17 +forEach 55 14.18 +forEach 65 14.19 +reduceRight cur value 65 14.20 +reduceRight cur value 55 14.21 +reduceRight cur value 334 14.22 +reduceRight 454 14.23 +reduce cur value 334 14.24 +reduce cur value 55 14.25 +reduce cur value 65 14.26 +reduce 454 14.27 +forEach 14.28 +334 14.29 +55 14.30 +65 14.31 +Array.isArray(array)? true 14.32 +TypeError: "bar" is not a writable property of [object Object] 14.33 +forEach on mirror 14.34 +334 14.35 +55 14.36 +65