| 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;
|
|
|