| 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 |