Fri, 22 Nov 2013 08:52:45 +0530
Merge
1.1 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java Mon Nov 04 11:11:03 2013 +0100 1.2 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java Fri Nov 22 08:52:45 2013 +0530 1.3 @@ -2186,15 +2186,14 @@ 1.4 1.5 @Override 1.6 public boolean enterWhileNode(final WhileNode whileNode) { 1.7 - lineNumber(whileNode); 1.8 - 1.9 final Expression test = whileNode.getTest(); 1.10 final Block body = whileNode.getBody(); 1.11 final Label breakLabel = whileNode.getBreakLabel(); 1.12 final Label continueLabel = whileNode.getContinueLabel(); 1.13 + final boolean isDoWhile = whileNode.isDoWhile(); 1.14 final Label loopLabel = new Label("loop"); 1.15 1.16 - if (!whileNode.isDoWhile()) { 1.17 + if (!isDoWhile) { 1.18 method._goto(continueLabel); 1.19 } 1.20 1.21 @@ -2202,6 +2201,7 @@ 1.22 body.accept(this); 1.23 if (!whileNode.isTerminal()) { 1.24 method.label(continueLabel); 1.25 + lineNumber(whileNode); 1.26 new BranchOptimizer(this, method).execute(test, loopLabel, true); 1.27 method.label(breakLabel); 1.28 }
2.1 --- a/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java Mon Nov 04 11:11:03 2013 +0100 2.2 +++ b/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java Fri Nov 22 08:52:45 2013 +0530 2.3 @@ -28,6 +28,7 @@ 2.4 import java.util.List; 2.5 import jdk.nashorn.internal.ir.BinaryNode; 2.6 import jdk.nashorn.internal.ir.Block; 2.7 +import jdk.nashorn.internal.ir.BlockStatement; 2.8 import jdk.nashorn.internal.ir.CaseNode; 2.9 import jdk.nashorn.internal.ir.CatchNode; 2.10 import jdk.nashorn.internal.ir.ExpressionStatement; 2.11 @@ -141,7 +142,6 @@ 2.12 @Override 2.13 public boolean enterBlock(final Block block) { 2.14 sb.append(' '); 2.15 - //sb.append(Debug.id(block)); 2.16 sb.append('{'); 2.17 2.18 indent += TABWIDTH; 2.19 @@ -190,12 +190,17 @@ 2.20 sb.append(EOLN); 2.21 indent(); 2.22 sb.append('}'); 2.23 - // sb.append(Debug.id(block)); 2.24 2.25 return false; 2.26 } 2.27 2.28 @Override 2.29 + public boolean enterBlockStatement(final BlockStatement statement) { 2.30 + statement.getBlock().accept(this); 2.31 + return false; 2.32 + } 2.33 + 2.34 + @Override 2.35 public boolean enterBinaryNode(final BinaryNode binaryNode) { 2.36 binaryNode.lhs().accept(this); 2.37 sb.append(' '); 2.38 @@ -233,7 +238,6 @@ 2.39 public boolean enterFunctionNode(final FunctionNode functionNode) { 2.40 functionNode.toString(sb); 2.41 enterBlock(functionNode.getBody()); 2.42 - //sb.append(EOLN); 2.43 return false; 2.44 } 2.45
3.1 --- a/src/jdk/nashorn/internal/objects/NativeArguments.java Mon Nov 04 11:11:03 2013 +0100 3.2 +++ b/src/jdk/nashorn/internal/objects/NativeArguments.java Fri Nov 22 08:52:45 2013 +0530 3.3 @@ -35,6 +35,7 @@ 3.4 import java.util.Arrays; 3.5 import java.util.BitSet; 3.6 import jdk.nashorn.internal.runtime.AccessorProperty; 3.7 +import jdk.nashorn.internal.runtime.JSType; 3.8 import jdk.nashorn.internal.runtime.Property; 3.9 import jdk.nashorn.internal.runtime.PropertyDescriptor; 3.10 import jdk.nashorn.internal.runtime.PropertyMap; 3.11 @@ -140,8 +141,9 @@ 3.12 3.13 @Override 3.14 public boolean delete(final Object key, final boolean strict) { 3.15 - final int index = ArrayIndex.getArrayIndex(key); 3.16 - return isMapped(index) ? deleteMapped(index, strict) : super.delete(key, strict); 3.17 + final Object primitiveKey = JSType.toPrimitive(key, String.class); 3.18 + final int index = ArrayIndex.getArrayIndex(primitiveKey); 3.19 + return isMapped(index) ? deleteMapped(index, strict) : super.delete(primitiveKey, strict); 3.20 } 3.21 3.22 /**
4.1 --- a/src/jdk/nashorn/internal/objects/NativeObject.java Mon Nov 04 11:11:03 2013 +0100 4.2 +++ b/src/jdk/nashorn/internal/objects/NativeObject.java Fri Nov 22 08:52:45 2013 +0530 4.3 @@ -484,10 +484,12 @@ 4.4 */ 4.5 @Function(attributes = Attribute.NOT_ENUMERABLE) 4.6 public static Object hasOwnProperty(final Object self, final Object v) { 4.7 - final String str = JSType.toString(v); 4.8 + // Convert ScriptObjects to primitive with String.class hint 4.9 + // but no need to convert other primitives to string. 4.10 + final Object key = JSType.toPrimitive(v, String.class); 4.11 final Object obj = Global.toObject(self); 4.12 4.13 - return (obj instanceof ScriptObject) && ((ScriptObject)obj).hasOwnProperty(str); 4.14 + return (obj instanceof ScriptObject) && ((ScriptObject)obj).hasOwnProperty(key); 4.15 } 4.16 4.17 /**
5.1 --- a/src/jdk/nashorn/internal/objects/NativeString.java Mon Nov 04 11:11:03 2013 +0100 5.2 +++ b/src/jdk/nashorn/internal/objects/NativeString.java Fri Nov 22 08:52:45 2013 +0530 5.3 @@ -167,11 +167,12 @@ 5.4 @SuppressWarnings("unused") 5.5 private static Object get(final Object self, final Object key) { 5.6 final CharSequence cs = JSType.toCharSequence(self); 5.7 - final int index = ArrayIndex.getArrayIndex(key); 5.8 + final Object primitiveKey = JSType.toPrimitive(key, String.class); 5.9 + final int index = ArrayIndex.getArrayIndex(primitiveKey); 5.10 if (index >= 0 && index < cs.length()) { 5.11 return String.valueOf(cs.charAt(index)); 5.12 } 5.13 - return ((ScriptObject) Global.toObject(self)).get(key); 5.14 + return ((ScriptObject) Global.toObject(self)).get(primitiveKey); 5.15 } 5.16 5.17 @SuppressWarnings("unused") 5.18 @@ -202,11 +203,12 @@ 5.19 // String characters can be accessed with array-like indexing.. 5.20 @Override 5.21 public Object get(final Object key) { 5.22 - final int index = ArrayIndex.getArrayIndex(key); 5.23 + final Object primitiveKey = JSType.toPrimitive(key, String.class); 5.24 + final int index = ArrayIndex.getArrayIndex(primitiveKey); 5.25 if (index >= 0 && index < value.length()) { 5.26 return String.valueOf(value.charAt(index)); 5.27 } 5.28 - return super.get(key); 5.29 + return super.get(primitiveKey); 5.30 } 5.31 5.32 @Override 5.33 @@ -295,8 +297,9 @@ 5.34 5.35 @Override 5.36 public boolean has(final Object key) { 5.37 - final int index = ArrayIndex.getArrayIndex(key); 5.38 - return isValid(index) || super.has(key); 5.39 + final Object primitiveKey = JSType.toPrimitive(key, String.class); 5.40 + final int index = ArrayIndex.getArrayIndex(primitiveKey); 5.41 + return isValid(index) || super.has(primitiveKey); 5.42 } 5.43 5.44 @Override 5.45 @@ -318,8 +321,9 @@ 5.46 5.47 @Override 5.48 public boolean hasOwnProperty(final Object key) { 5.49 - final int index = ArrayIndex.getArrayIndex(key); 5.50 - return isValid(index) || super.hasOwnProperty(key); 5.51 + final Object primitiveKey = JSType.toPrimitive(key, String.class); 5.52 + final int index = ArrayIndex.getArrayIndex(primitiveKey); 5.53 + return isValid(index) || super.hasOwnProperty(primitiveKey); 5.54 } 5.55 5.56 @Override 5.57 @@ -358,8 +362,9 @@ 5.58 5.59 @Override 5.60 public boolean delete(final Object key, final boolean strict) { 5.61 - final int index = ArrayIndex.getArrayIndex(key); 5.62 - return checkDeleteIndex(index, strict)? false : super.delete(key, strict); 5.63 + final Object primitiveKey = JSType.toPrimitive(key, String.class); 5.64 + final int index = ArrayIndex.getArrayIndex(primitiveKey); 5.65 + return checkDeleteIndex(index, strict)? false : super.delete(primitiveKey, strict); 5.66 } 5.67 5.68 private boolean checkDeleteIndex(final int index, final boolean strict) {
6.1 --- a/src/jdk/nashorn/internal/parser/Parser.java Mon Nov 04 11:11:03 2013 +0100 6.2 +++ b/src/jdk/nashorn/internal/parser/Parser.java Fri Nov 22 08:52:45 2013 +0530 6.3 @@ -1210,21 +1210,24 @@ 6.4 */ 6.5 private void whileStatement() { 6.6 // Capture WHILE token. 6.7 - final int whileLine = line; 6.8 final long whileToken = token; 6.9 // WHILE tested in caller. 6.10 next(); 6.11 6.12 // Construct WHILE node. 6.13 - WhileNode whileNode = new WhileNode(whileLine, whileToken, Token.descPosition(whileToken), false); 6.14 + WhileNode whileNode = new WhileNode(line, whileToken, Token.descPosition(whileToken), false); 6.15 lc.push(whileNode); 6.16 6.17 try { 6.18 expect(LPAREN); 6.19 - whileNode = whileNode.setTest(lc, expression()); 6.20 + final int whileLine = line; 6.21 + final Expression test = expression(); 6.22 expect(RPAREN); 6.23 - whileNode = whileNode.setBody(lc, getStatement()); 6.24 - appendStatement(whileNode); 6.25 + final Block body = getStatement(); 6.26 + appendStatement(whileNode = 6.27 + new WhileNode(whileLine, whileToken, finish, false). 6.28 + setTest(lc, test). 6.29 + setBody(lc, body)); 6.30 } finally { 6.31 lc.pop(whileNode); 6.32 } 6.33 @@ -1242,28 +1245,33 @@ 6.34 */ 6.35 private void doStatement() { 6.36 // Capture DO token. 6.37 - final int doLine = line; 6.38 final long doToken = token; 6.39 // DO tested in the caller. 6.40 next(); 6.41 6.42 - WhileNode doWhileNode = new WhileNode(doLine, doToken, Token.descPosition(doToken), true); 6.43 + WhileNode doWhileNode = new WhileNode(-1, doToken, Token.descPosition(doToken), true); 6.44 lc.push(doWhileNode); 6.45 6.46 try { 6.47 // Get DO body. 6.48 - doWhileNode = doWhileNode.setBody(lc, getStatement()); 6.49 + final Block body = getStatement(); 6.50 6.51 expect(WHILE); 6.52 expect(LPAREN); 6.53 - doWhileNode = doWhileNode.setTest(lc, expression()); 6.54 + final int doLine = line; 6.55 + final Expression test = expression(); 6.56 expect(RPAREN); 6.57 6.58 if (type == SEMICOLON) { 6.59 endOfLine(); 6.60 } 6.61 doWhileNode.setFinish(finish); 6.62 - appendStatement(doWhileNode); 6.63 + 6.64 + //line number is last 6.65 + appendStatement(doWhileNode = 6.66 + new WhileNode(doLine, doToken, finish, true). 6.67 + setBody(lc, body). 6.68 + setTest(lc, test)); 6.69 } finally { 6.70 lc.pop(doWhileNode); 6.71 }
7.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Mon Nov 04 11:11:03 2013 +0100 7.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Nov 22 08:52:45 2013 +0530 7.3 @@ -2373,11 +2373,13 @@ 7.4 7.5 private int getInt(final int index, final String key) { 7.6 if (isValidArrayIndex(index)) { 7.7 - for (ScriptObject object = this; ; ) { 7.8 - final FindProperty find = object.findProperty(key, false, false, this); 7.9 - 7.10 - if (find != null) { 7.11 - return getIntValue(find); 7.12 + for (ScriptObject object = this; ; ) { 7.13 + if (object.getMap().containsArrayKeys()) { 7.14 + final FindProperty find = object.findProperty(key, false, false, this); 7.15 + 7.16 + if (find != null) { 7.17 + return getIntValue(find); 7.18 + } 7.19 } 7.20 7.21 if ((object = object.getProto()) == null) { 7.22 @@ -2389,7 +2391,7 @@ 7.23 if (array.has(index)) { 7.24 return array.getInt(index); 7.25 } 7.26 - } 7.27 + } 7.28 } else { 7.29 final FindProperty find = findProperty(key, true); 7.30 7.31 @@ -2403,14 +2405,15 @@ 7.32 7.33 @Override 7.34 public int getInt(final Object key) { 7.35 - final int index = getArrayIndex(key); 7.36 + final Object primitiveKey = JSType.toPrimitive(key, String.class); 7.37 + final int index = getArrayIndex(primitiveKey); 7.38 final ArrayData array = getArray(); 7.39 7.40 if (array.has(index)) { 7.41 return array.getInt(index); 7.42 } 7.43 7.44 - return getInt(index, JSType.toString(key)); 7.45 + return getInt(index, JSType.toString(primitiveKey)); 7.46 } 7.47 7.48 @Override 7.49 @@ -2439,22 +2442,25 @@ 7.50 7.51 @Override 7.52 public int getInt(final int key) { 7.53 + final int index = getArrayIndex(key); 7.54 final ArrayData array = getArray(); 7.55 7.56 - if (array.has(key)) { 7.57 - return array.getInt(key); 7.58 + if (array.has(index)) { 7.59 + return array.getInt(index); 7.60 } 7.61 7.62 - return getInt(key, JSType.toString(key)); 7.63 + return getInt(index, JSType.toString(key)); 7.64 } 7.65 7.66 private long getLong(final int index, final String key) { 7.67 if (isValidArrayIndex(index)) { 7.68 for (ScriptObject object = this; ; ) { 7.69 - final FindProperty find = object.findProperty(key, false, false, this); 7.70 - 7.71 - if (find != null) { 7.72 - return getLongValue(find); 7.73 + if (object.getMap().containsArrayKeys()) { 7.74 + final FindProperty find = object.findProperty(key, false, false, this); 7.75 + 7.76 + if (find != null) { 7.77 + return getLongValue(find); 7.78 + } 7.79 } 7.80 7.81 if ((object = object.getProto()) == null) { 7.82 @@ -2466,7 +2472,7 @@ 7.83 if (array.has(index)) { 7.84 return array.getLong(index); 7.85 } 7.86 - } 7.87 + } 7.88 } else { 7.89 final FindProperty find = findProperty(key, true); 7.90 7.91 @@ -2480,14 +2486,15 @@ 7.92 7.93 @Override 7.94 public long getLong(final Object key) { 7.95 - final int index = getArrayIndex(key); 7.96 + final Object primitiveKey = JSType.toPrimitive(key, String.class); 7.97 + final int index = getArrayIndex(primitiveKey); 7.98 final ArrayData array = getArray(); 7.99 7.100 if (array.has(index)) { 7.101 return array.getLong(index); 7.102 } 7.103 7.104 - return getLong(index, JSType.toString(key)); 7.105 + return getLong(index, JSType.toString(primitiveKey)); 7.106 } 7.107 7.108 @Override 7.109 @@ -2516,22 +2523,25 @@ 7.110 7.111 @Override 7.112 public long getLong(final int key) { 7.113 + final int index = getArrayIndex(key); 7.114 final ArrayData array = getArray(); 7.115 7.116 - if (array.has(key)) { 7.117 - return array.getLong(key); 7.118 + if (array.has(index)) { 7.119 + return array.getLong(index); 7.120 } 7.121 7.122 - return getLong(key, JSType.toString(key)); 7.123 + return getLong(index, JSType.toString(key)); 7.124 } 7.125 7.126 private double getDouble(final int index, final String key) { 7.127 if (isValidArrayIndex(index)) { 7.128 for (ScriptObject object = this; ; ) { 7.129 - final FindProperty find = object.findProperty(key, false, false, this); 7.130 - 7.131 - if (find != null) { 7.132 - return getDoubleValue(find); 7.133 + if (object.getMap().containsArrayKeys()) { 7.134 + final FindProperty find = object.findProperty(key, false, false, this); 7.135 + 7.136 + if (find != null) { 7.137 + return getDoubleValue(find); 7.138 + } 7.139 } 7.140 7.141 if ((object = object.getProto()) == null) { 7.142 @@ -2543,7 +2553,7 @@ 7.143 if (array.has(index)) { 7.144 return array.getDouble(index); 7.145 } 7.146 - } 7.147 + } 7.148 } else { 7.149 final FindProperty find = findProperty(key, true); 7.150 7.151 @@ -2557,14 +2567,15 @@ 7.152 7.153 @Override 7.154 public double getDouble(final Object key) { 7.155 - final int index = getArrayIndex(key); 7.156 + final Object primitiveKey = JSType.toPrimitive(key, String.class); 7.157 + final int index = getArrayIndex(primitiveKey); 7.158 final ArrayData array = getArray(); 7.159 7.160 if (array.has(index)) { 7.161 return array.getDouble(index); 7.162 } 7.163 7.164 - return getDouble(index, JSType.toString(key)); 7.165 + return getDouble(index, JSType.toString(primitiveKey)); 7.166 } 7.167 7.168 @Override 7.169 @@ -2593,22 +2604,25 @@ 7.170 7.171 @Override 7.172 public double getDouble(final int key) { 7.173 + final int index = getArrayIndex(key); 7.174 final ArrayData array = getArray(); 7.175 7.176 - if (array.has(key)) { 7.177 - return array.getDouble(key); 7.178 + if (array.has(index)) { 7.179 + return array.getDouble(index); 7.180 } 7.181 7.182 - return getDouble(key, JSType.toString(key)); 7.183 + return getDouble(index, JSType.toString(key)); 7.184 } 7.185 7.186 private Object get(final int index, final String key) { 7.187 if (isValidArrayIndex(index)) { 7.188 for (ScriptObject object = this; ; ) { 7.189 - final FindProperty find = object.findProperty(key, false, false, this); 7.190 - 7.191 - if (find != null) { 7.192 - return getObjectValue(find); 7.193 + if (object.getMap().containsArrayKeys()) { 7.194 + final FindProperty find = object.findProperty(key, false, false, this); 7.195 + 7.196 + if (find != null) { 7.197 + return getObjectValue(find); 7.198 + } 7.199 } 7.200 7.201 if ((object = object.getProto()) == null) { 7.202 @@ -2634,14 +2648,15 @@ 7.203 7.204 @Override 7.205 public Object get(final Object key) { 7.206 - final int index = getArrayIndex(key); 7.207 + final Object primitiveKey = JSType.toPrimitive(key, String.class); 7.208 + final int index = getArrayIndex(primitiveKey); 7.209 final ArrayData array = getArray(); 7.210 7.211 if (array.has(index)) { 7.212 return array.getObject(index); 7.213 } 7.214 7.215 - return get(index, JSType.toString(key)); 7.216 + return get(index, JSType.toString(primitiveKey)); 7.217 } 7.218 7.219 @Override 7.220 @@ -2670,13 +2685,14 @@ 7.221 7.222 @Override 7.223 public Object get(final int key) { 7.224 + final int index = getArrayIndex(key); 7.225 final ArrayData array = getArray(); 7.226 7.227 - if (array.has(key)) { 7.228 - return array.getObject(key); 7.229 + if (array.has(index)) { 7.230 + return array.getObject(index); 7.231 } 7.232 7.233 - return get(key, JSType.toString(key)); 7.234 + return get(index, JSType.toString(key)); 7.235 } 7.236 7.237 /** 7.238 @@ -2688,7 +2704,7 @@ 7.239 */ 7.240 private void doesNotHave(final int index, final Object value, final boolean strict) { 7.241 final long oldLength = getArray().length(); 7.242 - final long longIndex = index & JSType.MAX_UINT; 7.243 + final long longIndex = ArrayIndex.toLongIndex(index); 7.244 7.245 if (getMap().containsArrayKeys()) { 7.246 final String key = JSType.toString(longIndex); 7.247 @@ -2774,7 +2790,8 @@ 7.248 7.249 @Override 7.250 public void set(final Object key, final int value, final boolean strict) { 7.251 - final int index = getArrayIndex(key); 7.252 + final Object primitiveKey = JSType.toPrimitive(key, String.class); 7.253 + final int index = getArrayIndex(primitiveKey); 7.254 7.255 if (isValidArrayIndex(index)) { 7.256 if (getArray().has(index)) { 7.257 @@ -2786,13 +2803,14 @@ 7.258 return; 7.259 } 7.260 7.261 - final String propName = JSType.toString(key); 7.262 + final String propName = JSType.toString(primitiveKey); 7.263 setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 7.264 } 7.265 7.266 @Override 7.267 public void set(final Object key, final long value, final boolean strict) { 7.268 - final int index = getArrayIndex(key); 7.269 + final Object primitiveKey = JSType.toPrimitive(key, String.class); 7.270 + final int index = getArrayIndex(primitiveKey); 7.271 7.272 if (isValidArrayIndex(index)) { 7.273 if (getArray().has(index)) { 7.274 @@ -2804,13 +2822,14 @@ 7.275 return; 7.276 } 7.277 7.278 - final String propName = JSType.toString(key); 7.279 + final String propName = JSType.toString(primitiveKey); 7.280 setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 7.281 } 7.282 7.283 @Override 7.284 public void set(final Object key, final double value, final boolean strict) { 7.285 - final int index = getArrayIndex(key); 7.286 + final Object primitiveKey = JSType.toPrimitive(key, String.class); 7.287 + final int index = getArrayIndex(primitiveKey); 7.288 7.289 if (isValidArrayIndex(index)) { 7.290 if (getArray().has(index)) { 7.291 @@ -2822,13 +2841,14 @@ 7.292 return; 7.293 } 7.294 7.295 - final String propName = JSType.toString(key); 7.296 + final String propName = JSType.toString(primitiveKey); 7.297 setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 7.298 } 7.299 7.300 @Override 7.301 public void set(final Object key, final Object value, final boolean strict) { 7.302 - final int index = getArrayIndex(key); 7.303 + final Object primitiveKey = JSType.toPrimitive(key, String.class); 7.304 + final int index = getArrayIndex(primitiveKey); 7.305 7.306 if (isValidArrayIndex(index)) { 7.307 if (getArray().has(index)) { 7.308 @@ -2840,7 +2860,7 @@ 7.309 return; 7.310 } 7.311 7.312 - final String propName = JSType.toString(key); 7.313 + final String propName = JSType.toString(primitiveKey); 7.314 setObject(findProperty(propName, true), strict, propName, value); 7.315 } 7.316 7.317 @@ -3062,82 +3082,69 @@ 7.318 7.319 @Override 7.320 public boolean has(final Object key) { 7.321 - final int index = getArrayIndex(key); 7.322 - 7.323 - if (isValidArrayIndex(index)) { 7.324 - for (ScriptObject self = this; self != null; self = self.getProto()) { 7.325 - if (self.getArray().has(index)) { 7.326 - return true; 7.327 - } 7.328 - } 7.329 - } 7.330 - 7.331 - return hasProperty(JSType.toString(key), true); 7.332 + final Object primitiveKey = JSType.toPrimitive(key); 7.333 + final int index = getArrayIndex(primitiveKey); 7.334 + return isValidArrayIndex(index) ? hasArrayProperty(index) : hasProperty(JSType.toString(primitiveKey), true); 7.335 } 7.336 7.337 @Override 7.338 public boolean has(final double key) { 7.339 final int index = getArrayIndex(key); 7.340 - 7.341 - if (isValidArrayIndex(index)) { 7.342 - for (ScriptObject self = this; self != null; self = self.getProto()) { 7.343 - if (self.getArray().has(index)) { 7.344 - return true; 7.345 - } 7.346 - } 7.347 - } 7.348 - 7.349 - return hasProperty(JSType.toString(key), true); 7.350 + return isValidArrayIndex(index) ? hasArrayProperty(index) : hasProperty(JSType.toString(key), true); 7.351 } 7.352 7.353 @Override 7.354 public boolean has(final long key) { 7.355 final int index = getArrayIndex(key); 7.356 - 7.357 - if (isValidArrayIndex(index)) { 7.358 - for (ScriptObject self = this; self != null; self = self.getProto()) { 7.359 - if (self.getArray().has(index)) { 7.360 - return true; 7.361 - } 7.362 - } 7.363 - } 7.364 - 7.365 - return hasProperty(JSType.toString(key), true); 7.366 + return isValidArrayIndex(index) ? hasArrayProperty(index) : hasProperty(JSType.toString(key), true); 7.367 } 7.368 7.369 @Override 7.370 public boolean has(final int key) { 7.371 final int index = getArrayIndex(key); 7.372 - 7.373 - if (isValidArrayIndex(index)) { 7.374 - for (ScriptObject self = this; self != null; self = self.getProto()) { 7.375 - if (self.getArray().has(index)) { 7.376 - return true; 7.377 - } 7.378 + return isValidArrayIndex(index) ? hasArrayProperty(index) : hasProperty(JSType.toString(key), true); 7.379 + } 7.380 + 7.381 + private boolean hasArrayProperty(final int index) { 7.382 + boolean hasArrayKeys = false; 7.383 + 7.384 + for (ScriptObject self = this; self != null; self = self.getProto()) { 7.385 + if (self.getArray().has(index)) { 7.386 + return true; 7.387 } 7.388 + hasArrayKeys = hasArrayKeys || self.getMap().containsArrayKeys(); 7.389 } 7.390 7.391 - return hasProperty(JSType.toString(key), true); 7.392 + return hasArrayKeys && hasProperty(ArrayIndex.toKey(index), true); 7.393 } 7.394 7.395 @Override 7.396 public boolean hasOwnProperty(final Object key) { 7.397 - return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false); 7.398 + final Object primitiveKey = JSType.toPrimitive(key, String.class); 7.399 + final int index = getArrayIndex(primitiveKey); 7.400 + return isValidArrayIndex(index) ? hasOwnArrayProperty(index) : hasProperty(JSType.toString(primitiveKey), false); 7.401 } 7.402 7.403 @Override 7.404 public boolean hasOwnProperty(final int key) { 7.405 - return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false); 7.406 + final int index = getArrayIndex(key); 7.407 + return isValidArrayIndex(index) ? hasOwnArrayProperty(index) : hasProperty(JSType.toString(key), false); 7.408 } 7.409 7.410 @Override 7.411 public boolean hasOwnProperty(final long key) { 7.412 - return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false); 7.413 + final int index = getArrayIndex(key); 7.414 + return isValidArrayIndex(index) ? hasOwnArrayProperty(index) : hasProperty(JSType.toString(key), false); 7.415 } 7.416 7.417 @Override 7.418 public boolean hasOwnProperty(final double key) { 7.419 - return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false); 7.420 + final int index = getArrayIndex(key); 7.421 + return isValidArrayIndex(index) ? hasOwnArrayProperty(index) : hasProperty(JSType.toString(key), false); 7.422 + } 7.423 + 7.424 + private boolean hasOwnArrayProperty(final int index) { 7.425 + return getArray().has(index) || (getMap().containsArrayKeys() && hasProperty(ArrayIndex.toKey(index), false)); 7.426 } 7.427 7.428 @Override 7.429 @@ -3190,7 +3197,8 @@ 7.430 7.431 @Override 7.432 public boolean delete(final Object key, final boolean strict) { 7.433 - final int index = getArrayIndex(key); 7.434 + final Object primitiveKey = JSType.toPrimitive(key, String.class); 7.435 + final int index = getArrayIndex(primitiveKey); 7.436 final ArrayData array = getArray(); 7.437 7.438 if (array.has(index)) { 7.439 @@ -3201,7 +3209,7 @@ 7.440 return false; 7.441 } 7.442 7.443 - return deleteObject(key, strict); 7.444 + return deleteObject(primitiveKey, strict); 7.445 } 7.446 7.447 private boolean deleteObject(final Object key, final boolean strict) {
8.1 --- a/src/jdk/nashorn/internal/runtime/arrays/ArrayIndex.java Mon Nov 04 11:11:03 2013 +0100 8.2 +++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayIndex.java Fri Nov 22 08:52:45 2013 +0530 8.3 @@ -27,6 +27,7 @@ 8.4 8.5 import jdk.nashorn.internal.runtime.ConsString; 8.6 import jdk.nashorn.internal.runtime.JSType; 8.7 +import jdk.nashorn.internal.runtime.ScriptObject; 8.8 8.9 /** 8.10 * Array index computation helpers. that both throw exceptions or return 8.11 @@ -80,7 +81,12 @@ 8.12 * Returns a valid array index in an int, if the object represents one. This 8.13 * routine needs to perform quickly since all keys are tested with it. 8.14 * 8.15 - * @param key key to check for array index 8.16 + * <p>The {@code key} parameter must be a JavaScript primitive type, i.e. one of 8.17 + * {@code String}, {@code Number}, {@code Boolean}, {@code null}, or {@code undefined}. 8.18 + * {@code ScriptObject} instances should be converted to primitive with 8.19 + * {@code String.class} hint before being passed to this method.</p> 8.20 + * 8.21 + * @param key key to check for array index. 8.22 * @return the array index, or {@code -1} if {@code key} does not represent a valid index. 8.23 * Note that negative return values other than {@code -1} are considered valid and can be converted to 8.24 * the actual index using {@link #toLongIndex(int)}. 8.25 @@ -88,18 +94,31 @@ 8.26 public static int getArrayIndex(final Object key) { 8.27 if (key instanceof Integer) { 8.28 return getArrayIndex(((Integer) key).intValue()); 8.29 - } else if (key instanceof Number) { 8.30 - return getArrayIndex(((Number) key).doubleValue()); 8.31 + } else if (key instanceof Double) { 8.32 + return getArrayIndex(((Double) key).doubleValue()); 8.33 } else if (key instanceof String) { 8.34 return (int)fromString((String) key); 8.35 + } else if (key instanceof Long) { 8.36 + return getArrayIndex(((Long) key).longValue()); 8.37 } else if (key instanceof ConsString) { 8.38 return (int)fromString(key.toString()); 8.39 } 8.40 8.41 + assert !(key instanceof ScriptObject); 8.42 return INVALID_ARRAY_INDEX; 8.43 } 8.44 8.45 /** 8.46 + * Returns a valid array index in an int, if {@code key} represents one. 8.47 + * 8.48 + * @param key key to check 8.49 + * @return the array index, or {@code -1} if {@code key} is not a valid array index. 8.50 + */ 8.51 + public static int getArrayIndex(final int key) { 8.52 + return (key >= 0) ? key : INVALID_ARRAY_INDEX; 8.53 + } 8.54 + 8.55 + /** 8.56 * Returns a valid array index in an int, if the long represents one. 8.57 * 8.58 * @param key key to check 8.59 @@ -129,10 +148,7 @@ 8.60 */ 8.61 public static int getArrayIndex(final double key) { 8.62 if (JSType.isRepresentableAsInt(key)) { 8.63 - final int intKey = (int)key; 8.64 - if (intKey >= 0) { 8.65 - return intKey; 8.66 - } 8.67 + return getArrayIndex((int) key); 8.68 } else if (JSType.isRepresentableAsLong(key)) { 8.69 return getArrayIndex((long) key); 8.70 } 8.71 @@ -177,5 +193,16 @@ 8.72 return index & JSType.MAX_UINT; 8.73 } 8.74 8.75 + /** 8.76 + * Convert an index to a key string. This is the same as calling {@link #toLongIndex(int)} 8.77 + * and converting the result to String. 8.78 + * 8.79 + * @param index index to convert 8.80 + * @return index as string 8.81 + */ 8.82 + public static String toKey(final int index) { 8.83 + return Long.toString(index & JSType.MAX_UINT); 8.84 + } 8.85 + 8.86 } 8.87
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/test/script/basic/JDK-8028210.js Fri Nov 22 08:52:45 2013 +0530 9.3 @@ -0,0 +1,83 @@ 9.4 +/* 9.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.7 + * 9.8 + * This code is free software; you can redistribute it and/or modify it 9.9 + * under the terms of the GNU General Public License version 2 only, as 9.10 + * published by the Free Software Foundation. 9.11 + * 9.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 9.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 9.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 9.15 + * version 2 for more details (a copy is included in the LICENSE file that 9.16 + * accompanied this code). 9.17 + * 9.18 + * You should have received a copy of the GNU General Public License version 9.19 + * 2 along with this work; if not, write to the Free Software Foundation, 9.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 9.21 + * 9.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 9.23 + * or visit www.oracle.com if you need additional information or have any 9.24 + * questions. 9.25 + */ 9.26 + 9.27 +/** 9.28 + * JDK-8028210: Missing conversions on array index expression 9.29 + * 9.30 + * @test 9.31 + * @run 9.32 + */ 9.33 + 9.34 +var array = [1, 2]; 9.35 +var key1 = [[[0]]]; 9.36 +var key2 = new String("1"); 9.37 +var key3 = { 9.38 + toString: function() { 9.39 + print("toString called"); 9.40 + return "2"; 9.41 + } 9.42 +}; 9.43 + 9.44 +print(array[key1]); 9.45 +print(array[key2]); 9.46 +array[key3] = 3; 9.47 +print(array[key3]); 9.48 +print(key3 in array); 9.49 +print(array.hasOwnProperty(key3)); 9.50 +print(delete array[key3]); 9.51 +print(array[key3]); 9.52 + 9.53 +// string access 9.54 +print("abc"[key1]); 9.55 +print("abc"[key2]); 9.56 +print("abc"[key3]); 9.57 + 9.58 +// arguments object 9.59 +(function(a, b, c) { 9.60 + print(arguments[key3]); 9.61 + delete arguments[key3]; 9.62 + print(arguments[key3], c); 9.63 +})(1, 2, 3); 9.64 + 9.65 +// int keys 9.66 +array = []; 9.67 +array[4294967294] = 1; 9.68 +print(array[-2]); 9.69 +print(array[4294967294]); 9.70 +print(-2 in array); 9.71 +print(4294967294 in array); 9.72 +print(delete(array[-2])); 9.73 +print(array[4294967294]); 9.74 +print(delete(array[4294967294])); 9.75 +print(array[4294967294]); 9.76 + 9.77 +array = []; 9.78 +array[-2] = 1; 9.79 +print(array[-2]); 9.80 +print(array[4294967294]); 9.81 +print(-2 in array); 9.82 +print(4294967294 in array); 9.83 +print(delete(array[4294967294])); 9.84 +print(array[-2]); 9.85 +print(delete(array[-2])); 9.86 +print(array[-2]);
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/test/script/basic/JDK-8028210.js.EXPECTED Fri Nov 22 08:52:45 2013 +0530 10.3 @@ -0,0 +1,38 @@ 10.4 +1 10.5 +2 10.6 +toString called 10.7 +toString called 10.8 +3 10.9 +toString called 10.10 +true 10.11 +toString called 10.12 +true 10.13 +toString called 10.14 +true 10.15 +toString called 10.16 +undefined 10.17 +a 10.18 +b 10.19 +toString called 10.20 +c 10.21 +toString called 10.22 +3 10.23 +toString called 10.24 +toString called 10.25 +undefined 3 10.26 +undefined 10.27 +1 10.28 +false 10.29 +true 10.30 +true 10.31 +1 10.32 +true 10.33 +undefined 10.34 +1 10.35 +undefined 10.36 +true 10.37 +false 10.38 +true 10.39 +1 10.40 +true 10.41 +undefined
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/test/script/basic/JDK-8028434.js Fri Nov 22 08:52:45 2013 +0530 11.3 @@ -0,0 +1,58 @@ 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. 11.11 + * 11.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 11.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11.15 + * version 2 for more details (a copy is included in the LICENSE file that 11.16 + * accompanied this code). 11.17 + * 11.18 + * You should have received a copy of the GNU General Public License version 11.19 + * 2 along with this work; if not, write to the Free Software Foundation, 11.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 11.21 + * 11.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 11.23 + * or visit www.oracle.com if you need additional information or have any 11.24 + * questions. 11.25 + */ 11.26 + 11.27 +/** 11.28 + * JDK-8028434: Check that the line number of the tests in while and do while loops 11.29 + * is correct. It needs to correspond to the line with the test expression. 11.30 + * 11.31 + * @test 11.32 + * @run 11.33 + */ 11.34 + 11.35 +try { 11.36 + while (test.apa < 0) { 11.37 + print("x"); 11.38 + } 11.39 +} catch (e) { 11.40 + var st = e.getStackTrace(); 11.41 + if (st.length != 1) { 11.42 + print("erroneous stacktrace length " + s.length); 11.43 + } 11.44 + if (st[0].lineNumber !== 33) { 11.45 + print("erroneous stacktrace element, lineNumber=" + st[0].lineNumber + " elem=" + st); 11.46 + } 11.47 +} 11.48 + 11.49 +try { 11.50 + do { 11.51 + print("x"); 11.52 + } while (test.apa < 0); 11.53 +} catch (e) { 11.54 + var st = e.getStackTrace(); 11.55 + if (st.length != 1) { 11.56 + print("erroneous stacktrace length " + s.length); 11.57 + } 11.58 + if (st[0].lineNumber !== 49) { 11.59 + print("erroneous stacktrace element, lineNumber= " + st[0].lineNumber + " elem=" + st); 11.60 + } 11.61 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/test/script/basic/JDK-8028434.js.EXPECTED Fri Nov 22 08:52:45 2013 +0530 12.3 @@ -0,0 +1,1 @@ 12.4 +x
13.1 --- a/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Mon Nov 04 11:11:03 2013 +0100 13.2 +++ b/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Fri Nov 22 08:52:45 2013 +0530 13.3 @@ -50,7 +50,7 @@ 13.4 * 13.5 * @test 13.6 * @build jdk.nashorn.api.scripting.Window jdk.nashorn.api.scripting.WindowEventHandler jdk.nashorn.api.scripting.VariableArityTestInterface jdk.nashorn.api.scripting.ScriptEngineTest 13.7 - * @run testng jdk.nashorn.api.scripting.ScriptEngineTest 13.8 + * @run testng/othervm jdk.nashorn.api.scripting.ScriptEngineTest 13.9 */ 13.10 public class ScriptEngineTest { 13.11