| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are |
| 4 // met: |
| 5 // |
| 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided |
| 11 // with the distribution. |
| 12 // * Neither the name of Google Inc. nor the names of its |
| 13 // contributors may be used to endorse or promote products derived |
| 14 // from this software without specific prior written permission. |
| 15 // |
| 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 |
| 28 /** |
| 29 * @fileoverview Test splice, shift, unshift, slice and join on small |
| 30 * and large arrays. Some of these methods are specified such that they |
| 31 * should work on other objects too, so we test that too. |
| 32 */ |
| 33 |
| 34 var LARGE = 40000000; |
| 35 var VERYLARGE = 4000000000; |
| 36 |
| 37 // Nicer for firefox 1.5. Unless you uncomment the following two lines, |
| 38 // smjs will appear to hang on this file. |
| 39 //var LARGE = 40000; |
| 40 //var VERYLARGE = 40000; |
| 41 |
| 42 var fourhundredth = LARGE/400; |
| 43 |
| 44 function PseudoArray() { |
| 45 }; |
| 46 |
| 47 for (var use_real_arrays = 0; use_real_arrays <= 1; use_real_arrays++) { |
| 48 var poses = [0, 140, 20000, VERYLARGE]; |
| 49 var the_prototype; |
| 50 var new_function; |
| 51 var push_function; |
| 52 var concat_function; |
| 53 var slice_function; |
| 54 var splice_function; |
| 55 var splice_function_2; |
| 56 var unshift_function; |
| 57 var unshift_function_2; |
| 58 var shift_function; |
| 59 if (use_real_arrays) { |
| 60 new_function = function(length) { |
| 61 return new Array(length); |
| 62 }; |
| 63 the_prototype = Array.prototype; |
| 64 push_function = function(array, elt) { |
| 65 return array.push(elt); |
| 66 }; |
| 67 concat_function = function(array, other) { |
| 68 return array.concat(other); |
| 69 }; |
| 70 slice_function = function(array, start, len) { |
| 71 return array.slice(start, len); |
| 72 }; |
| 73 splice_function = function(array, start, len) { |
| 74 return array.splice(start, len); |
| 75 }; |
| 76 splice_function_2 = function(array, start, len, elt) { |
| 77 return array.splice(start, len, elt); |
| 78 }; |
| 79 unshift_function = function(array, elt) { |
| 80 return array.unshift(elt); |
| 81 }; |
| 82 unshift_function_2 = function(array, elt1, elt2) { |
| 83 return array.unshift(elt1, elt2); |
| 84 }; |
| 85 shift_function = function(array) { |
| 86 return array.shift(); |
| 87 }; |
| 88 } else { |
| 89 // Don't run largest size on non-arrays or we'll be here for ever. |
| 90 poses.pop(); |
| 91 new_function = function(length) { |
| 92 var obj = new PseudoArray(); |
| 93 obj.length = length; |
| 94 return obj; |
| 95 }; |
| 96 the_prototype = PseudoArray.prototype; |
| 97 push_function = function(array, elt) { |
| 98 array[array.length] = elt; |
| 99 array.length++; |
| 100 }; |
| 101 concat_function = function(array, other) { |
| 102 return Array.prototype.concat.call(array, other); |
| 103 }; |
| 104 slice_function = function(array, start, len) { |
| 105 return Array.prototype.slice.call(array, start, len); |
| 106 }; |
| 107 splice_function = function(array, start, len) { |
| 108 return Array.prototype.splice.call(array, start, len); |
| 109 }; |
| 110 splice_function_2 = function(array, start, len, elt) { |
| 111 return Array.prototype.splice.call(array, start, len, elt); |
| 112 }; |
| 113 unshift_function = function(array, elt) { |
| 114 return Array.prototype.unshift.call(array, elt); |
| 115 }; |
| 116 unshift_function_2 = function(array, elt1, elt2) { |
| 117 return Array.prototype.unshift.call(array, elt1, elt2); |
| 118 }; |
| 119 shift_function = function(array) { |
| 120 return Array.prototype.shift.call(array); |
| 121 }; |
| 122 } |
| 123 |
| 124 for (var pos_pos = 0; pos_pos < poses.length; pos_pos++) { |
| 125 var pos = poses[pos_pos]; |
| 126 if (pos > 100) { |
| 127 var a = new_function(pos); |
| 128 assertEquals(pos, a.length); |
| 129 push_function(a, 'foo'); |
| 130 assertEquals(pos + 1, a.length); |
| 131 var b = ['bar']; |
| 132 // Delete a huge number of holes. |
| 133 var c = splice_function(a, 10, pos - 20); |
| 134 assertEquals(pos - 20, c.length); |
| 135 assertEquals(21, a.length); |
| 136 } |
| 137 |
| 138 // Add a numeric property to the prototype of the array class. This |
| 139 // allows us to test some borderline stuff relative to the standard. |
| 140 the_prototype["" + (pos + 1)] = 'baz'; |
| 141 |
| 142 if (use_real_arrays) { |
| 143 // It seems quite clear from ECMAScript spec 15.4.4.5. Just call Get on |
| 144 // every integer in the range. |
| 145 // IE, Safari get this right. |
| 146 // FF, Opera get this wrong. |
| 147 var a = ['zero', ,'two']; |
| 148 if (pos == 0) { |
| 149 assertEquals("zero,baz,two", a.join(",")); |
| 150 } |
| 151 |
| 152 // Concat only applies to real arrays, unlike most of the other methods. |
| 153 var a = new_function(pos); |
| 154 push_function(a, "con"); |
| 155 assertEquals("con", a[pos]); |
| 156 assertEquals(pos + 1, a.length); |
| 157 var b = new_function(0); |
| 158 push_function(b, "cat"); |
| 159 assertEquals("cat", b[0]); |
| 160 var ab = concat_function(a, b); |
| 161 assertEquals("con", ab[pos]); |
| 162 assertEquals(pos + 2, ab.length); |
| 163 assertEquals("cat", ab[pos + 1]); |
| 164 var ba = concat_function(b, a); |
| 165 assertEquals("con", ba[pos + 1]); |
| 166 assertEquals(pos + 2, ba.length); |
| 167 assertEquals("cat", ba[0]); |
| 168 |
| 169 // Join with '' as separator. |
| 170 var join = a.join(''); |
| 171 assertEquals("con", join); |
| 172 join = b.join(''); |
| 173 assertEquals("cat", join); |
| 174 join = ab.join(''); |
| 175 assertEquals("concat", join); |
| 176 join = ba.join(''); |
| 177 assertEquals("catcon", join); |
| 178 |
| 179 var sparse = []; |
| 180 sparse[pos + 1000] = 'is '; |
| 181 sparse[pos + 271828] = 'time '; |
| 182 sparse[pos + 31415] = 'the '; |
| 183 sparse[pos + 012260199] = 'all '; |
| 184 sparse[-1] = 'foo'; |
| 185 sparse[pos + 22591927] = 'good '; |
| 186 sparse[pos + 1618033] = 'for '; |
| 187 sparse[pos + 91] = ': Now '; |
| 188 sparse[pos + 86720199] = 'men.'; |
| 189 sparse.hest = 'fisk'; |
| 190 |
| 191 assertEquals("baz: Now is the time for all good men.", sparse.join('')); |
| 192 } |
| 193 |
| 194 a = new_function(pos); |
| 195 push_function(a, 'zero'); |
| 196 push_function(a, void 0); |
| 197 push_function(a, 'two'); |
| 198 |
| 199 // Splice works differently from join. |
| 200 // IE, Safari get this wrong. |
| 201 // FF, Opera get this right. |
| 202 // 15.4.4.12 line 24 says the object itself has to have the property... |
| 203 var zero = splice_function(a, pos, 1); |
| 204 assertEquals("undefined", typeof(a[pos])); |
| 205 assertEquals("two", a[pos+1], "pos1:" + pos); |
| 206 assertEquals(pos + 2, a.length, "a length"); |
| 207 assertEquals(1, zero.length, "zero length"); |
| 208 assertEquals("zero", zero[0]); |
| 209 |
| 210 // 15.4.4.12 line 41 says the object itself has to have the property... |
| 211 a = new_function(pos); |
| 212 push_function(a, 'zero'); |
| 213 push_function(a, void 0); |
| 214 push_function(a, 'two'); |
| 215 var nothing = splice_function_2(a, pos, 0, 'minus1'); |
| 216 assertEquals("minus1", a[pos]); |
| 217 assertEquals("zero", a[pos+1]); |
| 218 assertEquals("undefined", typeof(a[pos+2]), "toot!"); |
| 219 assertEquals("two", a[pos+3], "pos3"); |
| 220 assertEquals(pos + 4, a.length); |
| 221 assertEquals(1, zero.length); |
| 222 assertEquals("zero", zero[0]); |
| 223 |
| 224 // 15.4.4.12 line 10 says the object itself has to have the property... |
| 225 a = new_function(pos); |
| 226 push_function(a, 'zero'); |
| 227 push_function(a, void 0); |
| 228 push_function(a, 'two'); |
| 229 var one = splice_function(a, pos + 1, 1); |
| 230 assertEquals("", one.join(",")); |
| 231 assertEquals(pos + 2, a.length); |
| 232 assertEquals("zero", a[pos]); |
| 233 assertEquals("two", a[pos+1]); |
| 234 |
| 235 // Set things back to the way they were. |
| 236 the_prototype[pos + 1] = undefined; |
| 237 |
| 238 // Unshift. |
| 239 var a = new_function(pos); |
| 240 push_function(a, "foo"); |
| 241 assertEquals("foo", a[pos]); |
| 242 assertEquals(pos + 1, a.length); |
| 243 unshift_function(a, "bar"); |
| 244 assertEquals("foo", a[pos+1]); |
| 245 assertEquals(pos + 2, a.length); |
| 246 assertEquals("bar", a[0]); |
| 247 unshift_function_2(a, "baz", "boo"); |
| 248 assertEquals("foo", a[pos+3]); |
| 249 assertEquals(pos + 4, a.length); |
| 250 assertEquals("baz", a[0]); |
| 251 assertEquals("boo", a[1]); |
| 252 assertEquals("bar", a[2]); |
| 253 |
| 254 // Shift. |
| 255 var baz = shift_function(a); |
| 256 assertEquals("baz", baz); |
| 257 assertEquals("boo", a[0]); |
| 258 assertEquals(pos + 3, a.length); |
| 259 assertEquals("foo", a[pos + 2]); |
| 260 |
| 261 // Slice. |
| 262 var bar = slice_function(a, 1, 0); // don't throw an exception please. |
| 263 bar = slice_function(a, 1, 2); |
| 264 assertEquals("bar", bar[0]); |
| 265 assertEquals(1, bar.length); |
| 266 assertEquals("bar", a[1]); |
| 267 |
| 268 } |
| 269 } |
| 270 |
| 271 // Lets see if performance is reasonable. |
| 272 |
| 273 var a = new Array(LARGE + 10); |
| 274 for (var i = 0; i < a.length; i += 1000) { |
| 275 a[i] = i; |
| 276 } |
| 277 |
| 278 // Take something near the end of the array. |
| 279 for (var i = 0; i < 100; i++) { |
| 280 var top = a.splice(LARGE, 5); |
| 281 assertEquals(5, top.length); |
| 282 assertEquals(LARGE, top[0]); |
| 283 assertEquals("undefined", typeof(top[1])); |
| 284 assertEquals(LARGE + 5, a.length); |
| 285 a.splice(LARGE, 0, LARGE); |
| 286 a.length = LARGE + 10; |
| 287 } |
| 288 |
| 289 var a = new Array(LARGE + 10); |
| 290 for (var i = 0; i < a.length; i += fourhundredth) { |
| 291 a[i] = i; |
| 292 } |
| 293 |
| 294 // Take something near the middle of the array. |
| 295 for (var i = 0; i < 10; i++) { |
| 296 var top = a.splice(LARGE >> 1, 5); |
| 297 assertEquals(5, top.length); |
| 298 assertEquals(LARGE >> 1, top[0]); |
| 299 assertEquals("undefined", typeof(top[1])); |
| 300 assertEquals(LARGE + 5, a.length); |
| 301 a.splice(LARGE >> 1, 0, LARGE >> 1, void 0, void 0, void 0, void 0); |
| 302 } |
| 303 |
| 304 |
| 305 // Test http://b/issue?id=1202711 |
| 306 arr = [0]; |
| 307 arr.length = 2; |
| 308 Array.prototype[1] = 1; |
| 309 assertEquals(1, arr.pop()); |
| 310 assertEquals(0, arr.pop()); |
| 311 Array.prototype[1] = undefined; |
| 312 |
| 313 // Test http://code.google.com/p/chromium/issues/detail?id=21860 |
| 314 Array.prototype.push.apply([], [1].splice(0, -(-1 % 5))); |
| OLD | NEW |