Revision: 9549
Author:   [email protected]
Date:     Fri Oct  7 07:07:33 2011
Log:      Fix some array functions to behave as specified.

This fixes the handling of primitives and the order of how side effects
are visible in some array functions as specified by the ES5.

[email protected]
TEST=test262

Review URL: http://codereview.chromium.org/8197002
http://code.google.com/p/v8/source/detail?r=9549

Modified:
 /branches/bleeding_edge/src/array.js
 /branches/bleeding_edge/test/test262/test262.status

=======================================
--- /branches/bleeding_edge/src/array.js        Wed Oct  5 00:08:23 2011
+++ /branches/bleeding_edge/src/array.js        Fri Oct  7 07:07:33 2011
@@ -1002,6 +1002,11 @@
     throw MakeTypeError("called_on_null_or_undefined",
                         ["Array.prototype.filter"]);
   }
+
+  // Pull out the length so that modifications to the length in the
+  // loop will not affect the looping and side effects are visible.
+  var array = ToObject(this);
+  var length = ToUint32(array.length);

   if (!IS_SPEC_FUNCTION(f)) {
     throw MakeTypeError('called_non_callable', [ f ]);
@@ -1009,15 +1014,13 @@
   if (IS_NULL_OR_UNDEFINED(receiver)) {
     receiver = %GetDefaultReceiver(f) || receiver;
   }
-  // Pull out the length so that modifications to the length in the
-  // loop will not affect the looping.
-  var length = ToUint32(this.length);
+
   var result = [];
   var result_length = 0;
   for (var i = 0; i < length; i++) {
-    var current = this[i];
-    if (!IS_UNDEFINED(current) || i in this) {
-      if (%_CallFunction(receiver, current, i, this, f)) {
+    var current = array[i];
+    if (!IS_UNDEFINED(current) || i in array) {
+      if (%_CallFunction(receiver, current, i, array, f)) {
         result[result_length++] = current;
       }
     }
@@ -1031,6 +1034,11 @@
     throw MakeTypeError("called_on_null_or_undefined",
                         ["Array.prototype.forEach"]);
   }
+
+  // Pull out the length so that modifications to the length in the
+  // loop will not affect the looping and side effects are visible.
+  var array = ToObject(this);
+  var length = TO_UINT32(array.length);

   if (!IS_SPEC_FUNCTION(f)) {
     throw MakeTypeError('called_non_callable', [ f ]);
@@ -1038,13 +1046,11 @@
   if (IS_NULL_OR_UNDEFINED(receiver)) {
     receiver = %GetDefaultReceiver(f) || receiver;
   }
-  // Pull out the length so that modifications to the length in the
-  // loop will not affect the looping.
-  var length =  TO_UINT32(this.length);
+
   for (var i = 0; i < length; i++) {
-    var current = this[i];
-    if (!IS_UNDEFINED(current) || i in this) {
-      %_CallFunction(receiver, current, i, this, f);
+    var current = array[i];
+    if (!IS_UNDEFINED(current) || i in array) {
+      %_CallFunction(receiver, current, i, array, f);
     }
   }
 }
@@ -1057,6 +1063,11 @@
     throw MakeTypeError("called_on_null_or_undefined",
                         ["Array.prototype.some"]);
   }
+
+  // Pull out the length so that modifications to the length in the
+  // loop will not affect the looping and side effects are visible.
+  var array = ToObject(this);
+  var length = TO_UINT32(array.length);

   if (!IS_SPEC_FUNCTION(f)) {
     throw MakeTypeError('called_non_callable', [ f ]);
@@ -1064,13 +1075,11 @@
   if (IS_NULL_OR_UNDEFINED(receiver)) {
     receiver = %GetDefaultReceiver(f) || receiver;
   }
-  // Pull out the length so that modifications to the length in the
-  // loop will not affect the looping.
-  var length = TO_UINT32(this.length);
+
   for (var i = 0; i < length; i++) {
-    var current = this[i];
-    if (!IS_UNDEFINED(current) || i in this) {
-      if (%_CallFunction(receiver, current, i, this, f)) return true;
+    var current = array[i];
+    if (!IS_UNDEFINED(current) || i in array) {
+      if (%_CallFunction(receiver, current, i, array, f)) return true;
     }
   }
   return false;
@@ -1082,6 +1091,11 @@
     throw MakeTypeError("called_on_null_or_undefined",
                         ["Array.prototype.every"]);
   }
+
+  // Pull out the length so that modifications to the length in the
+  // loop will not affect the looping and side effects are visible.
+  var array = ToObject(this);
+  var length = TO_UINT32(array.length);

   if (!IS_SPEC_FUNCTION(f)) {
     throw MakeTypeError('called_non_callable', [ f ]);
@@ -1089,13 +1103,11 @@
   if (IS_NULL_OR_UNDEFINED(receiver)) {
     receiver = %GetDefaultReceiver(f) || receiver;
   }
-  // Pull out the length so that modifications to the length in the
-  // loop will not affect the looping.
-  var length = TO_UINT32(this.length);
+
   for (var i = 0; i < length; i++) {
-    var current = this[i];
-    if (!IS_UNDEFINED(current) || i in this) {
-      if (!%_CallFunction(receiver, current, i, this, f)) return false;
+    var current = array[i];
+    if (!IS_UNDEFINED(current) || i in array) {
+      if (!%_CallFunction(receiver, current, i, array, f)) return false;
     }
   }
   return true;
@@ -1106,6 +1118,11 @@
     throw MakeTypeError("called_on_null_or_undefined",
                         ["Array.prototype.map"]);
   }
+
+  // Pull out the length so that modifications to the length in the
+  // loop will not affect the looping and side effects are visible.
+  var array = ToObject(this);
+  var length = TO_UINT32(array.length);

   if (!IS_SPEC_FUNCTION(f)) {
     throw MakeTypeError('called_non_callable', [ f ]);
@@ -1113,15 +1130,13 @@
   if (IS_NULL_OR_UNDEFINED(receiver)) {
     receiver = %GetDefaultReceiver(f) || receiver;
   }
-  // Pull out the length so that modifications to the length in the
-  // loop will not affect the looping.
-  var length = TO_UINT32(this.length);
+
   var result = new $Array();
   var accumulator = new InternalArray(length);
   for (var i = 0; i < length; i++) {
-    var current = this[i];
-    if (!IS_UNDEFINED(current) || i in this) {
-      accumulator[i] = %_CallFunction(receiver, current, i, this, f);
+    var current = array[i];
+    if (!IS_UNDEFINED(current) || i in array) {
+      accumulator[i] = %_CallFunction(receiver, current, i, array, f);
     }
   }
   %MoveArrayContents(accumulator, result);
@@ -1254,20 +1269,21 @@
     throw MakeTypeError("called_on_null_or_undefined",
                         ["Array.prototype.reduce"]);
   }
+
+  // Pull out the length so that modifications to the length in the
+  // loop will not affect the looping and side effects are visible.
+  var array = ToObject(this);
+  var length = ToUint32(array.length);

   if (!IS_SPEC_FUNCTION(callback)) {
     throw MakeTypeError('called_non_callable', [callback]);
   }

-  // Pull out the length so that modifications to the length in the
-  // loop will not affect the looping.
-  var length = ToUint32(this.length);
   var i = 0;
-
   find_initial: if (%_ArgumentsLength() < 2) {
     for (; i < length; i++) {
-      current = this[i];
-      if (!IS_UNDEFINED(current) || i in this) {
+      current = array[i];
+      if (!IS_UNDEFINED(current) || i in array) {
         i++;
         break find_initial;
       }
@@ -1277,9 +1293,9 @@

   var receiver = %GetDefaultReceiver(callback);
   for (; i < length; i++) {
-    var element = this[i];
-    if (!IS_UNDEFINED(element) || i in this) {
- current = %_CallFunction(receiver, current, element, i, this, callback);
+    var element = array[i];
+    if (!IS_UNDEFINED(element) || i in array) {
+ current = %_CallFunction(receiver, current, element, i, array, callback);
     }
   }
   return current;
@@ -1290,16 +1306,21 @@
     throw MakeTypeError("called_on_null_or_undefined",
                         ["Array.prototype.reduceRight"]);
   }
+
+  // Pull out the length so that side effects are visible before the
+  // callback function is checked.
+  var array = ToObject(this);
+  var length = ToUint32(array.length);

   if (!IS_SPEC_FUNCTION(callback)) {
     throw MakeTypeError('called_non_callable', [callback]);
   }
-  var i = ToUint32(this.length) - 1;
-
+
+  var i = length - 1;
   find_initial: if (%_ArgumentsLength() < 2) {
     for (; i >= 0; i--) {
-      current = this[i];
-      if (!IS_UNDEFINED(current) || i in this) {
+      current = array[i];
+      if (!IS_UNDEFINED(current) || i in array) {
         i--;
         break find_initial;
       }
@@ -1309,9 +1330,9 @@

   var receiver = %GetDefaultReceiver(callback);
   for (; i >= 0; i--) {
-    var element = this[i];
-    if (!IS_UNDEFINED(element) || i in this) {
- current = %_CallFunction(receiver, current, element, i, this, callback);
+    var element = array[i];
+    if (!IS_UNDEFINED(element) || i in array) {
+ current = %_CallFunction(receiver, current, element, i, array, callback);
     }
   }
   return current;
=======================================
--- /branches/bleeding_edge/test/test262/test262.status Fri Oct 7 00:30:45 2011 +++ /branches/bleeding_edge/test/test262/test262.status Fri Oct 7 07:07:33 2011
@@ -1106,27 +1106,6 @@
# Bug? Array.prototype.lastIndexOf terminates iteration on unhandled exception
 #      on an Array
 15.4.4.15-8-b-i-30: FAIL
-# Bug? Array.prototype.every applied to boolean primitive
-15.4.4.16-1-3: FAIL
-# Bug? Array.prototype.every applied to number primitive
-15.4.4.16-1-5: FAIL
-# Bug? Array.prototype.every applied to string primitive
-15.4.4.16-1-7: FAIL
-# Bug? Array.prototype.every - side effects produced by step 2 are visible when
-#      an exception occurs
-15.4.4.16-4-8: FAIL
-# Bug? Array.prototype.every - side effects produced by step 3 are visible when
-#      an exception occurs
-15.4.4.16-4-9: FAIL
-# Bug? Array.prototype.every - the exception is not thrown if exception was
-#      thrown by step 2
-15.4.4.16-4-10: FAIL
-# Bug? Array.prototype.every - the exception is not thrown if exception was
-#      thrown by step 3
-15.4.4.16-4-11: FAIL
-# Bug? Array.prototype.every - calling with no callbackfn is the same as passing
-#      undefined for callbackfn
-15.4.4.16-4-15: FAIL
 # Bug? Array.prototype.every - decreasing length of array does not delete
 #      non-configurable properties
 15.4.4.16-7-b-16: FAIL
@@ -1149,27 +1128,6 @@
# Bug? Array.prototype.every - element changed by getter on previous iterations
 #      is observed on an Array
 15.4.4.16-7-c-i-28: FAIL
-# Bug? Array.prototype.some applied to boolean primitive
-15.4.4.17-1-3: FAIL
-# Bug? Array.prototype.some applied to number primitive
-15.4.4.17-1-5: FAIL
-# Bug? Array.prototype.some applied to applied to string primitive
-15.4.4.17-1-7: FAIL
-# Bug? Array.prototype.some - side effects produced by step 2 are visible when
-#      an exception occurs
-15.4.4.17-4-8: FAIL
-# Bug? Array.prototype.some - side effects produced by step 3 are visible when
-#      an exception occurs
-15.4.4.17-4-9: FAIL
-# Bug? Array.prototype.some - the exception is not thrown if exception was
-#      thrown by step 2
-15.4.4.17-4-10: FAIL
-# Bug? Array.prototype.some - the exception is not thrown if exception was
-#      thrown by step 3
-15.4.4.17-4-11: FAIL
-# Bug? Array.prototype.some - calling with no callbackfn is the same as passing
-#      undefined for callbackfn
-15.4.4.17-4-15: FAIL
 # Bug? Array.prototype.some - decreasing length of array does not delete
 #      non-configurable properties
 15.4.4.17-7-b-16: FAIL
@@ -1192,27 +1150,6 @@
# Bug? Array.prototype.some - element changed by getter on previous iterations
 #      is observed on an Array
 15.4.4.17-7-c-i-28: FAIL
-# Bug? Array.prototype.forEach applied to boolean primitive
-15.4.4.18-1-3: FAIL
-# Bug? Array.prototype.forEach applied to number primitive
-15.4.4.18-1-5: FAIL
-# Bug? Array.prototype.forEach applied to string primitive
-15.4.4.18-1-7: FAIL
-# Bug? Array.prototype.forEach - side effects produced by step 2 are visible
-#      when an exception occurs
-15.4.4.18-4-8: FAIL
-# Bug? Array.prototype.forEach - side effects produced by step 3 are visible
-#      when an exception occurs
-15.4.4.18-4-9: FAIL
-# Bug? Array.prototype.forEach - the exception is not thrown if exception was
-#      thrown by step 2
-15.4.4.18-4-10: FAIL
-# Bug? Array.prototype.forEach - the exception is not thrown if exception was
-#      thrown by step 3
-15.4.4.18-4-11: FAIL
-# Bug? Array.prototype.forEach - calling with no callbackfn is the same as
-#      passing undefined for callbackfn
-15.4.4.18-4-15: FAIL
 # Bug? Array.prototype.forEach - decreasing length of array does not delete
 #      non-configurable properties
 15.4.4.18-7-b-16: FAIL
@@ -1235,27 +1172,6 @@
 # Bug? Array.prototype.forEach - element changed by getter on previous
 #      iterations is observed on an Array
 15.4.4.18-7-c-i-28: FAIL
-# Bug? Array.prototype.map - applied to boolean primitive
-15.4.4.19-1-3: FAIL
-# Bug? Array.prototype.map - applied to number primitive
-15.4.4.19-1-5: FAIL
-# Bug? Array.prototype.map - applied to string primitive
-15.4.4.19-1-7: FAIL
-# Bug? Array.prototype.map - Side effects produced by step 2 are visible when an
-#      exception occurs
-15.4.4.19-4-8: FAIL
-# Bug? Array.prototype.map - Side effects produced by step 3 are visible when an
-#      exception occurs
-15.4.4.19-4-9: FAIL
-# Bug? Array.prototype.map - the exception is not thrown if exception was thrown
-#      by step 2
-15.4.4.19-4-10: FAIL
-# Bug? Array.prototype.map - the exception is not thrown if exception was thrown
-#      by step 3
-15.4.4.19-4-11: FAIL
-# Bug? Array.prototype.map - calling with no callbackfn is the same as passing
-#      undefined for callbackfn
-15.4.4.19-4-15: FAIL
 # Bug? Array.prototype.map - decreasing length of array does not delete
 #      non-configurable properties
 15.4.4.19-8-b-16: FAIL
@@ -1278,27 +1194,6 @@
# Bug? Array.prototype.map - element changed by getter on previous iterations is
 #      observed on an Array
 15.4.4.19-8-c-i-28: FAIL
-# Bug? Array.prototype.filter applied to boolean primitive
-15.4.4.20-1-3: FAIL
-# Bug? Array.prototype.filter applied to number primitive
-15.4.4.20-1-5: FAIL
-# Bug? Array.prototype.filter applied to string primitive
-15.4.4.20-1-7: FAIL
-# Bug? Array.prototype.filter - side effects produced by step 2 are visible when
-#      an exception occurs
-15.4.4.20-4-8: FAIL
-# Bug? Array.prototype.filter - side effects produced by step 3 are visible when
-#      an exception occurs
-15.4.4.20-4-9: FAIL
-# Bug? Array.prototype.filter - the exception is not thrown if exception was
-#      thrown by step 2
-15.4.4.20-4-10: FAIL
-# Bug? Array.prototype.filter - the exception is not thrown if exception was
-#      thrown by step 3
-15.4.4.20-4-11: FAIL
-# Bug? Array.prototype.filter - calling with no callbackfn is the same as
-#      passing undefined for callbackfn
-15.4.4.20-4-15: FAIL
 # Bug? Array.prototype.filter - properties can be added to prototype after
 #      current position are visited on an Array-like object
 15.4.4.20-9-b-6: FAIL
@@ -1333,54 +1228,12 @@
# Bug? Array.prototype.filter - element changed by getter on previous iterations
 #      is observed on an Array
 15.4.4.20-9-c-i-28: FAIL
-# Bug? Array.prototype.reduce applied to boolean primitive
-15.4.4.21-1-3: FAIL
-# Bug? Array.prototype.reduce applied to number primitive
-15.4.4.21-1-5: FAIL
-# Bug? Array.prototype.reduce applied to string primitive
-15.4.4.21-1-7: FAIL
-# Bug? Array.prototype.reduce - side effects produced by step 2 are visible when
-#      an exception occurs
-15.4.4.21-4-8: FAIL
-# Bug? Array.prototype.reduce - side effects produced by step 3 are visible when
-#      an exception occurs
-15.4.4.21-4-9: FAIL
-# Bug? Array.prototype.reduce - the exception is not thrown if exception was
-#      thrown by step 2
-15.4.4.21-4-10: FAIL
-# Bug? Array.prototype.reduce - the exception is not thrown if exception was
-#      thrown by step 3
-15.4.4.21-4-11: FAIL
-# Bug? Array.prototype.reduce - calling with no callbackfn is the same as
-#      passing undefined for callbackfn
-15.4.4.21-4-15: FAIL
# Bug? Array.prototype.reduce - decreasing length of array in step 8 does not
 #      delete non-configurable properties
 15.4.4.21-9-b-16: FAIL
 # Bug? Array.prototype.reduce - decreasing length of array does not delete
 #      non-configurable properties
 15.4.4.21-9-b-29: FAIL
-# Bug? Array.prototype.reduceRight applied to boolean primitive
-15.4.4.22-1-3: FAIL
-# Bug? Array.prototype.reduceRight applied to number primitive
-15.4.4.22-1-5: FAIL
-# Bug? Array.prototype.reduceRight applied to string primitive
-15.4.4.22-1-7: FAIL
-# Bug? Array.prototype.reduceRight - side effects produced by step 2 are visible
-#      when an exception occurs
-15.4.4.22-4-8: FAIL
-# Bug? Array.prototype.reduceRight - side effects produced by step 3 are visible
-#      when an exception occurs
-15.4.4.22-4-9: FAIL
-# Bug? Array.prototype.reduceRight - the exception is not thrown if exception
-#      was thrown by step 2
-15.4.4.22-4-10: FAIL
-# Bug? Array.prototype.reduceRight - the exception is not thrown if exception
-#      was thrown by step 3
-15.4.4.22-4-11: FAIL
-# Bug? Array.prototype.reduceRight - calling with no callbackfn is the same as
-#      passing undefined for callbackfn
-15.4.4.22-4-15: FAIL
# Bug? Array.prototype.reduceRight - element to be retrieved is own accessor
 #      property that overrides an inherited data property on an Array
 15.4.4.22-8-b-iii-1-12: FAIL

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to