update V8 to TOT snapshot branch
diff --git a/test/mjsunit/array-functions-prototype-misc.js b/test/mjsunit/array-functions-prototype-misc.js
new file mode 100644
index 0000000..0543c32
--- /dev/null
+++ b/test/mjsunit/array-functions-prototype-misc.js
@@ -0,0 +1,314 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview Test splice, shift, unshift, slice and join on small
+ * and large arrays. Some of these methods are specified such that they
+ * should work on other objects too, so we test that too.
+ */
+
+var LARGE = 40000000;
+var VERYLARGE = 4000000000;
+
+// Nicer for firefox 1.5. Unless you uncomment the following two lines,
+// smjs will appear to hang on this file.
+//var LARGE = 40000;
+//var VERYLARGE = 40000;
+
+var fourhundredth = LARGE/400;
+
+function PseudoArray() {
+};
+
+for (var use_real_arrays = 0; use_real_arrays <= 1; use_real_arrays++) {
+ var poses = [0, 140, 20000, VERYLARGE];
+ var the_prototype;
+ var new_function;
+ var push_function;
+ var concat_function;
+ var slice_function;
+ var splice_function;
+ var splice_function_2;
+ var unshift_function;
+ var unshift_function_2;
+ var shift_function;
+ if (use_real_arrays) {
+ new_function = function(length) {
+ return new Array(length);
+ };
+ the_prototype = Array.prototype;
+ push_function = function(array, elt) {
+ return array.push(elt);
+ };
+ concat_function = function(array, other) {
+ return array.concat(other);
+ };
+ slice_function = function(array, start, len) {
+ return array.slice(start, len);
+ };
+ splice_function = function(array, start, len) {
+ return array.splice(start, len);
+ };
+ splice_function_2 = function(array, start, len, elt) {
+ return array.splice(start, len, elt);
+ };
+ unshift_function = function(array, elt) {
+ return array.unshift(elt);
+ };
+ unshift_function_2 = function(array, elt1, elt2) {
+ return array.unshift(elt1, elt2);
+ };
+ shift_function = function(array) {
+ return array.shift();
+ };
+ } else {
+ // Don't run largest size on non-arrays or we'll be here for ever.
+ poses.pop();
+ new_function = function(length) {
+ var obj = new PseudoArray();
+ obj.length = length;
+ return obj;
+ };
+ the_prototype = PseudoArray.prototype;
+ push_function = function(array, elt) {
+ array[array.length] = elt;
+ array.length++;
+ };
+ concat_function = function(array, other) {
+ return Array.prototype.concat.call(array, other);
+ };
+ slice_function = function(array, start, len) {
+ return Array.prototype.slice.call(array, start, len);
+ };
+ splice_function = function(array, start, len) {
+ return Array.prototype.splice.call(array, start, len);
+ };
+ splice_function_2 = function(array, start, len, elt) {
+ return Array.prototype.splice.call(array, start, len, elt);
+ };
+ unshift_function = function(array, elt) {
+ return Array.prototype.unshift.call(array, elt);
+ };
+ unshift_function_2 = function(array, elt1, elt2) {
+ return Array.prototype.unshift.call(array, elt1, elt2);
+ };
+ shift_function = function(array) {
+ return Array.prototype.shift.call(array);
+ };
+ }
+
+ for (var pos_pos = 0; pos_pos < poses.length; pos_pos++) {
+ var pos = poses[pos_pos];
+ if (pos > 100) {
+ var a = new_function(pos);
+ assertEquals(pos, a.length);
+ push_function(a, 'foo');
+ assertEquals(pos + 1, a.length);
+ var b = ['bar'];
+ // Delete a huge number of holes.
+ var c = splice_function(a, 10, pos - 20);
+ assertEquals(pos - 20, c.length);
+ assertEquals(21, a.length);
+ }
+
+ // Add a numeric property to the prototype of the array class. This
+ // allows us to test some borderline stuff relative to the standard.
+ the_prototype["" + (pos + 1)] = 'baz';
+
+ if (use_real_arrays) {
+ // It seems quite clear from ECMAScript spec 15.4.4.5. Just call Get on
+ // every integer in the range.
+ // IE, Safari get this right.
+ // FF, Opera get this wrong.
+ var a = ['zero', ,'two'];
+ if (pos == 0) {
+ assertEquals("zero,baz,two", a.join(","));
+ }
+
+ // Concat only applies to real arrays, unlike most of the other methods.
+ var a = new_function(pos);
+ push_function(a, "con");
+ assertEquals("con", a[pos]);
+ assertEquals(pos + 1, a.length);
+ var b = new_function(0);
+ push_function(b, "cat");
+ assertEquals("cat", b[0]);
+ var ab = concat_function(a, b);
+ assertEquals("con", ab[pos]);
+ assertEquals(pos + 2, ab.length);
+ assertEquals("cat", ab[pos + 1]);
+ var ba = concat_function(b, a);
+ assertEquals("con", ba[pos + 1]);
+ assertEquals(pos + 2, ba.length);
+ assertEquals("cat", ba[0]);
+
+ // Join with '' as separator.
+ var join = a.join('');
+ assertEquals("con", join);
+ join = b.join('');
+ assertEquals("cat", join);
+ join = ab.join('');
+ assertEquals("concat", join);
+ join = ba.join('');
+ assertEquals("catcon", join);
+
+ var sparse = [];
+ sparse[pos + 1000] = 'is ';
+ sparse[pos + 271828] = 'time ';
+ sparse[pos + 31415] = 'the ';
+ sparse[pos + 012260199] = 'all ';
+ sparse[-1] = 'foo';
+ sparse[pos + 22591927] = 'good ';
+ sparse[pos + 1618033] = 'for ';
+ sparse[pos + 91] = ': Now ';
+ sparse[pos + 86720199] = 'men.';
+ sparse.hest = 'fisk';
+
+ assertEquals("baz: Now is the time for all good men.", sparse.join(''));
+ }
+
+ a = new_function(pos);
+ push_function(a, 'zero');
+ push_function(a, void 0);
+ push_function(a, 'two');
+
+ // Splice works differently from join.
+ // IE, Safari get this wrong.
+ // FF, Opera get this right.
+ // 15.4.4.12 line 24 says the object itself has to have the property...
+ var zero = splice_function(a, pos, 1);
+ assertEquals("undefined", typeof(a[pos]));
+ assertEquals("two", a[pos+1], "pos1:" + pos);
+ assertEquals(pos + 2, a.length, "a length");
+ assertEquals(1, zero.length, "zero length");
+ assertEquals("zero", zero[0]);
+
+ // 15.4.4.12 line 41 says the object itself has to have the property...
+ a = new_function(pos);
+ push_function(a, 'zero');
+ push_function(a, void 0);
+ push_function(a, 'two');
+ var nothing = splice_function_2(a, pos, 0, 'minus1');
+ assertEquals("minus1", a[pos]);
+ assertEquals("zero", a[pos+1]);
+ assertEquals("undefined", typeof(a[pos+2]), "toot!");
+ assertEquals("two", a[pos+3], "pos3");
+ assertEquals(pos + 4, a.length);
+ assertEquals(1, zero.length);
+ assertEquals("zero", zero[0]);
+
+ // 15.4.4.12 line 10 says the object itself has to have the property...
+ a = new_function(pos);
+ push_function(a, 'zero');
+ push_function(a, void 0);
+ push_function(a, 'two');
+ var one = splice_function(a, pos + 1, 1);
+ assertEquals("", one.join(","));
+ assertEquals(pos + 2, a.length);
+ assertEquals("zero", a[pos]);
+ assertEquals("two", a[pos+1]);
+
+ // Set things back to the way they were.
+ the_prototype[pos + 1] = undefined;
+
+ // Unshift.
+ var a = new_function(pos);
+ push_function(a, "foo");
+ assertEquals("foo", a[pos]);
+ assertEquals(pos + 1, a.length);
+ unshift_function(a, "bar");
+ assertEquals("foo", a[pos+1]);
+ assertEquals(pos + 2, a.length);
+ assertEquals("bar", a[0]);
+ unshift_function_2(a, "baz", "boo");
+ assertEquals("foo", a[pos+3]);
+ assertEquals(pos + 4, a.length);
+ assertEquals("baz", a[0]);
+ assertEquals("boo", a[1]);
+ assertEquals("bar", a[2]);
+
+ // Shift.
+ var baz = shift_function(a);
+ assertEquals("baz", baz);
+ assertEquals("boo", a[0]);
+ assertEquals(pos + 3, a.length);
+ assertEquals("foo", a[pos + 2]);
+
+ // Slice.
+ var bar = slice_function(a, 1, 0); // don't throw an exception please.
+ bar = slice_function(a, 1, 2);
+ assertEquals("bar", bar[0]);
+ assertEquals(1, bar.length);
+ assertEquals("bar", a[1]);
+
+ }
+}
+
+// Lets see if performance is reasonable.
+
+var a = new Array(LARGE + 10);
+for (var i = 0; i < a.length; i += 1000) {
+ a[i] = i;
+}
+
+// Take something near the end of the array.
+for (var i = 0; i < 100; i++) {
+ var top = a.splice(LARGE, 5);
+ assertEquals(5, top.length);
+ assertEquals(LARGE, top[0]);
+ assertEquals("undefined", typeof(top[1]));
+ assertEquals(LARGE + 5, a.length);
+ a.splice(LARGE, 0, LARGE);
+ a.length = LARGE + 10;
+}
+
+var a = new Array(LARGE + 10);
+for (var i = 0; i < a.length; i += fourhundredth) {
+ a[i] = i;
+}
+
+// Take something near the middle of the array.
+for (var i = 0; i < 10; i++) {
+ var top = a.splice(LARGE >> 1, 5);
+ assertEquals(5, top.length);
+ assertEquals(LARGE >> 1, top[0]);
+ assertEquals("undefined", typeof(top[1]));
+ assertEquals(LARGE + 5, a.length);
+ a.splice(LARGE >> 1, 0, LARGE >> 1, void 0, void 0, void 0, void 0);
+}
+
+
+// Test http://b/issue?id=1202711
+arr = [0];
+arr.length = 2;
+Array.prototype[1] = 1;
+assertEquals(1, arr.pop());
+assertEquals(0, arr.pop());
+Array.prototype[1] = undefined;
+
+// Test http://code.google.com/p/chromium/issues/detail?id=21860
+Array.prototype.push.apply([], [1].splice(0, -(-1 % 5)));
diff --git a/test/mjsunit/array-shift.js b/test/mjsunit/array-shift.js
new file mode 100644
index 0000000..d985b31
--- /dev/null
+++ b/test/mjsunit/array-shift.js
@@ -0,0 +1,71 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Check that shifting array of holes keeps it as array of holes
+(function() {
+ var array = new Array(10);
+ array.shift();
+ assertFalse(0 in array);
+})();
+
+// Now check the case with array of holes and some elements on prototype.
+(function() {
+ var len = 9;
+ var array = new Array(len);
+ Array.prototype[3] = "@3";
+ Array.prototype[7] = "@7";
+
+ assertEquals(len, array.length);
+ for (var i = 0; i < array.length; i++) {
+ assertEquals(array[i], Array.prototype[i]);
+ }
+
+ array.shift();
+
+ assertEquals(len - 1, array.length);
+ // Note that shift copies values from prototype into the array.
+ assertEquals(array[2], Array.prototype[3]);
+ assertTrue(array.hasOwnProperty(2));
+
+ assertEquals(array[6], Array.prototype[7]);
+ assertTrue(array.hasOwnProperty(6));
+
+ // ... but keeps the rest as holes:
+ Array.prototype[5] = "@5";
+ assertEquals(array[5], Array.prototype[5]);
+ assertFalse(array.hasOwnProperty(5));
+
+ assertEquals(array[3], Array.prototype[3]);
+ assertFalse(array.hasOwnProperty(3));
+
+ assertEquals(array[7], Array.prototype[7]);
+ assertFalse(array.hasOwnProperty(7));
+
+ assertTrue(delete Array.prototype[3]);
+ assertTrue(delete Array.prototype[5]);
+ assertTrue(delete Array.prototype[7]);
+})();
diff --git a/test/mjsunit/array-slice.js b/test/mjsunit/array-slice.js
new file mode 100644
index 0000000..c993a07
--- /dev/null
+++ b/test/mjsunit/array-slice.js
@@ -0,0 +1,162 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Check that slicing array of holes keeps it as array of holes
+(function() {
+ var array = new Array(10);
+ for (var i = 0; i < 7; i++) {
+ var sliced = array.slice();
+ assertEquals(array.length, sliced.length);
+ assertFalse(0 in sliced);
+ }
+})();
+
+
+// Check various forms of arguments omission.
+(function() {
+ var array = new Array(7);
+
+ for (var i = 0; i < 7; i++) {
+ assertEquals(array, array.slice());
+ assertEquals(array, array.slice(0));
+ assertEquals(array, array.slice(undefined));
+ assertEquals(array, array.slice("foobar"));
+ assertEquals(array, array.slice(undefined, undefined));
+ }
+})();
+
+
+// Check variants of negatives and positive indices.
+(function() {
+ var array = new Array(7);
+
+ for (var i = 0; i < 7; i++) {
+ assertEquals(7, array.slice(-100).length);
+ assertEquals(3, array.slice(-3).length);
+ assertEquals(3, array.slice(4).length);
+ assertEquals(1, array.slice(6).length);
+ assertEquals(0, array.slice(7).length);
+ assertEquals(0, array.slice(8).length);
+ assertEquals(0, array.slice(100).length);
+
+ assertEquals(0, array.slice(0, -100).length);
+ assertEquals(4, array.slice(0, -3).length);
+ assertEquals(4, array.slice(0, 4).length);
+ assertEquals(6, array.slice(0, 6).length);
+ assertEquals(7, array.slice(0, 7).length);
+ assertEquals(7, array.slice(0, 8).length);
+ assertEquals(7, array.slice(0, 100).length);
+
+ // Some exotic cases.
+
+ obj = { toString: function() { throw 'Exception'; } };
+
+ // More than 2 arguments:
+ assertEquals(7, array.slice(0, 7, obj, null, undefined).length);
+
+ // Custom conversion:
+ assertEquals(1, array.slice({valueOf: function() { return 1; }},
+ {toString: function() { return 2; }}).length);
+
+ // Throwing an exception in conversion:
+ try {
+ assertEquals(7, array.slice(0, obj).length);
+ throw 'Should have thrown';
+ } catch (e) {
+ assertEquals('Exception', e);
+ }
+ }
+})();
+
+
+// Nasty: modify the array in ToInteger.
+(function() {
+ var array = [];
+ var expected = []
+ bad_guy = { valueOf: function() { array.push(array.length); return -1; } };
+
+ for (var i = 0; i < 13; i++) {
+ var sliced = array.slice(bad_guy);
+ expected.push(i);
+ assertEquals(expected, array);
+ // According to the spec (15.4.4.10), length is calculated before
+ // performing ToInteger on arguments.
+ if (i == 0) {
+ assertEquals([], sliced); // Length was 0, nothing to get.
+ } else {
+ // Actually out of array [0..i] we get [i - 1] as length is i.
+ assertEquals([i - 1], sliced);
+ }
+ }
+})();
+
+
+// Now check the case with array of holes and some elements on prototype.
+(function() {
+ var len = 9;
+ var array = new Array(len);
+
+ var at3 = "@3";
+ var at7 = "@7";
+
+ for (var i = 0; i < 7; i++) {
+ Array.prototype[3] = at3;
+ Array.prototype[7] = at7;
+
+ assertEquals(len, array.length);
+ for (var i = 0; i < array.length; i++) {
+ assertEquals(array[i], Array.prototype[i]);
+ }
+
+ var sliced = array.slice();
+
+ assertEquals(len, sliced.length);
+
+ assertTrue(delete Array.prototype[3]);
+ assertTrue(delete Array.prototype[7]);
+
+ // Note that slice copies values from prototype into the array.
+ assertEquals(array[3], undefined);
+ assertFalse(array.hasOwnProperty(3));
+ assertEquals(sliced[3], at3);
+ assertTrue(sliced.hasOwnProperty(3));
+
+ assertEquals(array[7], undefined);
+ assertFalse(array.hasOwnProperty(7));
+ assertEquals(sliced[7], at7);
+ assertTrue(sliced.hasOwnProperty(7));
+
+ // ... but keeps the rest as holes:
+ Array.prototype[5] = "@5";
+ assertEquals(array[5], Array.prototype[5]);
+ assertFalse(array.hasOwnProperty(5));
+ assertEquals(sliced[5], Array.prototype[5]);
+ assertFalse(sliced.hasOwnProperty(5));
+
+ assertTrue(delete Array.prototype[5]);
+ }
+})();
diff --git a/test/mjsunit/array-splice.js b/test/mjsunit/array-splice.js
index 0543c32..18f81fe 100644
--- a/test/mjsunit/array-splice.js
+++ b/test/mjsunit/array-splice.js
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -25,290 +25,265 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-/**
- * @fileoverview Test splice, shift, unshift, slice and join on small
- * and large arrays. Some of these methods are specified such that they
- * should work on other objects too, so we test that too.
- */
+// Check that splicing array of holes keeps it as array of holes
+(function() {
+ for (var i = 0; i < 7; i++) {
+ var array = new Array(10);
+ var spliced = array.splice(1, 1, 'one', 'two');
+ assertEquals(1, spliced.length);
+ assertFalse(0 in spliced);
-var LARGE = 40000000;
-var VERYLARGE = 4000000000;
-
-// Nicer for firefox 1.5. Unless you uncomment the following two lines,
-// smjs will appear to hang on this file.
-//var LARGE = 40000;
-//var VERYLARGE = 40000;
-
-var fourhundredth = LARGE/400;
-
-function PseudoArray() {
-};
-
-for (var use_real_arrays = 0; use_real_arrays <= 1; use_real_arrays++) {
- var poses = [0, 140, 20000, VERYLARGE];
- var the_prototype;
- var new_function;
- var push_function;
- var concat_function;
- var slice_function;
- var splice_function;
- var splice_function_2;
- var unshift_function;
- var unshift_function_2;
- var shift_function;
- if (use_real_arrays) {
- new_function = function(length) {
- return new Array(length);
- };
- the_prototype = Array.prototype;
- push_function = function(array, elt) {
- return array.push(elt);
- };
- concat_function = function(array, other) {
- return array.concat(other);
- };
- slice_function = function(array, start, len) {
- return array.slice(start, len);
- };
- splice_function = function(array, start, len) {
- return array.splice(start, len);
- };
- splice_function_2 = function(array, start, len, elt) {
- return array.splice(start, len, elt);
- };
- unshift_function = function(array, elt) {
- return array.unshift(elt);
- };
- unshift_function_2 = function(array, elt1, elt2) {
- return array.unshift(elt1, elt2);
- };
- shift_function = function(array) {
- return array.shift();
- };
- } else {
- // Don't run largest size on non-arrays or we'll be here for ever.
- poses.pop();
- new_function = function(length) {
- var obj = new PseudoArray();
- obj.length = length;
- return obj;
- };
- the_prototype = PseudoArray.prototype;
- push_function = function(array, elt) {
- array[array.length] = elt;
- array.length++;
- };
- concat_function = function(array, other) {
- return Array.prototype.concat.call(array, other);
- };
- slice_function = function(array, start, len) {
- return Array.prototype.slice.call(array, start, len);
- };
- splice_function = function(array, start, len) {
- return Array.prototype.splice.call(array, start, len);
- };
- splice_function_2 = function(array, start, len, elt) {
- return Array.prototype.splice.call(array, start, len, elt);
- };
- unshift_function = function(array, elt) {
- return Array.prototype.unshift.call(array, elt);
- };
- unshift_function_2 = function(array, elt1, elt2) {
- return Array.prototype.unshift.call(array, elt1, elt2);
- };
- shift_function = function(array) {
- return Array.prototype.shift.call(array);
- };
+ assertEquals(11, array.length);
+ assertFalse(0 in array);
+ assertTrue(1 in array);
+ assertTrue(2 in array);
+ assertFalse(3 in array);
}
+})();
- for (var pos_pos = 0; pos_pos < poses.length; pos_pos++) {
- var pos = poses[pos_pos];
- if (pos > 100) {
- var a = new_function(pos);
- assertEquals(pos, a.length);
- push_function(a, 'foo');
- assertEquals(pos + 1, a.length);
- var b = ['bar'];
- // Delete a huge number of holes.
- var c = splice_function(a, 10, pos - 20);
- assertEquals(pos - 20, c.length);
- assertEquals(21, a.length);
+
+// Check various forms of arguments omission.
+(function() {
+ var array;
+ for (var i = 0; i < 7; i++) {
+ // SpiderMonkey and JSC return undefined in the case where no
+ // arguments are given instead of using the implicit undefined
+ // arguments. This does not follow ECMA-262, but we do the same for
+ // compatibility.
+ // TraceMonkey follows ECMA-262 though.
+ array = [1, 2, 3]
+ assertEquals(undefined, array.splice());
+ assertEquals([1, 2, 3], array);
+
+ // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
+ // given differently from when an undefined delete count is given.
+ // This does not follow ECMA-262, but we do the same for
+ // compatibility.
+ array = [1, 2, 3]
+ assertEquals([1, 2, 3], array.splice(0));
+ assertEquals([], array);
+
+ array = [1, 2, 3]
+ assertEquals([1, 2, 3], array.splice(undefined));
+ assertEquals([], array);
+
+ array = [1, 2, 3]
+ assertEquals([1, 2, 3], array.splice("foobar"));
+ assertEquals([], array);
+
+ array = [1, 2, 3]
+ assertEquals([], array.splice(undefined, undefined));
+ assertEquals([1, 2, 3], array);
+
+ array = [1, 2, 3]
+ assertEquals([], array.splice("foobar", undefined));
+ assertEquals([1, 2, 3], array);
+
+ array = [1, 2, 3]
+ assertEquals([], array.splice(undefined, "foobar"));
+ assertEquals([1, 2, 3], array);
+
+ array = [1, 2, 3]
+ assertEquals([], array.splice("foobar", "foobar"));
+ assertEquals([1, 2, 3], array);
+ }
+})();
+
+
+// Check variants of negatives and positive indices.
+(function() {
+ var array, spliced;
+ for (var i = 0; i < 7; i++) {
+ array = [1, 2, 3, 4, 5, 6, 7];
+ spliced = array.splice(-100);
+ assertEquals([], array);
+ assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
+
+ array = [1, 2, 3, 4, 5, 6, 7];
+ spliced = array.splice(-3);
+ assertEquals([1, 2, 3, 4], array);
+ assertEquals([5, 6, 7], spliced);
+
+ array = [1, 2, 3, 4, 5, 6, 7];
+ spliced = array.splice(4);
+ assertEquals([1, 2, 3, 4], array);
+ assertEquals([5, 6, 7], spliced);
+
+ array = [1, 2, 3, 4, 5, 6, 7];
+ spliced = array.splice(6);
+ assertEquals([1, 2, 3, 4, 5, 6], array);
+ assertEquals([7], spliced);
+
+ array = [1, 2, 3, 4, 5, 6, 7];
+ spliced = array.splice(7);
+ assertEquals([1, 2, 3, 4, 5, 6, 7], array);
+ assertEquals([], spliced);
+
+ array = [1, 2, 3, 4, 5, 6, 7];
+ spliced = array.splice(8);
+ assertEquals([1, 2, 3, 4, 5, 6, 7], array);
+ assertEquals([], spliced);
+
+ array = [1, 2, 3, 4, 5, 6, 7];
+ spliced = array.splice(100);
+ assertEquals([1, 2, 3, 4, 5, 6, 7], array);
+ assertEquals([], spliced);
+
+ array = [1, 2, 3, 4, 5, 6, 7];
+ spliced = array.splice(0, -100);
+ assertEquals([1, 2, 3, 4, 5, 6, 7], array);
+ assertEquals([], spliced);
+
+ array = [1, 2, 3, 4, 5, 6, 7];
+ spliced = array.splice(0, -3);
+ assertEquals([1, 2, 3, 4, 5, 6, 7], array);
+ assertEquals([], spliced);
+
+ array = [1, 2, 3, 4, 5, 6, 7];
+ spliced = array.splice(0, 4);
+ assertEquals([5, 6, 7], array);
+ assertEquals([1, 2, 3, 4], spliced);
+
+ array = [1, 2, 3, 4, 5, 6, 7];
+ spliced = array.splice(0, 6);
+ assertEquals([7], array);
+ assertEquals([1, 2, 3, 4, 5, 6], spliced);
+
+ array = [1, 2, 3, 4, 5, 6, 7];
+ spliced = array.splice(0, 7);
+ assertEquals([], array);
+ assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
+
+ array = [1, 2, 3, 4, 5, 6, 7];
+ spliced = array.splice(0, 8);
+ assertEquals([], array);
+ assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
+
+ array = [1, 2, 3, 4, 5, 6, 7];
+ spliced = array.splice(0, 100);
+ assertEquals([], array);
+ assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
+
+ // Some exotic cases.
+ obj = { toString: function() { throw 'Exception'; } };
+
+ // Throwing an exception in conversion:
+ try {
+ [1, 2, 3].splice(obj, 3);
+ throw 'Should have thrown';
+ } catch (e) {
+ assertEquals('Exception', e);
}
- // Add a numeric property to the prototype of the array class. This
- // allows us to test some borderline stuff relative to the standard.
- the_prototype["" + (pos + 1)] = 'baz';
-
- if (use_real_arrays) {
- // It seems quite clear from ECMAScript spec 15.4.4.5. Just call Get on
- // every integer in the range.
- // IE, Safari get this right.
- // FF, Opera get this wrong.
- var a = ['zero', ,'two'];
- if (pos == 0) {
- assertEquals("zero,baz,two", a.join(","));
- }
-
- // Concat only applies to real arrays, unlike most of the other methods.
- var a = new_function(pos);
- push_function(a, "con");
- assertEquals("con", a[pos]);
- assertEquals(pos + 1, a.length);
- var b = new_function(0);
- push_function(b, "cat");
- assertEquals("cat", b[0]);
- var ab = concat_function(a, b);
- assertEquals("con", ab[pos]);
- assertEquals(pos + 2, ab.length);
- assertEquals("cat", ab[pos + 1]);
- var ba = concat_function(b, a);
- assertEquals("con", ba[pos + 1]);
- assertEquals(pos + 2, ba.length);
- assertEquals("cat", ba[0]);
-
- // Join with '' as separator.
- var join = a.join('');
- assertEquals("con", join);
- join = b.join('');
- assertEquals("cat", join);
- join = ab.join('');
- assertEquals("concat", join);
- join = ba.join('');
- assertEquals("catcon", join);
-
- var sparse = [];
- sparse[pos + 1000] = 'is ';
- sparse[pos + 271828] = 'time ';
- sparse[pos + 31415] = 'the ';
- sparse[pos + 012260199] = 'all ';
- sparse[-1] = 'foo';
- sparse[pos + 22591927] = 'good ';
- sparse[pos + 1618033] = 'for ';
- sparse[pos + 91] = ': Now ';
- sparse[pos + 86720199] = 'men.';
- sparse.hest = 'fisk';
-
- assertEquals("baz: Now is the time for all good men.", sparse.join(''));
+ try {
+ [1, 2, 3].splice(0, obj, 3);
+ throw 'Should have thrown';
+ } catch (e) {
+ assertEquals('Exception', e);
}
- a = new_function(pos);
- push_function(a, 'zero');
- push_function(a, void 0);
- push_function(a, 'two');
+ array = [1, 2, 3];
+ array.splice(0, 3, obj);
+ assertEquals(1, array.length);
- // Splice works differently from join.
- // IE, Safari get this wrong.
- // FF, Opera get this right.
- // 15.4.4.12 line 24 says the object itself has to have the property...
- var zero = splice_function(a, pos, 1);
- assertEquals("undefined", typeof(a[pos]));
- assertEquals("two", a[pos+1], "pos1:" + pos);
- assertEquals(pos + 2, a.length, "a length");
- assertEquals(1, zero.length, "zero length");
- assertEquals("zero", zero[0]);
-
- // 15.4.4.12 line 41 says the object itself has to have the property...
- a = new_function(pos);
- push_function(a, 'zero');
- push_function(a, void 0);
- push_function(a, 'two');
- var nothing = splice_function_2(a, pos, 0, 'minus1');
- assertEquals("minus1", a[pos]);
- assertEquals("zero", a[pos+1]);
- assertEquals("undefined", typeof(a[pos+2]), "toot!");
- assertEquals("two", a[pos+3], "pos3");
- assertEquals(pos + 4, a.length);
- assertEquals(1, zero.length);
- assertEquals("zero", zero[0]);
-
- // 15.4.4.12 line 10 says the object itself has to have the property...
- a = new_function(pos);
- push_function(a, 'zero');
- push_function(a, void 0);
- push_function(a, 'two');
- var one = splice_function(a, pos + 1, 1);
- assertEquals("", one.join(","));
- assertEquals(pos + 2, a.length);
- assertEquals("zero", a[pos]);
- assertEquals("two", a[pos+1]);
-
- // Set things back to the way they were.
- the_prototype[pos + 1] = undefined;
-
- // Unshift.
- var a = new_function(pos);
- push_function(a, "foo");
- assertEquals("foo", a[pos]);
- assertEquals(pos + 1, a.length);
- unshift_function(a, "bar");
- assertEquals("foo", a[pos+1]);
- assertEquals(pos + 2, a.length);
- assertEquals("bar", a[0]);
- unshift_function_2(a, "baz", "boo");
- assertEquals("foo", a[pos+3]);
- assertEquals(pos + 4, a.length);
- assertEquals("baz", a[0]);
- assertEquals("boo", a[1]);
- assertEquals("bar", a[2]);
-
- // Shift.
- var baz = shift_function(a);
- assertEquals("baz", baz);
- assertEquals("boo", a[0]);
- assertEquals(pos + 3, a.length);
- assertEquals("foo", a[pos + 2]);
-
- // Slice.
- var bar = slice_function(a, 1, 0); // don't throw an exception please.
- bar = slice_function(a, 1, 2);
- assertEquals("bar", bar[0]);
- assertEquals(1, bar.length);
- assertEquals("bar", a[1]);
-
+ // Custom conversion:
+ array = [1, 2, 3];
+ spliced = array.splice({valueOf: function() { return 1; }},
+ {toString: function() { return 2; }},
+ 'one', 'two');
+ assertEquals([2, 3], spliced);
+ assertEquals([1, 'one', 'two'], array);
}
-}
-
-// Lets see if performance is reasonable.
-
-var a = new Array(LARGE + 10);
-for (var i = 0; i < a.length; i += 1000) {
- a[i] = i;
-}
-
-// Take something near the end of the array.
-for (var i = 0; i < 100; i++) {
- var top = a.splice(LARGE, 5);
- assertEquals(5, top.length);
- assertEquals(LARGE, top[0]);
- assertEquals("undefined", typeof(top[1]));
- assertEquals(LARGE + 5, a.length);
- a.splice(LARGE, 0, LARGE);
- a.length = LARGE + 10;
-}
-
-var a = new Array(LARGE + 10);
-for (var i = 0; i < a.length; i += fourhundredth) {
- a[i] = i;
-}
-
-// Take something near the middle of the array.
-for (var i = 0; i < 10; i++) {
- var top = a.splice(LARGE >> 1, 5);
- assertEquals(5, top.length);
- assertEquals(LARGE >> 1, top[0]);
- assertEquals("undefined", typeof(top[1]));
- assertEquals(LARGE + 5, a.length);
- a.splice(LARGE >> 1, 0, LARGE >> 1, void 0, void 0, void 0, void 0);
-}
+})();
-// Test http://b/issue?id=1202711
-arr = [0];
-arr.length = 2;
-Array.prototype[1] = 1;
-assertEquals(1, arr.pop());
-assertEquals(0, arr.pop());
-Array.prototype[1] = undefined;
+// Nasty: modify the array in ToInteger.
+(function() {
+ var array = [];
+ var spliced;
-// Test http://code.google.com/p/chromium/issues/detail?id=21860
-Array.prototype.push.apply([], [1].splice(0, -(-1 % 5)));
+ for (var i = 0; i < 13; i++) {
+ bad_start = { valueOf: function() { array.push(2*i); return -1; } };
+ bad_count = { valueOf: function() { array.push(2*i + 1); return 1; } };
+ spliced = array.splice(bad_start, bad_count);
+ // According to the spec (15.4.4.12), length is calculated before
+ // performing ToInteger on arguments. However, v8 ignores elements
+ // we add while converting, so we need corrective pushes.
+ array.push(2*i); array.push(2*i + 1);
+ if (i == 0) {
+ assertEquals([], spliced); // Length was 0, nothing to get.
+ assertEquals([0, 1], array);
+ } else {
+ // When we start splice, array is [0 .. 2*i - 1], so we get
+ // as a result [2*i], this element is removed from the array,
+ // but [2 * i, 2 * i + 1] are added.
+ assertEquals([2 * i - 1], spliced);
+ assertEquals(2 * i, array[i]);
+ assertEquals(2 * i + 1, array[i + 1]);
+ }
+ }
+})();
+
+
+// Now check the case with array of holes and some elements on prototype.
+(function() {
+ var len = 9;
+
+ var at3 = "@3";
+ var at7 = "@7";
+
+ for (var i = 0; i < 7; i++) {
+ var array = new Array(len);
+ Array.prototype[3] = at3;
+ Array.prototype[7] = at7;
+
+ var spliced = array.splice(2, 2, 'one', undefined, 'two');
+
+ // Second hole (at index 3) of array turns into
+ // value of Array.prototype[3] while copying.
+ assertEquals([, at3], spliced);
+ assertEquals([, , 'one', undefined, 'two', , , at7, at7, ,], array);
+
+ // ... but array[7] is actually a hole:
+ assertTrue(delete Array.prototype[7]);
+ assertEquals(undefined, array[7]);
+
+ // and now check hasOwnProperty
+ assertFalse(array.hasOwnProperty(0));
+ assertFalse(array.hasOwnProperty(1));
+ assertTrue(array.hasOwnProperty(2));
+ assertTrue(array.hasOwnProperty(3));
+ assertTrue(array.hasOwnProperty(4));
+ assertFalse(array.hasOwnProperty(5));
+ assertFalse(array.hasOwnProperty(6));
+ assertFalse(array.hasOwnProperty(7));
+ assertTrue(array.hasOwnProperty(8));
+ assertFalse(array.hasOwnProperty(9));
+
+ // and now check couple of indices above length.
+ assertFalse(array.hasOwnProperty(10));
+ assertFalse(array.hasOwnProperty(15));
+ assertFalse(array.hasOwnProperty(31));
+ assertFalse(array.hasOwnProperty(63));
+ assertFalse(array.hasOwnProperty(2 << 32 - 1));
+ }
+})();
+
+
+// Check the behaviour when approaching maximal values for length.
+(function() {
+ for (var i = 0; i < 7; i++) {
+ try {
+ new Array((1 << 32) - 3).splice(-1, 0, 1, 2, 3, 4, 5);
+ throw 'Should have thrown RangeError';
+ } catch (e) {
+ assertTrue(e instanceof RangeError);
+ }
+
+ // Check smi boundary
+ var bigNum = (1 << 30) - 3;
+ var array = new Array(bigNum);
+ array.splice(-1, 0, 1, 2, 3, 4, 5, 6, 7);
+ assertEquals(bigNum + 7, array.length);
+ }
+})();
diff --git a/test/mjsunit/array-unshift.js b/test/mjsunit/array-unshift.js
new file mode 100644
index 0000000..06a78a7
--- /dev/null
+++ b/test/mjsunit/array-unshift.js
@@ -0,0 +1,132 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Check that unshifting array of holes keeps the original array
+// as array of holes
+(function() {
+ var array = new Array(10);
+ assertEquals(13, array.unshift('1st', '2ns', '3rd'));
+ assertTrue(0 in array);
+ assertTrue(1 in array);
+ assertTrue(2 in array);
+ assertFalse(3 in array);
+})();
+
+
+// Check that unshif with no args has a side-effect of
+// feeling the holes with elements from the prototype
+// (if present, of course)
+(function() {
+ var len = 3;
+ var array = new Array(len);
+
+ var at0 = '@0';
+ var at2 = '@2';
+
+ Array.prototype[0] = at0;
+ Array.prototype[2] = at2;
+
+ // array owns nothing...
+ assertFalse(array.hasOwnProperty(0));
+ assertFalse(array.hasOwnProperty(1));
+ assertFalse(array.hasOwnProperty(2));
+
+ // ... but sees values from Array.prototype
+ assertEquals(array[0], at0);
+ assertEquals(array[1], undefined);
+ assertEquals(array[2], at2);
+
+ assertEquals(len, array.unshift());
+
+ assertTrue(delete Array.prototype[0]);
+ assertTrue(delete Array.prototype[2]);
+
+ // unshift makes array own 0 and 2...
+ assertTrue(array.hasOwnProperty(0));
+ assertFalse(array.hasOwnProperty(1));
+ assertTrue(array.hasOwnProperty(2));
+
+ // ... so they are not affected be delete.
+ assertEquals(array[0], at0);
+ assertEquals(array[1], undefined);
+ assertEquals(array[2], at2);
+})();
+
+
+// Now check the case with array of holes and some elements on prototype.
+(function() {
+ var len = 9;
+ var array = new Array(len);
+ Array.prototype[3] = "@3";
+ Array.prototype[7] = "@7";
+
+ assertEquals(len, array.length);
+ for (var i = 0; i < array.length; i++) {
+ assertEquals(array[i], Array.prototype[i]);
+ }
+
+ assertEquals(len + 1, array.unshift('head'));
+
+ assertEquals(len + 1, array.length);
+ // Note that unshift copies values from prototype into the array.
+ assertEquals(array[4], Array.prototype[3]);
+ assertTrue(array.hasOwnProperty(4));
+
+ assertEquals(array[8], Array.prototype[7]);
+ assertTrue(array.hasOwnProperty(8));
+
+ // ... but keeps the rest as holes:
+ Array.prototype[5] = "@5";
+ assertEquals(array[5], Array.prototype[5]);
+ assertFalse(array.hasOwnProperty(5));
+
+ assertEquals(array[3], Array.prototype[3]);
+ assertFalse(array.hasOwnProperty(3));
+
+ assertEquals(array[7], Array.prototype[7]);
+ assertFalse(array.hasOwnProperty(7));
+
+ assertTrue(delete Array.prototype[3]);
+ assertTrue(delete Array.prototype[5]);
+ assertTrue(delete Array.prototype[7]);
+})();
+
+// Check the behaviour when approaching maximal values for length.
+(function() {
+ for (var i = 0; i < 7; i++) {
+ try {
+ new Array((1 << 32) - 3).unshift(1, 2, 3, 4, 5);
+ throw 'Should have thrown RangeError';
+ } catch (e) {
+ assertTrue(e instanceof RangeError);
+ }
+
+ // Check smi boundary
+ var bigNum = (1 << 30) - 3;
+ assertEquals(bigNum + 7, new Array(bigNum).unshift(1, 2, 3, 4, 5, 6, 7));
+ }
+})();
diff --git a/test/mjsunit/bugs/618.js b/test/mjsunit/bugs/618.js
new file mode 100644
index 0000000..afa9929
--- /dev/null
+++ b/test/mjsunit/bugs/618.js
@@ -0,0 +1,86 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Simple class using inline constructor.
+function C1() {
+ this.x = 23;
+};
+var c1 = new C1();
+assertEquals(23, c1.x);
+assertEquals("undefined", typeof c1.y);
+
+// Add setter somewhere on the prototype chain after having constructed the
+// first instance.
+C1.prototype = { set x(value) { this.y = 23; } };
+var c1 = new C1();
+assertEquals("undefined", typeof c1.x);
+assertEquals(23, c1.y);
+
+// Simple class using inline constructor.
+function C2() {
+ this.x = 23;
+};
+var c2 = new C2();
+assertEquals(23, c2.x);
+assertEquals("undefined", typeof c2.y);
+
+// Add setter somewhere on the prototype chain after having constructed the
+// first instance.
+C2.prototype.__proto__ = { set x(value) { this.y = 23; } };
+var c2 = new C2();
+assertEquals("undefined", typeof c2.x);
+assertEquals(23, c2.y);
+
+// Simple class using inline constructor.
+function C3() {
+ this.x = 23;
+};
+var c3 = new C3();
+assertEquals(23, c3.x);
+assertEquals("undefined", typeof c3.y);
+
+// Add setter somewhere on the prototype chain after having constructed the
+// first instance.
+C3.prototype.__defineSetter__('x', function(value) { this.y = 23; });
+var c3 = new C3();
+assertEquals("undefined", typeof c3.x);
+assertEquals(23, c3.y);
+
+// Simple class using inline constructor.
+function C4() {
+ this.x = 23;
+};
+var c4 = new C4();
+assertEquals(23, c4.x);
+assertEquals("undefined", typeof c4.y);
+
+// Add setter somewhere on the prototype chain after having constructed the
+// first instance.
+C4.prototype.__proto__.__defineSetter__('x', function(value) { this.y = 23; });
+var c4 = new C4();
+assertEquals("undefined", typeof c4.x);
+assertEquals(23, c4.y);
diff --git a/test/mjsunit/bugs/bug-619.js b/test/mjsunit/bugs/bug-619.js
new file mode 100644
index 0000000..ef8ba80
--- /dev/null
+++ b/test/mjsunit/bugs/bug-619.js
@@ -0,0 +1,62 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// When this bug is corrected move to object-define-property and add
+// additional tests for configurable in the same manner as existing tests
+// there.
+
+var obj = {};
+obj[1] = 42;
+assertEquals(42, obj[1]);
+Object.defineProperty(obj, '1', {value:10, writable:false});
+assertEquals(10, obj[1]);
+
+// We should not be able to override obj[1].
+obj[1] = 5;
+assertEquals(10, obj[1]);
+
+// Try on a range of numbers.
+for(var i = 0; i < 1024; i++) {
+ obj[i] = 42;
+}
+
+for(var i = 0; i < 1024; i++) {
+ Object.defineProperty(obj, i, {value: i, writable:false});
+}
+
+for(var i = 0; i < 1024; i++) {
+ assertEquals(i, obj[i]);
+}
+
+for(var i = 0; i < 1024; i++) {
+ obj[1] = 5;
+}
+
+for(var i = 0; i < 1024; i++) {
+ assertEquals(i, obj[i]);
+}
+
diff --git a/test/mjsunit/codegen-coverage.js b/test/mjsunit/codegen-coverage.js
index d5e7769..42c371b 100644
--- a/test/mjsunit/codegen-coverage.js
+++ b/test/mjsunit/codegen-coverage.js
@@ -25,64 +25,110 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Test the paths in the code generator where values in specific
-// registers get moved around so that the shift operation can use
-// register ECX on ia32 for the shift amount. Other codegen coverage
-// tests should go here too.
+// Flags: --nofull-compiler --nofast-compiler
-
-
+// Test paths in the code generator where values in specific registers
+// get moved around.
function identity(x) {
return x;
}
function cover_codegen_paths() {
var x = 1;
- var a; // Register EAX
- var b; // Register EBX
- var c; // Register ECX
- var d; // Register EDX
- // Register ESI is already used.
- var di; // Register EDI
+
+ // This test depends on the fixed order of register allocation. We try to
+ // get values in specific registers (ia32, x64):
+ var a; // Register eax, rax.
+ var b; // Register ebx, rbx.
+ var c; // Register ecx, rcx.
+ var d; // Register edx, rdx.
+ var di; // Register edi, rdi.
while (x == 1) {
+ // The call will spill registers and leave x in {eax,rax}.
x = identity(1);
+ // The add will spill x and reuse {eax,rax} for the result.
a = x + 1;
+ // A fresh register {ebx,rbx} will be allocated for x, then reused for
+ // the result.
+ b = x + 1;
+ // Et cetera.
c = x + 1;
d = x + 1;
- b = x + 1;
di = x + 1;
// Locals are in the corresponding registers here.
- assertEquals(c << a, 8);
+ assertEquals(8, c << a);
x = identity(1);
a = x + 1;
+ b = x + 1;
c = x + 1;
d = x + 1;
- b = x + 1;
di = x + 1;
- // Locals are in the corresponding registers here.
- assertEquals(a << c, 8);
+ assertEquals(8, a << c);
x = identity(1);
a = x + 1;
+ b = x + 1;
c = x + 1;
d = x + 1;
- b = x + 1;
di = x + 1;
- // Locals are in the corresponding registers here.
c = 0; // Free register ecx.
- assertEquals(a << d, 8);
+ assertEquals(8, a << d);
x = identity(1);
a = x + 1;
+ b = x + 1;
c = x + 1;
d = x + 1;
- b = x + 1;
di = x + 1;
- // Locals are in the corresponding registers here.
b = 0; // Free register ebx.
- assertEquals(a << d, 8);
+ assertEquals(8, a << d);
+
+ // Test the non-commutative subtraction operation with a smi on the
+ // left, all available registers on the right, and a non-smi result.
+ x = identity(-1073741824); // Least (31-bit) smi.
+ a = x + 1; // Still a smi, the greatest smi negated.
+ b = x + 1;
+ c = x + 1;
+ d = x + 1;
+ di = x + 1;
+ // Subtraction should overflow the 31-bit smi range. The result
+ // (1073741824) is outside the 31-bit smi range so it doesn't hit the
+ // "unsafe smi" code that spills a register.
+ assertEquals(1073741824, 1 - a);
+
+ x = identity(-1073741824);
+ a = x + 1;
+ b = x + 1;
+ c = x + 1;
+ d = x + 1;
+ di = x + 1;
+ assertEquals(1073741824, 1 - b);
+
+ x = identity(-1073741824);
+ a = x + 1;
+ b = x + 1;
+ c = x + 1;
+ d = x + 1;
+ di = x + 1;
+ assertEquals(1073741824, 1 - c);
+
+ x = identity(-1073741824);
+ a = x + 1;
+ b = x + 1;
+ c = x + 1;
+ d = x + 1;
+ di = x + 1;
+ assertEquals(1073741824, 1 - d);
+
+ x = identity(-1073741824);
+ a = x + 1;
+ b = x + 1;
+ c = x + 1;
+ d = x + 1;
+ di = x + 1;
+ assertEquals(1073741824, 1 - di);
x = 3;
}
diff --git a/test/mjsunit/compiler/assignment.js b/test/mjsunit/compiler/assignment.js
new file mode 100644
index 0000000..ee2d323
--- /dev/null
+++ b/test/mjsunit/compiler/assignment.js
@@ -0,0 +1,264 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Tests for compound assignments at the top level
+
+z = 2;
+z += 4;
+
+assertEquals(z, 6);
+
+a = new Array(10);
+
+a[2] += 7;
+a[2] = 15;
+a[2] += 2;
+
+assertEquals(17, a[2]);
+
+b = new Object();
+b.foo = 5;
+b.foo += 12;
+
+assertEquals(17, b.foo);
+
+// Test compound assignments in an anonymous function with local variables.
+(function () {
+ var z = 2;
+ z += 4;
+
+ assertEquals(z, 6);
+
+ var a = new Array(10);
+
+ a[2] += 7;
+ a[2] = 15;
+ a[2] += 2;
+
+ assertEquals(17, a[2]);
+
+ var b = new Object();
+ b.foo = 5;
+ b.foo += 12;
+
+ assertEquals(17, b.foo);
+})();
+
+// Test compound assignments in an anonymous function with global variables.
+(function () {
+ z = 2;
+ z += 4;
+
+ assertEquals(z, 6);
+
+ a = new Array(10);
+
+ a[2] += 7;
+ a[2] = 15;
+ a[2] += 2;
+
+ assertEquals(17, a[2]);
+
+ b = new Object();
+ b.foo = 5;
+ b.foo += 12;
+
+ assertEquals(17, b.foo);
+})();
+
+// Test compound assignments in a named function with local variables.
+function foo() {
+ var z = 3;
+ z += 4;
+
+ assertEquals(z, 7);
+
+ var a = new Array(10);
+
+ a[2] += 7;
+ a[2] = 15;
+ a[2] += 2;
+
+ assertEquals(17, a[2]);
+
+ var b = new Object();
+ b.foo = 5;
+ b.foo += 12;
+
+ assertEquals(17, b.foo);
+}
+
+foo();
+
+// Test compound assignments in a named function with global variables.
+function bar() {
+ z = 2;
+ z += 5;
+
+ assertEquals(z, 7);
+
+ a = new Array(10);
+
+ a[2] += 7;
+ a[2] = 15;
+ a[2] += 2;
+
+ assertEquals(17, a[2]);
+
+ b = new Object();
+ b.foo = 5;
+ b.foo += 12;
+
+ assertEquals(17, b.foo);
+}
+
+bar();
+
+// Entire series of tests repeated, in loops.
+// -------------------------------------------
+// Tests for compound assignments in a loop at the top level
+
+for (i = 0; i < 5; ++i) {
+ z = 2;
+ z += 4;
+
+ assertEquals(z, 6);
+
+ a = new Array(10);
+
+ a[2] += 7;
+ a[2] = 15;
+ a[2] += 2;
+
+ assertEquals(17, a[2]);
+
+ b = new Object();
+ b.foo = 5;
+ b.foo += 12;
+
+ assertEquals(17, b.foo);
+}
+
+// Test compound assignments in an anonymous function with local variables.
+(function () {
+ for (var i = 0; i < 5; ++i) {
+ var z = 2;
+ z += 4;
+
+ assertEquals(z, 6);
+
+ var a = new Array(10);
+
+ a[2] += 7;
+ a[2] = 15;
+ a[2] += 2;
+
+ assertEquals(17, a[2]);
+
+ var b = new Object();
+ b.foo = 5;
+ b.foo += 12;
+
+ assertEquals(17, b.foo);
+ }
+})();
+
+// Test compound assignments in an anonymous function with global variables.
+(function () {
+ for (i = 0; i < 5; ++i) {
+ z = 2;
+ z += 4;
+
+ assertEquals(z, 6);
+
+ a = new Array(10);
+
+ a[2] += 7;
+ a[2] = 15;
+ a[2] += 2;
+
+ assertEquals(17, a[2]);
+
+ b = new Object();
+ b.foo = 5;
+ b.foo += 12;
+
+ assertEquals(17, b.foo);
+ }
+})();
+
+// Test compound assignments in a named function with local variables.
+function foo_loop() {
+ for (i = 0; i < 5; ++i) {
+ var z = 3;
+ z += 4;
+
+ assertEquals(z, 7);
+
+ var a = new Array(10);
+
+ a[2] += 7;
+ a[2] = 15;
+ a[2] += 2;
+
+ assertEquals(17, a[2]);
+
+ var b = new Object();
+ b.foo = 5;
+ b.foo += 12;
+
+ assertEquals(17, b.foo);
+ }
+}
+
+foo_loop();
+
+// Test compound assignments in a named function with global variables.
+function bar_loop() {
+ for (i = 0; i < 5; ++i) {
+ z = 2;
+ z += 5;
+
+ assertEquals(z, 7);
+
+ a = new Array(10);
+
+ a[2] += 7;
+ a[2] = 15;
+ a[2] += 2;
+
+ assertEquals(17, a[2]);
+
+ b = new Object();
+ b.foo = 5;
+ b.foo += 12;
+
+ assertEquals(17, b.foo);
+ }
+}
+
+bar_loop();
diff --git a/test/mjsunit/compiler/simple-bailouts.js b/test/mjsunit/compiler/simple-bailouts.js
new file mode 100644
index 0000000..af80b7f
--- /dev/null
+++ b/test/mjsunit/compiler/simple-bailouts.js
@@ -0,0 +1,127 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --fast-compiler
+
+function Test() {
+ this.result = 0;
+ this.x = 0;
+ this.y = 0;
+ this.z = 0;
+}
+var a = 1;
+var b = 2;
+var c = 4;
+var d = 8;
+
+// Test operations expected to stay on the fast path. Enumerate all binary
+// trees with <= 4 leaves.
+Test.prototype.test0 = function () {
+ this.result = a | b;
+};
+
+Test.prototype.test1 = function() {
+ this.result = (a | b) | c;
+};
+
+Test.prototype.test2 = function() {
+ this.result = a | (b | c);
+};
+
+Test.prototype.test3 = function() {
+ this.result = ((a | b) | c) | d;
+};
+
+Test.prototype.test4 = function() {
+ this.result = (a | (b | c)) | d;
+};
+
+Test.prototype.test5 = function() {
+ this.result = (a | b) | (c | d);
+};
+
+Test.prototype.test6 = function() {
+ this.result = a | ((b | c) | d);
+};
+
+Test.prototype.test7 = function() {
+ this.result = a | (b | (c | d));
+};
+
+// These tests should fail if we bailed out to the beginning of the full
+// code.
+Test.prototype.test8 = function () {
+ // If this.x = 1 and a = 1.1:
+ this.y = this.x | b; // Should be (1 | 2) == 3.
+ this.x = c; // Should be 4.
+ this.z = this.x | a; // Should be (4 | 1.1) == 5.
+};
+
+Test.prototype.test9 = function() {
+ // If this.x = 2 and a = 1.1:
+ this.z = // (14 | 1.1) == 15
+ (this.x = // (6 | 8) == 14
+ (this.y = // (2 | 4) == 6
+ this.x // 2
+ | c) // 4
+ | d) // 8
+ | a; // 1.1
+}
+
+var t = new Test();
+
+t.test0();
+assertEquals(3, t.result);
+
+t.test1();
+assertEquals(7, t.result);
+t.test2();
+assertEquals(7, t.result);
+
+t.test3();
+assertEquals(15, t.result);
+t.test4();
+assertEquals(15, t.result);
+t.test5();
+assertEquals(15, t.result);
+t.test6();
+assertEquals(15, t.result);
+t.test7();
+assertEquals(15, t.result);
+
+a = 1.1;
+t.x = 1;
+t.test8();
+assertEquals(4, t.x);
+assertEquals(3, t.y);
+assertEquals(5, t.z);
+
+t.x = 2;
+t.test9();
+assertEquals(14, t.x);
+assertEquals(6, t.y);
+assertEquals(15, t.z);
diff --git a/test/mjsunit/compiler/simple-binary-op.js b/test/mjsunit/compiler/simple-binary-op.js
new file mode 100644
index 0000000..15e1a55
--- /dev/null
+++ b/test/mjsunit/compiler/simple-binary-op.js
@@ -0,0 +1,40 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --fast-compiler
+
+var a = 1;
+var b = 2;
+var c = 4;
+
+function f() { this.x = this.x | a | b | c | a | c; }
+
+var o = {x:0, g:f}
+
+o.g();
+
+assertEquals(7, o.x);
diff --git a/test/mjsunit/compiler/simple-global-access.js b/test/mjsunit/compiler/simple-global-access.js
new file mode 100644
index 0000000..35746ba
--- /dev/null
+++ b/test/mjsunit/compiler/simple-global-access.js
@@ -0,0 +1,53 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --fast-compiler
+
+// Test global variable loads with the fast compiler.
+var g1 = 42;
+var g2 = 43;
+var g3 = 44;
+this.__defineGetter__("g4", function () { return 45; });
+
+function f1() { this.x = this.y = this.z = g1; }
+function f2() { this.x = g1; this.y = g2; this.z = g3; }
+function f3() { this.x = g4; }
+
+var o = { x:0, y:0, z:0, test1:f1, test2:f2, test3:f3 }
+
+o.test1();
+assertEquals(42, o.x);
+assertEquals(42, o.y);
+assertEquals(42, o.z);
+
+o.test2();
+assertEquals(42, o.x);
+assertEquals(43, o.y);
+assertEquals(44, o.z);
+
+o.test3();
+assertEquals(45, o.x);
diff --git a/test/mjsunit/compiler/this-property-refs.js b/test/mjsunit/compiler/this-property-refs.js
new file mode 100644
index 0000000..5e8ea59
--- /dev/null
+++ b/test/mjsunit/compiler/this-property-refs.js
@@ -0,0 +1,64 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --fast-compiler
+
+// Test references to properties of this.
+function Test() {
+ this.a = 0;
+ this.b = 1;
+ this.c = 2;
+ this.d = 3;
+}
+
+Test.prototype.test0 = function () {
+ this.a = this.b;
+};
+
+Test.prototype.test1 = function() {
+ this.a = this.b = this.c;
+};
+
+Test.prototype.test2 = function() {
+ this.c = this.d;
+ this.b = this.c;
+ this.a = this.b;
+};
+
+var t = new Test();
+
+t.test0();
+assertEquals(1, t.a);
+
+t.test1();
+assertEquals(2, t.a);
+assertEquals(2, t.b);
+
+t.test2();
+assertEquals(3, t.a);
+assertEquals(3, t.b);
+assertEquals(3, t.c);
diff --git a/test/mjsunit/debug-compile-event.js b/test/mjsunit/debug-compile-event.js
index 071183b..e7ecf47 100644
--- a/test/mjsunit/debug-compile-event.js
+++ b/test/mjsunit/debug-compile-event.js
@@ -90,6 +90,11 @@
var json = event_data.toJSONProtocol();
var msg = eval('(' + json + ')');
assertTrue('context' in msg.body.script);
+
+ // Check that we pick script name from //@ sourceURL, iff present
+ assertEquals(current_source.indexOf('sourceURL') >= 0 ?
+ 'myscript.js' : undefined,
+ event_data.script().name());
}
} catch (e) {
exception = e
@@ -109,6 +114,7 @@
source_count += 2; // Using eval causes additional compilation event.
compileSource('JSON.parse(\'{"a":1,"b":2}\')');
source_count++; // Using JSON.parse causes additional compilation event.
+compileSource('x=1; //@ sourceURL=myscript.js');
// Make sure that the debug event listener was invoked.
assertFalse(exception, "exception in listener")
diff --git a/test/mjsunit/debug-evaluate.js b/test/mjsunit/debug-evaluate.js
index c477907..182e2ac 100644
--- a/test/mjsunit/debug-evaluate.js
+++ b/test/mjsunit/debug-evaluate.js
@@ -87,6 +87,37 @@
testRequest(dcp, '{"expression":"a","global":true}', true, 1);
testRequest(dcp, '{"expression":"this.a","global":true}', true, 1);
+ // Test that the whole string text is returned if maxStringLength
+ // parameter is passed.
+ testRequest(
+ dcp,
+ '{"expression":"this.longString","global":true,maxStringLength:-1}',
+ true,
+ longString);
+ testRequest(
+ dcp,
+ '{"expression":"this.longString","global":true,maxStringLength:' +
+ longString.length + '}',
+ true,
+ longString);
+ var truncatedStringSuffix = '... (length: ' + longString.length + ')';
+ testRequest(
+ dcp,
+ '{"expression":"this.longString","global":true,maxStringLength:0}',
+ true,
+ truncatedStringSuffix);
+ testRequest(
+ dcp,
+ '{"expression":"this.longString","global":true,maxStringLength:1}',
+ true,
+ longString.charAt(0) + truncatedStringSuffix);
+ // Test that by default string is truncated to first 80 chars.
+ testRequest(
+ dcp,
+ '{"expression":"this.longString","global":true}',
+ true,
+ longString.substring(0, 80) + truncatedStringSuffix);
+
// Indicate that all was processed.
listenerComplete = true;
}
@@ -109,6 +140,12 @@
a = 1;
+// String which is longer than 80 chars.
+var longString = "1234567890_";
+for (var i = 0; i < 4; i++) {
+ longString += longString;
+}
+
// Set a break point at return in f and invoke g to hit the breakpoint.
Debug.setBreakPoint(f, 2, 0);
g();
diff --git a/test/mjsunit/div-mod.js b/test/mjsunit/div-mod.js
index b3c77e1..1d352b5 100644
--- a/test/mjsunit/div-mod.js
+++ b/test/mjsunit/div-mod.js
@@ -154,4 +154,18 @@
doTest(-a,-b);
}
}
-})()
+})();
+
+
+(function () {
+ // Edge cases
+ var zero = 0;
+ var minsmi32 = -0x40000000;
+ var minsmi64 = -0x80000000;
+ var somenum = 3532;
+ assertEquals(-0, zero / -1, "0 / -1");
+ assertEquals(1, minsmi32 / -0x40000000, "minsmi/minsmi-32");
+ assertEquals(1, minsmi64 / -0x80000000, "minsmi/minsmi-64");
+ assertEquals(somenum, somenum % -0x40000000, "%minsmi-32");
+ assertEquals(somenum, somenum % -0x80000000, "%minsmi-64");
+})();
diff --git a/test/mjsunit/fuzz-natives.js b/test/mjsunit/fuzz-natives.js
index d906eb8..e2f601e 100644
--- a/test/mjsunit/fuzz-natives.js
+++ b/test/mjsunit/fuzz-natives.js
@@ -27,6 +27,9 @@
// Flags: --allow-natives-syntax
+var RUN_WITH_ALL_ARGUMENT_ENTRIES = false;
+var kOnManyArgumentsRemove = 5;
+
function makeArguments() {
var result = [ ];
result.push(17);
@@ -74,13 +77,23 @@
var func = makeFunction(name, argc);
while (hasMore) {
var argPool = makeArguments();
+ // When we have 5 or more arguments we lower the amount of tests cases
+ // by randomly removing kOnManyArgumentsRemove entries
+ var numArguments = RUN_WITH_ALL_ARGUMENT_ENTRIES ?
+ kArgObjects : kArgObjects-kOnManyArgumentsRemove;
+ if (argc >= 5 && !RUN_WITH_ALL_ARGUMENT_ENTRIES) {
+ for (var i = 0; i < kOnManyArgumentsRemove; i++) {
+ var rand = Math.floor(Math.random() * (kArgObjects - i));
+ argPool.splice(rand,1);
+ }
+ }
var current = type;
var hasMore = false;
var argList = [ ];
for (var i = 0; i < argc; i++) {
- var index = current % kArgObjects;
- current = (current / kArgObjects) << 0;
- if (index != (kArgObjects - 1))
+ var index = current % numArguments;
+ current = (current / numArguments) << 0;
+ if (index != (numArguments - 1))
hasMore = true;
argList.push(argPool[index]);
}
diff --git a/test/mjsunit/object-define-properties.js b/test/mjsunit/object-define-properties.js
new file mode 100644
index 0000000..6b3725b
--- /dev/null
+++ b/test/mjsunit/object-define-properties.js
@@ -0,0 +1,56 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Tests the Object.defineProperties method - ES 15.2.3.7
+// Note that the internal DefineOwnProperty method is tested through
+// object-define-property.js, this file only contains tests specific for
+// Object.defineProperties. Also note that object-create.js contains
+// a range of indirect tests on this method since Object.create uses
+// Object.defineProperties as a step in setting up the object.
+
+// Try defining with null as descriptor:
+try {
+ Object.defineProperties({}, null);
+} catch(e) {
+ assertTrue(/null to object/.test(e));
+}
+
+// Try defining with null as object
+try {
+ Object.defineProperties(null, {});
+} catch(e) {
+ assertTrue(/called on non-object/.test(e));
+}
+
+
+var desc = {foo: {value: 10}, bar: {get: function() {return 42; }}};
+var obj = {};
+// Check that we actually get the object back as returnvalue
+var x = Object.defineProperties(obj, desc);
+
+assertEquals(x.foo, 10);
+assertEquals(x.bar, 42);
diff --git a/test/mjsunit/object-define-property.js b/test/mjsunit/object-define-property.js
new file mode 100644
index 0000000..43b1c7f
--- /dev/null
+++ b/test/mjsunit/object-define-property.js
@@ -0,0 +1,499 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Tests the object.defineProperty method - ES 15.2.3.6
+
+// Flags: --allow-natives-syntax
+
+// Check that an exception is thrown when null is passed as object.
+try {
+ Object.defineProperty(null, null, null);
+ assertTrue(false);
+} catch (e) {
+ assertTrue(/called on non-object/.test(e));
+}
+
+// Check that an exception is thrown when undefined is passed as object.
+try {
+ Object.defineProperty(undefined, undefined, undefined);
+ assertTrue(false);
+} catch (e) {
+ assertTrue(/called on non-object/.test(e));
+}
+
+// Check that an exception is thrown when non-object is passed as object.
+try {
+ Object.defineProperty(0, "foo", undefined);
+ assertTrue(false);
+} catch (e) {
+ assertTrue(/called on non-object/.test(e));
+}
+
+// Object
+var obj1 = {};
+
+// Values
+var val1 = 0;
+var val2 = 0;
+var val3 = 0;
+
+// Descriptors
+var emptyDesc = {};
+
+var accessorConfigurable = {
+ set: function() { val1++; },
+ get: function() { return val1; },
+ configurable: true
+};
+
+var accessorNoConfigurable = {
+ set: function() { val2++; },
+ get: function() { return val2; },
+ configurable: false
+};
+
+var accessorOnlySet = {
+ set: function() { val3++; },
+ configurable: true
+};
+
+var accessorOnlyGet = {
+ get: function() { return val3; },
+ configurable: true
+};
+
+var accessorDefault = {set: function(){} };
+
+var dataConfigurable = { value: 1000, configurable: true };
+
+var dataNoConfigurable = { value: 2000, configurable: false };
+
+var dataWritable = { value: 3000, writable: true};
+
+
+// Check that we can't add property with undefined attributes.
+try {
+ Object.defineProperty(obj1, "foo", undefined);
+ assertTrue(false);
+} catch (e) {
+ assertTrue(/must be an object/.test(e));
+}
+
+// Make sure that we can add a property with an empty descriptor and
+// that it has the default descriptor values.
+Object.defineProperty(obj1, "foo", emptyDesc);
+
+// foo should be undefined as it has no get, set or value
+assertEquals(undefined, obj1.foo);
+
+// We should, however, be able to retrieve the propertydescriptor which should
+// have all default values (according to 8.6.1).
+var desc = Object.getOwnPropertyDescriptor(obj1, "foo");
+assertFalse(desc.configurable);
+assertFalse(desc.enumerable);
+assertFalse(desc.writable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+assertEquals(desc.value, undefined);
+
+// Make sure that getOwnPropertyDescriptor does not return a descriptor
+// with default values if called with non existing property (otherwise
+// the test above is invalid).
+desc = Object.getOwnPropertyDescriptor(obj1, "bar");
+assertEquals(desc, undefined);
+
+// Make sure that foo can't be reset (as configurable is false).
+try {
+ Object.defineProperty(obj1, "foo", accessorConfigurable);
+} catch (e) {
+ assertTrue(/Cannot redefine property/.test(e));
+}
+
+
+// Accessor properties
+
+Object.defineProperty(obj1, "bar", accessorConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj1, "bar");
+assertTrue(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorConfigurable.get);
+assertEquals(desc.set, accessorConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj1.bar = 1);
+assertEquals(1, val1);
+assertEquals(1, obj1.bar = 1);
+assertEquals(2, val1);
+assertEquals(2, obj1.bar);
+
+// Redefine bar with non configurable test
+Object.defineProperty(obj1, "bar", accessorNoConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj1, "bar");
+assertFalse(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorNoConfigurable.get);
+assertEquals(desc.set, accessorNoConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj1.bar = 1);
+assertEquals(2, val1);
+assertEquals(1, val2);
+assertEquals(1, obj1.bar = 1)
+assertEquals(2, val1);
+assertEquals(2, val2);
+assertEquals(2, obj1.bar);
+
+// Try to redefine bar again - should fail as configurable is false.
+try {
+ Object.defineProperty(obj1, "bar", accessorConfigurable);
+ assertTrue(false);
+} catch(e) {
+ assertTrue(/Cannot redefine property/.test(e));
+}
+
+// Try to redefine bar again using the data descriptor - should fail.
+try {
+ Object.defineProperty(obj1, "bar", dataConfigurable);
+ assertTrue(false);
+} catch(e) {
+ assertTrue(/Cannot redefine property/.test(e));
+}
+
+// Redefine using same descriptor - should succeed.
+Object.defineProperty(obj1, "bar", accessorNoConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj1, "bar");
+assertFalse(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorNoConfigurable.get);
+assertEquals(desc.set, accessorNoConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj1.bar = 1);
+assertEquals(2, val1);
+assertEquals(3, val2);
+assertEquals(1, obj1.bar = 1)
+assertEquals(2, val1);
+assertEquals(4, val2);
+assertEquals(4, obj1.bar);
+
+// Define an accessor that has only a setter
+Object.defineProperty(obj1, "setOnly", accessorOnlySet);
+desc = Object.getOwnPropertyDescriptor(obj1, "setOnly");
+assertTrue(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.set, accessorOnlySet.set);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.value, undefined);
+assertEquals(desc.get, undefined);
+assertEquals(1, obj1.setOnly = 1);
+assertEquals(1, val3);
+
+// Add a getter - should not touch the setter
+Object.defineProperty(obj1, "setOnly", accessorOnlyGet);
+desc = Object.getOwnPropertyDescriptor(obj1, "setOnly");
+assertTrue(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, accessorOnlyGet.get);
+assertEquals(desc.set, accessorOnlySet.set);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj1.setOnly = 1);
+assertEquals(2, val3);
+
+// The above should also work if redefining just a getter or setter on
+// an existing property with both a getter and a setter.
+Object.defineProperty(obj1, "both", accessorConfigurable);
+
+Object.defineProperty(obj1, "both", accessorOnlySet);
+desc = Object.getOwnPropertyDescriptor(obj1, "both");
+assertTrue(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.set, accessorOnlySet.set);
+assertEquals(desc.get, accessorConfigurable.get);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj1.both = 1);
+assertEquals(3, val3);
+
+
+// Data properties
+
+Object.defineProperty(obj1, "foobar", dataConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj1, "foobar");
+assertEquals(obj1.foobar, 1000);
+assertEquals(desc.value, 1000);
+assertTrue(desc.configurable);
+assertFalse(desc.writable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+//Try writing to non writable attribute - should remain 1000
+obj1.foobar = 1001;
+assertEquals(obj1.foobar, 1000);
+
+
+// Redefine to writable descriptor - now writing to foobar should be allowed
+Object.defineProperty(obj1, "foobar", dataWritable);
+desc = Object.getOwnPropertyDescriptor(obj1, "foobar");
+assertEquals(obj1.foobar, 3000);
+assertEquals(desc.value, 3000);
+// Note that since dataWritable does not define configurable the configurable
+// setting from the redefined property (in this case true) is used.
+assertTrue(desc.configurable);
+assertTrue(desc.writable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+// Writing to the property should now be allowed
+obj1.foobar = 1001;
+assertEquals(obj1.foobar, 1001);
+
+
+// Redefine with non configurable data property.
+Object.defineProperty(obj1, "foobar", dataNoConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj1, "foobar");
+assertEquals(obj1.foobar, 2000);
+assertEquals(desc.value, 2000);
+assertFalse(desc.configurable);
+assertFalse(desc.writable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+
+// Try redefine again - shold fail because configurable is now false.
+try {
+ Object.defineProperty(obj1, "foobar", dataConfigurable);
+ assertTrue(false);
+} catch (e) {
+ assertTrue(/Cannot redefine property/.test(e));
+}
+
+// Try redefine again with accessor property - shold also fail.
+try {
+ Object.defineProperty(obj1, "foobar", dataConfigurable);
+ assertTrue(false);
+} catch (e) {
+ assertTrue(/Cannot redefine property/.test(e));
+}
+
+
+// Redifine with the same descriptor - should succeed (step 6).
+Object.defineProperty(obj1, "foobar", dataNoConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj1, "foobar");
+assertEquals(obj1.foobar, 2000);
+assertEquals(desc.value, 2000);
+assertFalse(desc.configurable);
+assertFalse(desc.writable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+
+
+// New object
+var obj2 = {};
+
+// Make accessor - redefine to data
+Object.defineProperty(obj2, "foo", accessorConfigurable);
+
+// Redefine to data property
+Object.defineProperty(obj2, "foo", dataConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj2, "foo");
+assertEquals(obj2.foo, 1000);
+assertEquals(desc.value, 1000);
+assertTrue(desc.configurable);
+assertFalse(desc.writable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+
+
+// Redefine back to accessor
+Object.defineProperty(obj2, "foo", accessorConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj2, "foo");
+assertTrue(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorConfigurable.get);
+assertEquals(desc.set, accessorConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj2.foo = 1);
+assertEquals(3, val1);
+assertEquals(4, val2);
+assertEquals(3, obj2.foo);
+
+// Make data - redefine to accessor
+Object.defineProperty(obj2, "bar", dataConfigurable)
+
+// Redefine to accessor property
+Object.defineProperty(obj2, "bar", accessorConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj2, "bar");
+assertTrue(desc.configurable);
+assertFalse(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorConfigurable.get);
+assertEquals(desc.set, accessorConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj2.bar = 1);
+assertEquals(4, val1);
+assertEquals(4, val2);
+assertEquals(4, obj2.foo);
+
+// Redefine back to data property
+Object.defineProperty(obj2, "bar", dataConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj2, "bar");
+assertEquals(obj2.bar, 1000);
+assertEquals(desc.value, 1000);
+assertTrue(desc.configurable);
+assertFalse(desc.writable);
+assertFalse(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+
+
+// Redefinition of an accessor defined using __defineGetter__ and
+// __defineSetter__
+function get(){return this.x}
+function set(x){this.x=x};
+
+var obj3 = {x:1000};
+obj3.__defineGetter__("foo", get);
+obj3.__defineSetter__("foo", set);
+
+desc = Object.getOwnPropertyDescriptor(obj3, "foo");
+assertTrue(desc.configurable);
+assertTrue(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, get);
+assertEquals(desc.set, set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj3.foo = 1);
+assertEquals(1, obj3.x);
+assertEquals(1, obj3.foo);
+
+// Redefine to accessor property (non configurable) - note that enumerable
+// which we do not redefine should remain the same (true).
+Object.defineProperty(obj3, "foo", accessorNoConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj3, "foo");
+assertFalse(desc.configurable);
+assertTrue(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorNoConfigurable.get);
+assertEquals(desc.set, accessorNoConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj3.foo = 1);
+assertEquals(5, val2);
+assertEquals(5, obj3.foo);
+
+
+obj3.__defineGetter__("bar", get);
+obj3.__defineSetter__("bar", set);
+
+
+// Redefine back to data property
+Object.defineProperty(obj3, "bar", dataConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj3, "bar");
+assertEquals(obj3.bar, 1000);
+assertEquals(desc.value, 1000);
+assertTrue(desc.configurable);
+assertFalse(desc.writable);
+assertTrue(desc.enumerable);
+assertEquals(desc.get, undefined);
+assertEquals(desc.set, undefined);
+
+
+var obj4 = {};
+var func = function (){return 42;};
+obj4.bar = func;
+assertEquals(42, obj4.bar());
+
+Object.defineProperty(obj4, "bar", accessorConfigurable);
+desc = Object.getOwnPropertyDescriptor(obj4, "bar");
+assertTrue(desc.configurable);
+assertTrue(desc.enumerable);
+assertEquals(desc.writable, undefined);
+assertEquals(desc.get, accessorConfigurable.get);
+assertEquals(desc.set, accessorConfigurable.set);
+assertEquals(desc.value, undefined);
+assertEquals(1, obj4.bar = 1);
+assertEquals(5, val1);
+assertEquals(5, obj4.bar);
+
+// Make sure an error is thrown when trying to access to redefined function
+try {
+ obj4.bar();
+ assertTrue(false);
+} catch (e) {
+ assertTrue(/is not a function/.test(e));
+}
+
+
+// Test runtime calls to DefineOrRedefineDataProperty and
+// DefineOrRedefineAccessorProperty - make sure we don't
+// crash
+try {
+ %DefineOrRedefineAccessorProperty(0, 0, 0, 0, 0);
+} catch (e) {
+ assertTrue(/illegal access/.test(e));
+}
+
+try {
+ %DefineOrRedefineDataProperty(0, 0, 0, 0);
+} catch (e) {
+ assertTrue(/illegal access/.test(e));
+}
+
+try {
+ %DefineOrRedefineDataProperty(null, null, null, null);
+} catch (e) {
+ assertTrue(/illegal access/.test(e));
+}
+
+try {
+ %DefineOrRedefineAccessorProperty(null, null, null, null, null);
+} catch (e) {
+ assertTrue(/illegal access/.test(e));
+}
+
+try {
+ %DefineOrRedefineDataProperty({}, null, null, null);
+} catch (e) {
+ assertTrue(/illegal access/.test(e));
+}
+
+// Defining properties null should fail even when we have
+// other allowed values
+try {
+ %DefineOrRedefineAccessorProperty(null, 'foo', 0, func, 0);
+} catch (e) {
+ assertTrue(/illegal access/.test(e));
+}
+
+try {
+ %DefineOrRedefineDataProperty(null, 'foo', 0, 0);
+} catch (e) {
+ assertTrue(/illegal access/.test(e));
+}
diff --git a/test/mjsunit/object-get-own-property-names.js b/test/mjsunit/object-get-own-property-names.js
index f52cee2..33aa85e 100644
--- a/test/mjsunit/object-get-own-property-names.js
+++ b/test/mjsunit/object-get-own-property-names.js
@@ -57,6 +57,8 @@
assertEquals(3, propertyNames.length);
assertEquals("0", propertyNames[0]);
assertEquals("1", propertyNames[1]);
+assertEquals("string", typeof propertyNames[0]);
+assertEquals("string", typeof propertyNames[1]);
assertEquals("length", propertyNames[2]);
// Check that no proto properties are returned.
diff --git a/test/mjsunit/regress/regress-603.js b/test/mjsunit/regress/regress-603.js
new file mode 100644
index 0000000..7d4c322
--- /dev/null
+++ b/test/mjsunit/regress/regress-603.js
@@ -0,0 +1,49 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Calling non-objects directly or via Function.prototype.call should
+// not mess up the stack.
+// http://code.google.com/p/v8/issues/detail?id=603
+
+function test0() {
+ var re = /b../;
+ return re('abcdefghijklm') + 'z';
+}
+assertEquals('bcdz', test0());
+
+var re1 = /c../;
+re1.call = Function.prototype.call;
+var test1 = re1.call(null, 'abcdefghijklm') + 'z';
+assertEquals('cdez', test1);
+
+var re2 = /d../;
+var test2 = Function.prototype.call.call(re2, null, 'abcdefghijklm') + 'z';
+assertEquals('defz', test2);
+
+var re3 = /e../;
+var test3 = Function.prototype.call.apply(re3, [null, 'abcdefghijklm']) + 'z';
+assertEquals('efgz', test3);
diff --git a/test/mjsunit/regress/regress-612.js b/test/mjsunit/regress/regress-612.js
new file mode 100644
index 0000000..aee6d53
--- /dev/null
+++ b/test/mjsunit/regress/regress-612.js
@@ -0,0 +1,44 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Tests intercation between __defineGetter__/__defineSetter and fast and slow
+// mode of the objects due to series of assignments optimization.
+// (See http://code.google.com/p/v8/issues/detail?id=612)
+
+obj = {}
+
+// Define getter which currently moves object into slow mode.
+obj.__defineGetter__('foobar', function() { return 42; })
+
+// Starts initialization block mode. And turns object into slow mode.
+obj.a = 1
+obj.b = 2;
+obj.c = 3;
+// Now object is turned into fast mode, but it has getter defined above...
+
+// Now assert is triggered.
+obj.__defineGetter__('foobar', function() { return 42; })
diff --git a/test/mjsunit/setter-on-constructor-prototype.js b/test/mjsunit/setter-on-constructor-prototype.js
new file mode 100644
index 0000000..d5718f9
--- /dev/null
+++ b/test/mjsunit/setter-on-constructor-prototype.js
@@ -0,0 +1,111 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function RunTest(ensure_fast_case) {
+ function C1() {
+ this.x = 23;
+ };
+ C1.prototype = { set x(value) { this.y = 23; } };
+ if (ensure_fast_case) {
+ %ToFastProperties(C1.prototype);
+ }
+
+ for (var i = 0; i < 10; i++) {
+ var c1 = new C1();
+ assertEquals("undefined", typeof c1.x);
+ assertEquals(23, c1.y);
+ }
+
+
+ function C2() {
+ this.x = 23;
+ };
+ C2.prototype = { };
+ C2.prototype.__proto__ = { set x(value) { this.y = 23; } };
+ if (ensure_fast_case) {
+ %ToFastProperties(C2.prototype.__proto__)
+ }
+
+ for (var i = 0; i < 10; i++) {
+ var c2 = new C2();
+ assertEquals("undefined", typeof c2.x);
+ assertEquals(23, c2.y);
+ }
+
+
+ function C3() {
+ this.x = 23;
+ };
+ C3.prototype = { };
+ C3.prototype.__defineSetter__('x', function(value) { this.y = 23; });
+ if (ensure_fast_case) {
+ %ToFastProperties(C3.prototype);
+ }
+
+ for (var i = 0; i < 10; i++) {
+ var c3 = new C3();
+ assertEquals("undefined", typeof c3.x);
+ assertEquals(23, c3.y);
+ }
+
+
+ function C4() {
+ this.x = 23;
+ };
+ C4.prototype = { };
+ C4.prototype.__proto__ = { };
+ C4.prototype.__proto__.__defineSetter__('x', function(value) { this.y = 23; });
+ if (ensure_fast_case) {
+ %ToFastProperties(C4.prototype.__proto__);
+ }
+
+ for (var i = 0; i < 10; i++) {
+ var c4 = new C4();
+ assertEquals("undefined", typeof c4.x);
+ assertEquals(23, c4.y);
+ }
+
+
+ function D() {
+ this.x = 23;
+ };
+ D.prototype = 1;
+ if (ensure_fast_case) {
+ %ToFastProperties(D.prototype);
+ }
+
+ for (var i = 0; i < 10; i++) {
+ var d = new D();
+ assertEquals(23, d.x);
+ assertEquals("undefined", typeof d.y);
+ }
+}
+
+RunTest(false);
+RunTest(true);
diff --git a/test/mjsunit/substr.js b/test/mjsunit/substr.js
old mode 100644
new mode 100755
diff --git a/test/mjsunit/tools/tickprocessor-test-func-info.log b/test/mjsunit/tools/tickprocessor-test-func-info.log
new file mode 100644
index 0000000..29a12f6
--- /dev/null
+++ b/test/mjsunit/tools/tickprocessor-test-func-info.log
@@ -0,0 +1,13 @@
+shared-library,"shell",0x08048000,0x081ee000
+shared-library,"/lib32/libm-2.7.so",0xf7db6000,0xf7dd9000
+shared-library,"ffffe000-fffff000",0xffffe000,0xfffff000
+profiler,"begin",1
+code-creation,Stub,0x424260,348,"CompareStub_GE"
+code-creation,LazyCompile,0x2a8100,18535,"DrawQube 3d-cube.js:188"
+function-creation,0x2d11b8,0x2a8100
+code-creation,LazyCompile,0x480100,3908,"DrawLine 3d-cube.js:17"
+function-creation,0x2d0f7c,0x480100
+tick,0x424284,0xbfffeea0,0x2d0f7c,0,0x2aaaa5
+tick,0x42429f,0xbfffed88,0x2d0f7c,0,0x2aacb4
+tick,0x48063d,0xbfffec7c,0x2d0f7c,0,0x2aaec6
+profiler,"end"