| Index: src/array.js
|
| diff --git a/src/array.js b/src/array.js
|
| index dcfcde51393cbe1d7fc4258c794c73ad01505a21..a3674e837d3ade7a59e7ddc159ff77b6b745ebd5 100644
|
| --- a/src/array.js
|
| +++ b/src/array.js
|
| @@ -395,23 +395,6 @@ function ArrayJoin(separator) {
|
| }
|
|
|
|
|
| -function ObservedArrayPop(n) {
|
| - n--;
|
| - var value = this[n];
|
| -
|
| - EnqueueSpliceRecord(this, n, [value], 1, 0);
|
| -
|
| - try {
|
| - BeginPerformSplice(this);
|
| - delete this[n];
|
| - this.length = n;
|
| - } finally {
|
| - EndPerformSplice(this);
|
| - }
|
| -
|
| - return value;
|
| -}
|
| -
|
| // Removes the last element from the array and returns it. See
|
| // ECMA-262, section 15.4.4.6.
|
| function ArrayPop() {
|
| @@ -425,10 +408,6 @@ function ArrayPop() {
|
| this.length = n;
|
| return;
|
| }
|
| -
|
| - if (%IsObserved(this))
|
| - return ObservedArrayPop.call(this, n);
|
| -
|
| n--;
|
| var value = this[n];
|
| delete this[n];
|
| @@ -445,6 +424,7 @@ function ObservedArrayPush() {
|
|
|
| try {
|
| BeginPerformSplice(this);
|
| +
|
| for (var i = 0; i < m; i++) {
|
| this[i+n] = %_Arguments(i);
|
| }
|
| @@ -578,22 +558,6 @@ function ArrayReverse() {
|
| }
|
|
|
|
|
| -function ObservedArrayShift(len) {
|
| - var first = this[0];
|
| -
|
| - EnqueueSpliceRecord(this, 0, [first], 1, 0);
|
| -
|
| - try {
|
| - BeginPerformSplice(this);
|
| - SimpleMove(this, 0, 1, len, 0);
|
| - this.length = len - 1;
|
| - } finally {
|
| - EndPerformSplice(this);
|
| - }
|
| -
|
| - return first;
|
| -}
|
| -
|
| function ArrayShift() {
|
| if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
|
| throw MakeTypeError("called_on_null_or_undefined",
|
| @@ -607,12 +571,9 @@ function ArrayShift() {
|
| return;
|
| }
|
|
|
| - if (%IsObserved(this))
|
| - return ObservedArrayShift.call(this, len);
|
| -
|
| var first = this[0];
|
|
|
| - if (IS_ARRAY(this)) {
|
| + if (IS_ARRAY(this) && !%IsObserved(this)) {
|
| SmartMove(this, 0, 1, len, 0);
|
| } else {
|
| SimpleMove(this, 0, 1, len, 0);
|
| @@ -623,25 +584,6 @@ function ArrayShift() {
|
| return first;
|
| }
|
|
|
| -function ObservedArrayUnshift() {
|
| - var len = TO_UINT32(this.length);
|
| - var num_arguments = %_ArgumentsLength();
|
| -
|
| - EnqueueSpliceRecord(this, 0, [], 0, num_arguments);
|
| -
|
| - try {
|
| - BeginPerformSplice(this);
|
| - SimpleMove(this, 0, 0, len, num_arguments);
|
| - for (var i = 0; i < num_arguments; i++) {
|
| - this[i] = %_Arguments(i);
|
| - }
|
| - this.length = len + num_arguments;
|
| - } finally {
|
| - EndPerformSplice(this);
|
| - }
|
| -
|
| - return len + num_arguments;
|
| -}
|
|
|
| function ArrayUnshift(arg1) { // length == 1
|
| if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
|
| @@ -649,13 +591,10 @@ function ArrayUnshift(arg1) { // length == 1
|
| ["Array.prototype.unshift"]);
|
| }
|
|
|
| - if (%IsObserved(this))
|
| - return ObservedArrayUnshift.apply(this, arguments);
|
| -
|
| var len = TO_UINT32(this.length);
|
| var num_arguments = %_ArgumentsLength();
|
|
|
| - if (IS_ARRAY(this)) {
|
| + if (IS_ARRAY(this) && !%IsObserved(this)) {
|
| SmartMove(this, 0, 0, len, num_arguments);
|
| } else {
|
| SimpleMove(this, 0, 0, len, num_arguments);
|
| @@ -716,100 +655,52 @@ function ArraySlice(start, end) {
|
| }
|
|
|
|
|
| -function ComputeSpliceStartIndex(start_i, len) {
|
| - if (start_i < 0) {
|
| - start_i += len;
|
| - return start_i < 0 ? 0 : start_i;
|
| +function ArraySplice(start, delete_count) {
|
| + if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
|
| + throw MakeTypeError("called_on_null_or_undefined",
|
| + ["Array.prototype.splice"]);
|
| }
|
|
|
| - return start_i > len ? len : start_i;
|
| -}
|
| + var num_arguments = %_ArgumentsLength();
|
|
|
| + var len = TO_UINT32(this.length);
|
| + var start_i = TO_INTEGER(start);
|
| +
|
| + if (start_i < 0) {
|
| + start_i += len;
|
| + if (start_i < 0) start_i = 0;
|
| + } else {
|
| + if (start_i > len) start_i = len;
|
| + }
|
|
|
| -function ComputeSpliceDeleteCount(delete_count, num_arguments, len, start_i) {
|
| // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
|
| // given as a request to delete all the elements from the start.
|
| // And it differs from the case of undefined delete count.
|
| // This does not follow ECMA-262, but we do the same for
|
| // compatibility.
|
| var del_count = 0;
|
| - if (num_arguments == 1)
|
| - return len - start_i;
|
| -
|
| - del_count = TO_INTEGER(delete_count);
|
| - if (del_count < 0)
|
| - return 0;
|
| -
|
| - if (del_count > len - start_i)
|
| - return len - start_i;
|
| -
|
| - return del_count;
|
| -}
|
| -
|
| + if (num_arguments == 1) {
|
| + del_count = len - start_i;
|
| + } else {
|
| + del_count = TO_INTEGER(delete_count);
|
| + if (del_count < 0) del_count = 0;
|
| + if (del_count > len - start_i) del_count = len - start_i;
|
| + }
|
|
|
| -function ObservedArraySplice(start, delete_count) {
|
| - var num_arguments = %_ArgumentsLength();
|
| - var len = TO_UINT32(this.length);
|
| - var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len);
|
| - var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len,
|
| - start_i);
|
| var deleted_elements = [];
|
| deleted_elements.length = del_count;
|
| - var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0;
|
| -
|
| - try {
|
| - BeginPerformSplice(this);
|
|
|
| - SimpleSlice(this, start_i, del_count, len, deleted_elements);
|
| - SimpleMove(this, start_i, del_count, len, num_elements_to_add);
|
| -
|
| - // Insert the arguments into the resulting array in
|
| - // place of the deleted elements.
|
| - var i = start_i;
|
| - var arguments_index = 2;
|
| - var arguments_length = %_ArgumentsLength();
|
| - while (arguments_index < arguments_length) {
|
| - this[i++] = %_Arguments(arguments_index++);
|
| - }
|
| - this.length = len - del_count + num_elements_to_add;
|
| -
|
| - } finally {
|
| - EndPerformSplice(this);
|
| - if (deleted_elements.length || num_elements_to_add) {
|
| - EnqueueSpliceRecord(this,
|
| - start_i,
|
| - deleted_elements.slice(),
|
| - deleted_elements.length,
|
| - num_elements_to_add);
|
| - }
|
| - }
|
| -
|
| - // Return the deleted elements.
|
| - return deleted_elements;
|
| -}
|
| -
|
| -
|
| -function ArraySplice(start, delete_count) {
|
| - if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
|
| - throw MakeTypeError("called_on_null_or_undefined",
|
| - ["Array.prototype.splice"]);
|
| + // Number of elements to add.
|
| + var num_additional_args = 0;
|
| + if (num_arguments > 2) {
|
| + num_additional_args = num_arguments - 2;
|
| }
|
|
|
| - if (%IsObserved(this))
|
| - return ObservedArraySplice.apply(this, arguments);
|
| -
|
| - var num_arguments = %_ArgumentsLength();
|
| - var len = TO_UINT32(this.length);
|
| - var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len);
|
| - var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len,
|
| - start_i);
|
| - var deleted_elements = [];
|
| - deleted_elements.length = del_count;
|
| - var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0;
|
| -
|
| var use_simple_splice = true;
|
| +
|
| if (IS_ARRAY(this) &&
|
| - num_elements_to_add !== del_count) {
|
| + !%IsObserved(this) &&
|
| + num_additional_args !== 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.
|
| @@ -821,10 +712,10 @@ function ArraySplice(start, delete_count) {
|
|
|
| if (use_simple_splice) {
|
| SimpleSlice(this, start_i, del_count, len, deleted_elements);
|
| - SimpleMove(this, start_i, del_count, len, num_elements_to_add);
|
| + SimpleMove(this, start_i, del_count, len, num_additional_args);
|
| } else {
|
| SmartSlice(this, start_i, del_count, len, deleted_elements);
|
| - SmartMove(this, start_i, del_count, len, num_elements_to_add);
|
| + SmartMove(this, start_i, del_count, len, num_additional_args);
|
| }
|
|
|
| // Insert the arguments into the resulting array in
|
| @@ -835,7 +726,7 @@ function ArraySplice(start, delete_count) {
|
| while (arguments_index < arguments_length) {
|
| this[i++] = %_Arguments(arguments_index++);
|
| }
|
| - this.length = len - del_count + num_elements_to_add;
|
| + this.length = len - del_count + num_additional_args;
|
|
|
| // Return the deleted elements.
|
| return deleted_elements;
|
|
|