Fix some more missing ToObject on Array.prototype.
authormstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 30 Apr 2014 08:52:00 +0000 (08:52 +0000)
committermstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 30 Apr 2014 08:52:00 +0000 (08:52 +0000)
R=mvstanton@chromium.org
BUG=

Review URL: https://codereview.chromium.org/254103002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@21077 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/array.js
test/mjsunit/regress/regress-builtinbust-6.js

index 4df4682..dcaf0f4 100644 (file)
@@ -357,17 +357,18 @@ function ArrayToLocaleString() {
 function ArrayJoin(separator) {
   CHECK_OBJECT_COERCIBLE(this, "Array.prototype.join");
 
-  var length = TO_UINT32(this.length);
+  var array = TO_OBJECT_INLINE(this);
+  var length = TO_UINT32(array.length);
   if (IS_UNDEFINED(separator)) {
     separator = ',';
   } else if (!IS_STRING(separator)) {
     separator = NonStringToString(separator);
   }
 
-  var result = %_FastAsciiArrayJoin(this, separator);
+  var result = %_FastAsciiArrayJoin(array, separator);
   if (!IS_UNDEFINED(result)) return result;
 
-  return Join(this, length, separator, ConvertToString);
+  return Join(array, length, separator, ConvertToString);
 }
 
 
@@ -518,33 +519,34 @@ function SparseReverse(array, len) {
 function ArrayReverse() {
   CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reverse");
 
-  var j = TO_UINT32(this.length) - 1;
+  var array = TO_OBJECT_INLINE(this);
+  var j = TO_UINT32(array.length) - 1;
 
-  if (UseSparseVariant(this, j, IS_ARRAY(this))) {
-    SparseReverse(this, j+1);
-    return this;
+  if (UseSparseVariant(array, j, IS_ARRAY(array))) {
+    SparseReverse(array, j+1);
+    return array;
   }
 
   for (var i = 0; i < j; i++, j--) {
-    var current_i = this[i];
-    if (!IS_UNDEFINED(current_i) || i in this) {
-      var current_j = this[j];
-      if (!IS_UNDEFINED(current_j) || j in this) {
-        this[i] = current_j;
-        this[j] = current_i;
+    var current_i = array[i];
+    if (!IS_UNDEFINED(current_i) || i in array) {
+      var current_j = array[j];
+      if (!IS_UNDEFINED(current_j) || j in array) {
+        array[i] = current_j;
+        array[j] = current_i;
       } else {
-        this[j] = current_i;
-        delete this[i];
+        array[j] = current_i;
+        delete array[i];
       }
     } else {
-      var current_j = this[j];
-      if (!IS_UNDEFINED(current_j) || j in this) {
-        this[i] = current_j;
-        delete this[j];
+      var current_j = array[j];
+      if (!IS_UNDEFINED(current_j) || j in array) {
+        array[i] = current_j;
+        delete array[j];
       }
     }
   }
-  return this;
+  return array;
 }
 
 
@@ -645,7 +647,8 @@ function ArrayUnshift(arg1) {  // length == 1
 function ArraySlice(start, end) {
   CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice");
 
-  var len = TO_UINT32(this.length);
+  var array = TO_OBJECT_INLINE(this);
+  var len = TO_UINT32(array.length);
   var start_i = TO_INTEGER(start);
   var end_i = len;
 
@@ -669,13 +672,13 @@ function ArraySlice(start, end) {
 
   if (end_i < start_i) return result;
 
-  if (IS_ARRAY(this) &&
-      !%IsObserved(this) &&
+  if (IS_ARRAY(array) &&
+      !%IsObserved(array) &&
       (end_i > 1000) &&
-      (%EstimateNumberOfElements(this) < end_i)) {
-    SmartSlice(this, start_i, end_i - start_i, len, result);
+      (%EstimateNumberOfElements(array) < end_i)) {
+    SmartSlice(array, start_i, end_i - start_i, len, result);
   } else {
-    SimpleSlice(this, start_i, end_i - start_i, len, result);
+    SimpleSlice(array, start_i, end_i - start_i, len, result);
   }
 
   result.length = end_i - start_i;
@@ -763,7 +766,8 @@ function ArraySplice(start, delete_count) {
     return ObservedArraySplice.apply(this, arguments);
 
   var num_arguments = %_ArgumentsLength();
-  var len = TO_UINT32(this.length);
+  var array = TO_OBJECT_INLINE(this);
+  var len = TO_UINT32(array.length);
   var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len);
   var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len,
                                            start_i);
@@ -771,32 +775,32 @@ function ArraySplice(start, delete_count) {
   deleted_elements.length = del_count;
   var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0;
 
-  if (del_count != num_elements_to_add && ObjectIsSealed(this)) {
+  if (del_count != num_elements_to_add && ObjectIsSealed(array)) {
     throw MakeTypeError("array_functions_change_sealed",
                         ["Array.prototype.splice"]);
-  } else if (del_count > 0 && ObjectIsFrozen(this)) {
+  } else if (del_count > 0 && ObjectIsFrozen(array)) {
     throw MakeTypeError("array_functions_on_frozen",
                         ["Array.prototype.splice"]);
   }
 
   var use_simple_splice = true;
-  if (IS_ARRAY(this) &&
+  if (IS_ARRAY(array) &&
       num_elements_to_add !== del_count) {
     // If we are only deleting/moving a few things near the end of the
     // array then the simple version is going to be faster, because it
     // doesn't touch most of the array.
-    var estimated_non_hole_elements = %EstimateNumberOfElements(this);
+    var estimated_non_hole_elements = %EstimateNumberOfElements(array);
     if (len > 20 && (estimated_non_hole_elements >> 2) < (len - start_i)) {
       use_simple_splice = false;
     }
   }
 
   if (use_simple_splice) {
-    SimpleSlice(this, start_i, del_count, len, deleted_elements);
-    SimpleMove(this, start_i, del_count, len, num_elements_to_add);
+    SimpleSlice(array, start_i, del_count, len, deleted_elements);
+    SimpleMove(array, start_i, del_count, len, num_elements_to_add);
   } else {
-    SmartSlice(this, start_i, del_count, len, deleted_elements);
-    SmartMove(this, start_i, del_count, len, num_elements_to_add);
+    SmartSlice(array, start_i, del_count, len, deleted_elements);
+    SmartMove(array, start_i, del_count, len, num_elements_to_add);
   }
 
   // Insert the arguments into the resulting array in
@@ -805,9 +809,9 @@ function ArraySplice(start, delete_count) {
   var arguments_index = 2;
   var arguments_length = %_ArgumentsLength();
   while (arguments_index < arguments_length) {
-    this[i++] = %_Arguments(arguments_index++);
+    array[i++] = %_Arguments(arguments_index++);
   }
-  this.length = len - del_count + num_elements_to_add;
+  array.length = len - del_count + num_elements_to_add;
 
   // Return the deleted elements.
   return deleted_elements;
index 771f80a..d926bd0 100644 (file)
@@ -6,32 +6,35 @@
 var values = [ 23, 4.2, true, false, 0/0 ];
 for (var i = 0; i < values.length; ++i) {
   var v = values[i];
+  Array.prototype.join.call(v);
   Array.prototype.pop.call(v);
   Array.prototype.push.call(v);
+  Array.prototype.reverse.call(v);
   Array.prototype.shift.call(v);
+  Array.prototype.slice.call(v);
+  Array.prototype.splice.call(v);
   Array.prototype.unshift.call(v);
 }
 
 // Test that ToObject on primitive values is only called once.
 var length_receiver, element_receiver;
-function length() { length_receiver = this; return 1; }
+function length() { length_receiver = this; return 2; }
 function element() { element_receiver = this; return "x"; }
 Object.defineProperty(Number.prototype, "length", { get:length, set:length });
 Object.defineProperty(Number.prototype, "0", { get:element, set:element });
 Object.defineProperty(Number.prototype, "1", { get:element, set:element });
+Object.defineProperty(Number.prototype, "2", { get:element, set:element });
+function test_receiver(expected, call_string) {
+  assertDoesNotThrow(call_string);
+  assertEquals(new Number(expected), length_receiver);
+  assertSame(length_receiver, element_receiver);
+}
 
-assertDoesNotThrow("Array.prototype.pop.call(23)");
-assertEquals(new Number(23), length_receiver);
-assertSame(length_receiver, element_receiver);
-
-assertDoesNotThrow("Array.prototype.push.call(42, 'y')");
-assertEquals(new Number(42), length_receiver);
-assertSame(length_receiver, element_receiver);
-
-assertDoesNotThrow("Array.prototype.shift.call(65)");
-assertEquals(new Number(65), length_receiver);
-assertSame(length_receiver, element_receiver);
-
-assertDoesNotThrow("Array.prototype.unshift.call(99, 'z')");
-assertEquals(new Number(99), length_receiver);
-assertSame(length_receiver, element_receiver);
+test_receiver(11, "Array.prototype.join.call(11)")
+test_receiver(23, "Array.prototype.pop.call(23)");
+test_receiver(42, "Array.prototype.push.call(42, 'y')");
+test_receiver(49, "Array.prototype.reverse.call(49)");
+test_receiver(65, "Array.prototype.shift.call(65)");
+test_receiver(77, "Array.prototype.slice.call(77, 1)");
+test_receiver(88, "Array.prototype.splice.call(88, 1, 1)");
+test_receiver(99, "Array.prototype.unshift.call(99, 'z')");