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