Index: src/array.js |
diff --git a/src/array.js b/src/array.js |
index 397adc7582671109f98aa729160704f109a3e21d..84d29d1239aa9c21ca251fd4d4d1a43575cd4d3f 100644 |
--- a/src/array.js |
+++ b/src/array.js |
@@ -1003,21 +1003,24 @@ function ArrayFilter(f, receiver) { |
["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 ]); |
} |
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; |
} |
} |
@@ -1032,19 +1035,22 @@ function ArrayForEach(f, receiver) { |
["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 ]); |
} |
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); |
} |
} |
} |
@@ -1058,19 +1064,22 @@ function ArraySome(f, receiver) { |
["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 ]); |
} |
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; |
@@ -1083,19 +1092,22 @@ function ArrayEvery(f, receiver) { |
["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 ]); |
} |
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; |
@@ -1107,21 +1119,24 @@ function ArrayMap(f, receiver) { |
["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 ]); |
} |
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); |
@@ -1255,19 +1270,20 @@ function ArrayReduce(callback, current) { |
["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 @@ function ArrayReduce(callback, current) { |
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; |
@@ -1291,15 +1307,20 @@ function ArrayReduceRight(callback, current) { |
["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 @@ function ArrayReduceRight(callback, current) { |
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; |