summaryrefslogtreecommitdiff
path: root/deps/v8/src/js/array.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/js/array.js')
-rw-r--r--deps/v8/src/js/array.js497
1 files changed, 88 insertions, 409 deletions
diff --git a/deps/v8/src/js/array.js b/deps/v8/src/js/array.js
index 1406df336d..d10e7f18b5 100644
--- a/deps/v8/src/js/array.js
+++ b/deps/v8/src/js/array.js
@@ -11,77 +11,46 @@
// -------------------------------------------------------------------
// Imports
-var AddIndexedProperty;
-var FLAG_harmony_species;
var GetIterator;
var GetMethod;
var GlobalArray = global.Array;
var InternalArray = utils.InternalArray;
var InternalPackedArray = utils.InternalPackedArray;
-var MakeTypeError;
var MaxSimple;
var MinSimple;
-var ObjectDefineProperty;
var ObjectHasOwnProperty;
var ObjectToString = utils.ImportNow("object_to_string");
-var ObserveBeginPerformSplice;
-var ObserveEndPerformSplice;
-var ObserveEnqueueSpliceRecord;
var iteratorSymbol = utils.ImportNow("iterator_symbol");
+var speciesSymbol = utils.ImportNow("species_symbol");
var unscopablesSymbol = utils.ImportNow("unscopables_symbol");
utils.Import(function(from) {
- AddIndexedProperty = from.AddIndexedProperty;
GetIterator = from.GetIterator;
GetMethod = from.GetMethod;
- MakeTypeError = from.MakeTypeError;
MaxSimple = from.MaxSimple;
MinSimple = from.MinSimple;
- ObjectDefineProperty = from.ObjectDefineProperty;
ObjectHasOwnProperty = from.ObjectHasOwnProperty;
- ObserveBeginPerformSplice = from.ObserveBeginPerformSplice;
- ObserveEndPerformSplice = from.ObserveEndPerformSplice;
- ObserveEnqueueSpliceRecord = from.ObserveEnqueueSpliceRecord;
-});
-
-utils.ImportFromExperimental(function(from) {
- FLAG_harmony_species = from.FLAG_harmony_species;
});
// -------------------------------------------------------------------
function ArraySpeciesCreate(array, length) {
- var constructor;
- if (FLAG_harmony_species) {
- constructor = %ArraySpeciesConstructor(array);
- } else {
- constructor = GlobalArray;
- }
+ length = INVERT_NEG_ZERO(length);
+ var constructor = %ArraySpeciesConstructor(array);
return new constructor(length);
}
-function DefineIndexedProperty(array, i, value) {
- if (FLAG_harmony_species) {
- var result = ObjectDefineProperty(array, i, {
- value: value, writable: true, configurable: true, enumerable: true
- });
- if (!result) throw MakeTypeError(kStrictCannotAssign, i);
- } else {
- AddIndexedProperty(array, i, value);
- }
-}
-
function KeySortCompare(a, b) {
return a - b;
}
function GetSortedArrayKeys(array, indices) {
if (IS_NUMBER(indices)) {
- var keys = new InternalArray();
// It's an interval
var limit = indices;
+ var keys = new InternalArray();
for (var i = 0; i < limit; ++i) {
var e = array[i];
if (!IS_UNDEFINED(e) || i in array) {
@@ -94,26 +63,24 @@ function GetSortedArrayKeys(array, indices) {
}
-function SparseJoinWithSeparatorJS(array, keys, length, convert, separator) {
+function SparseJoinWithSeparatorJS(array, keys, length, use_locale, separator) {
var keys_length = keys.length;
var elements = new InternalArray(keys_length * 2);
for (var i = 0; i < keys_length; i++) {
var key = keys[i];
- var e = array[key];
elements[i * 2] = key;
- elements[i * 2 + 1] = IS_STRING(e) ? e : convert(e);
+ elements[i * 2 + 1] = ConvertToString(use_locale, array[key]);
}
return %SparseJoinWithSeparator(elements, length, separator);
}
// Optimized for sparse arrays if separator is ''.
-function SparseJoin(array, keys, convert) {
+function SparseJoin(array, keys, use_locale) {
var keys_length = keys.length;
var elements = new InternalArray(keys_length);
for (var i = 0; i < keys_length; i++) {
- var e = array[keys[i]];
- elements[i] = IS_STRING(e) ? e : convert(e);
+ elements[i] = ConvertToString(use_locale, array[keys[i]]);
}
return %StringBuilderConcat(elements, keys_length, '');
}
@@ -123,8 +90,7 @@ function UseSparseVariant(array, length, is_array, touched) {
// Only use the sparse variant on arrays that are likely to be sparse and the
// number of elements touched in the operation is relatively small compared to
// the overall size of the array.
- if (!is_array || length < 1000 || %IsObserved(array) ||
- %HasComplexElements(array)) {
+ if (!is_array || length < 1000 || %HasComplexElements(array)) {
return false;
}
if (!%_IsSmi(length)) {
@@ -167,60 +133,38 @@ function StackHas(stack, v) {
// join invocations.
var visited_arrays = new Stack();
-function DoJoin(array, length, is_array, separator, convert) {
+function DoJoin(array, length, is_array, separator, use_locale) {
if (UseSparseVariant(array, length, is_array, length)) {
%NormalizeElements(array);
var keys = GetSortedArrayKeys(array, %GetArrayKeys(array, length));
if (separator === '') {
if (keys.length === 0) return '';
- return SparseJoin(array, keys, convert);
+ return SparseJoin(array, keys, use_locale);
} else {
- return SparseJoinWithSeparatorJS(array, keys, length, convert, separator);
+ return SparseJoinWithSeparatorJS(
+ array, keys, length, use_locale, separator);
}
}
// Fast case for one-element arrays.
if (length === 1) {
- var e = array[0];
- return IS_STRING(e) ? e : convert(e);
+ return ConvertToString(use_locale, array[0]);
}
// Construct an array for the elements.
var elements = new InternalArray(length);
+ for (var i = 0; i < length; i++) {
+ elements[i] = ConvertToString(use_locale, array[i]);
+ }
- // We pull the empty separator check outside the loop for speed!
if (separator === '') {
- for (var i = 0; i < length; i++) {
- var e = array[i];
- elements[i] = IS_STRING(e) ? e : convert(e);
- }
return %StringBuilderConcat(elements, length, '');
- }
- // Non-empty separator case.
- // If the first element is a number then use the heuristic that the
- // remaining elements are also likely to be numbers.
- var e = array[0];
- if (IS_NUMBER(e)) {
- elements[0] = %_NumberToString(e);
- for (var i = 1; i < length; i++) {
- e = array[i];
- if (IS_NUMBER(e)) {
- elements[i] = %_NumberToString(e);
- } else {
- elements[i] = IS_STRING(e) ? e : convert(e);
- }
- }
} else {
- elements[0] = IS_STRING(e) ? e : convert(e);
- for (var i = 1; i < length; i++) {
- e = array[i];
- elements[i] = IS_STRING(e) ? e : convert(e);
- }
+ return %StringBuilderJoin(elements, length, separator);
}
- return %StringBuilderJoin(elements, length, separator);
}
-function Join(array, length, separator, convert) {
+function Join(array, length, separator, use_locale) {
if (length === 0) return '';
var is_array = IS_ARRAY(array);
@@ -234,7 +178,7 @@ function Join(array, length, separator, convert) {
// Attempt to convert the elements.
try {
- return DoJoin(array, length, is_array, separator, convert);
+ return DoJoin(array, length, is_array, separator, use_locale);
} finally {
// Make sure to remove the last element of the visited array no
// matter what happens.
@@ -243,15 +187,9 @@ function Join(array, length, separator, convert) {
}
-function ConvertToString(x) {
+function ConvertToString(use_locale, x) {
if (IS_NULL_OR_UNDEFINED(x)) return '';
- return TO_STRING(x);
-}
-
-
-function ConvertToLocaleString(e) {
- if (IS_NULL_OR_UNDEFINED(e)) return '';
- return TO_STRING(e.toLocaleString());
+ return TO_STRING(use_locale ? x.toLocaleString() : x);
}
@@ -265,7 +203,7 @@ function SparseSlice(array, start_i, del_count, len, deleted_elements) {
for (var i = start_i; i < limit; ++i) {
var current = array[i];
if (!IS_UNDEFINED(current) || i in array) {
- DefineIndexedProperty(deleted_elements, i - start_i, current);
+ %CreateDataProperty(deleted_elements, i - start_i, current);
}
}
} else {
@@ -275,7 +213,7 @@ function SparseSlice(array, start_i, del_count, len, deleted_elements) {
if (key >= start_i) {
var current = array[key];
if (!IS_UNDEFINED(current) || key in array) {
- DefineIndexedProperty(deleted_elements, key - start_i, current);
+ %CreateDataProperty(deleted_elements, key - start_i, current);
}
}
}
@@ -347,19 +285,17 @@ function SparseMove(array, start_i, del_count, len, num_additional_args) {
// because the receiver is not an array (so we have no choice) or because we
// know we are not deleting or moving a lot of elements.
function SimpleSlice(array, start_i, del_count, len, deleted_elements) {
- var is_array = IS_ARRAY(array);
for (var i = 0; i < del_count; i++) {
var index = start_i + i;
- if (HAS_INDEX(array, index, is_array)) {
+ if (index in array) {
var current = array[index];
- DefineIndexedProperty(deleted_elements, i, current);
+ %CreateDataProperty(deleted_elements, i, current);
}
}
}
function SimpleMove(array, start_i, del_count, len, num_additional_args) {
- var is_array = IS_ARRAY(array);
if (num_additional_args !== del_count) {
// Move the existing elements after the elements to be deleted
// to the right position in the resulting array.
@@ -367,7 +303,7 @@ function SimpleMove(array, start_i, del_count, len, num_additional_args) {
for (var i = len - del_count; i > start_i; i--) {
var from_index = i + del_count - 1;
var to_index = i + num_additional_args - 1;
- if (HAS_INDEX(array, from_index, is_array)) {
+ if (from_index in array) {
array[to_index] = array[from_index];
} else {
delete array[to_index];
@@ -377,7 +313,7 @@ function SimpleMove(array, start_i, del_count, len, num_additional_args) {
for (var i = start_i; i < len - del_count; i++) {
var from_index = i + del_count;
var to_index = i + num_additional_args;
- if (HAS_INDEX(array, from_index, is_array)) {
+ if (from_index in array) {
array[to_index] = array[from_index];
} else {
delete array[to_index];
@@ -400,7 +336,7 @@ function ArrayToString() {
if (IS_ARRAY(this)) {
func = this.join;
if (func === ArrayJoin) {
- return Join(this, this.length, ',', ConvertToString);
+ return Join(this, this.length, ',', false);
}
array = this;
} else {
@@ -415,9 +351,7 @@ function ArrayToString() {
function InnerArrayToLocaleString(array, length) {
- var len = TO_LENGTH(length);
- if (len === 0) return "";
- return Join(array, len, ',', ConvertToLocaleString);
+ return Join(array, TO_LENGTH(length), ',', true);
}
@@ -442,7 +376,7 @@ function InnerArrayJoin(separator, array, length) {
return TO_STRING(e);
}
- return Join(array, length, separator, ConvertToString);
+ return Join(array, length, separator, false);
}
@@ -456,23 +390,6 @@ function ArrayJoin(separator) {
}
-function ObservedArrayPop(n) {
- n--;
- var value = this[n];
-
- try {
- ObserveBeginPerformSplice(this);
- delete this[n];
- this.length = n;
- } finally {
- ObserveEndPerformSplice(this);
- ObserveEnqueueSpliceRecord(this, n, [value], 0);
- }
-
- return value;
-}
-
-
// Removes the last element from the array and returns it. See
// ECMA-262, section 15.4.4.6.
function ArrayPop() {
@@ -485,9 +402,6 @@ function ArrayPop() {
return;
}
- if (%IsObserved(array))
- return ObservedArrayPop.call(array, n);
-
n--;
var value = array[n];
%DeleteProperty_Strict(array, n);
@@ -496,46 +410,19 @@ function ArrayPop() {
}
-function ObservedArrayPush() {
- var n = TO_LENGTH(this.length);
- var m = arguments.length;
-
- try {
- ObserveBeginPerformSplice(this);
- for (var i = 0; i < m; i++) {
- this[i+n] = arguments[i];
- }
- var new_length = n + m;
- this.length = new_length;
- } finally {
- ObserveEndPerformSplice(this);
- ObserveEnqueueSpliceRecord(this, n, [], m);
- }
-
- return new_length;
-}
-
-
// Appends the arguments to the end of the array and returns the new
// length of the array. See ECMA-262, section 15.4.4.7.
function ArrayPush() {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.push");
- if (%IsObserved(this))
- return ObservedArrayPush.apply(this, arguments);
-
var array = TO_OBJECT(this);
var n = TO_LENGTH(array.length);
var m = arguments.length;
- // It appears that there is no enforced, absolute limit on the number of
- // arguments, but it would surely blow the stack to use 2**30 or more.
- // To avoid integer overflow, do the comparison to the max safe integer
- // after subtracting 2**30 from both sides. (2**31 would seem like a
- // natural value, but it is negative in JS, and 2**32 is 1.)
- if (m > (1 << 30) || (n - (1 << 30)) + m > kMaxSafeInteger - (1 << 30)) {
- throw MakeTypeError(kPushPastSafeLength, m, n);
- }
+ // Subtract n from kMaxSafeInteger rather than testing m + n >
+ // kMaxSafeInteger. n may already be kMaxSafeInteger. In that case adding
+ // e.g., 1 would not be safe.
+ if (m > kMaxSafeInteger - n) throw %make_type_error(kPushPastSafeLength, m, n);
for (var i = 0; i < m; i++) {
array[i+n] = arguments[i];
@@ -646,22 +533,6 @@ function ArrayReverse() {
}
-function ObservedArrayShift(len) {
- var first = this[0];
-
- try {
- ObserveBeginPerformSplice(this);
- SimpleMove(this, 0, 1, len, 0);
- this.length = len - 1;
- } finally {
- ObserveEndPerformSplice(this);
- ObserveEnqueueSpliceRecord(this, 0, [first], 0);
- }
-
- return first;
-}
-
-
function ArrayShift() {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.shift");
@@ -673,10 +544,7 @@ function ArrayShift() {
return;
}
- if (%object_is_sealed(array)) throw MakeTypeError(kArrayFunctionsOnSealed);
-
- if (%IsObserved(array))
- return ObservedArrayShift.call(array, len);
+ if (%object_is_sealed(array)) throw %make_type_error(kArrayFunctionsOnSealed);
var first = array[0];
@@ -692,33 +560,9 @@ function ArrayShift() {
}
-function ObservedArrayUnshift() {
- var len = TO_LENGTH(this.length);
- var num_arguments = arguments.length;
-
- try {
- ObserveBeginPerformSplice(this);
- SimpleMove(this, 0, 0, len, num_arguments);
- for (var i = 0; i < num_arguments; i++) {
- this[i] = arguments[i];
- }
- var new_length = len + num_arguments;
- this.length = new_length;
- } finally {
- ObserveEndPerformSplice(this);
- ObserveEnqueueSpliceRecord(this, 0, [], num_arguments);
- }
-
- return new_length;
-}
-
-
function ArrayUnshift(arg1) { // length == 1
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift");
- if (%IsObserved(this))
- return ObservedArrayUnshift.apply(this, arguments);
-
var array = TO_OBJECT(this);
var len = TO_LENGTH(array.length);
var num_arguments = arguments.length;
@@ -770,7 +614,7 @@ function ArraySlice(start, end) {
if (UseSparseVariant(array, len, IS_ARRAY(array), end_i - start_i)) {
%NormalizeElements(array);
- %NormalizeElements(result);
+ if (IS_ARRAY(result)) %NormalizeElements(result);
SparseSlice(array, start_i, end_i - start_i, len, result);
} else {
SimpleSlice(array, start_i, end_i - start_i, len, result);
@@ -813,53 +657,9 @@ function ComputeSpliceDeleteCount(delete_count, num_arguments, len, start_i) {
}
-function ObservedArraySplice(start, delete_count) {
- var num_arguments = arguments.length;
- var len = TO_LENGTH(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 {
- ObserveBeginPerformSplice(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 = arguments.length;
- while (arguments_index < arguments_length) {
- this[i++] = arguments[arguments_index++];
- }
- this.length = len - del_count + num_elements_to_add;
-
- } finally {
- ObserveEndPerformSplice(this);
- if (deleted_elements.length || num_elements_to_add) {
- ObserveEnqueueSpliceRecord(this,
- start_i,
- deleted_elements.slice(),
- num_elements_to_add);
- }
- }
-
- // Return the deleted elements.
- return deleted_elements;
-}
-
-
function ArraySplice(start, delete_count) {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.splice");
- if (%IsObserved(this))
- return ObservedArraySplice.apply(this, arguments);
-
var num_arguments = arguments.length;
var array = TO_OBJECT(this);
var len = TO_LENGTH(array.length);
@@ -871,9 +671,9 @@ function ArraySplice(start, delete_count) {
var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0;
if (del_count != num_elements_to_add && %object_is_sealed(array)) {
- throw MakeTypeError(kArrayFunctionsOnSealed);
+ throw %make_type_error(kArrayFunctionsOnSealed);
} else if (del_count > 0 && %object_is_frozen(array)) {
- throw MakeTypeError(kArrayFunctionsOnFrozen);
+ throw %make_type_error(kArrayFunctionsOnFrozen);
}
var changed_elements = del_count;
@@ -884,7 +684,7 @@ function ArraySplice(start, delete_count) {
}
if (UseSparseVariant(array, len, IS_ARRAY(array), changed_elements)) {
%NormalizeElements(array);
- %NormalizeElements(deleted_elements);
+ if (IS_ARRAY(deleted_elements)) %NormalizeElements(deleted_elements);
SparseSlice(array, start_i, del_count, len, deleted_elements);
SparseMove(array, start_i, del_count, len, num_elements_to_add);
} else {
@@ -1048,7 +848,8 @@ function InnerArraySort(array, length, comparefn) {
// of a prototype property.
var CopyFromPrototype = function CopyFromPrototype(obj, length) {
var max = 0;
- for (var proto = %_GetPrototype(obj); proto; proto = %_GetPrototype(proto)) {
+ for (var proto = %object_get_prototype_of(obj); proto;
+ proto = %object_get_prototype_of(proto)) {
var indices = IS_PROXY(proto) ? length : %GetArrayKeys(proto, length);
if (IS_NUMBER(indices)) {
// It's an interval.
@@ -1076,7 +877,8 @@ function InnerArraySort(array, length, comparefn) {
// where a prototype of obj has an element. I.e., shadow all prototype
// elements in that range.
var ShadowPrototypeElements = function(obj, from, to) {
- for (var proto = %_GetPrototype(obj); proto; proto = %_GetPrototype(proto)) {
+ for (var proto = %object_get_prototype_of(obj); proto;
+ proto = %object_get_prototype_of(proto)) {
var indices = IS_PROXY(proto) ? to : %GetArrayKeys(proto, to);
if (IS_NUMBER(indices)) {
// It's an interval.
@@ -1143,7 +945,7 @@ function InnerArraySort(array, length, comparefn) {
}
for (i = length - num_holes; i < length; i++) {
// For compatability with Webkit, do not expose elements in the prototype.
- if (i in %_GetPrototype(obj)) {
+ if (i in %object_get_prototype_of(obj)) {
obj[i] = UNDEFINED;
} else {
delete obj[i];
@@ -1174,9 +976,9 @@ function InnerArraySort(array, length, comparefn) {
var num_non_undefined = %RemoveArrayHoles(array, length);
if (num_non_undefined == -1) {
- // The array is observed, or there were indexed accessors in the array.
+ // There were indexed accessors in the array.
// Move array holes and undefineds to the end using a Javascript function
- // that is safe in the presence of accessors and is observable.
+ // that is safe in the presence of accessors.
num_non_undefined = SafeRemoveArrayHoles(array);
}
@@ -1206,12 +1008,11 @@ function ArraySort(comparefn) {
// or delete elements from the array.
function InnerArrayFilter(f, receiver, array, length, result) {
var result_length = 0;
- var is_array = IS_ARRAY(array);
for (var i = 0; i < length; i++) {
- if (HAS_INDEX(array, i, is_array)) {
+ if (i in array) {
var element = array[i];
if (%_Call(f, receiver, element, i, array)) {
- DefineIndexedProperty(result, result_length, element);
+ %CreateDataProperty(result, result_length, element);
result_length++;
}
}
@@ -1228,26 +1029,25 @@ function ArrayFilter(f, receiver) {
// loop will not affect the looping and side effects are visible.
var array = TO_OBJECT(this);
var length = TO_LENGTH(array.length);
- if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
+ if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
var result = ArraySpeciesCreate(array, 0);
return InnerArrayFilter(f, receiver, array, length, result);
}
function InnerArrayForEach(f, receiver, array, length) {
- if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
+ if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
- var is_array = IS_ARRAY(array);
if (IS_UNDEFINED(receiver)) {
for (var i = 0; i < length; i++) {
- if (HAS_INDEX(array, i, is_array)) {
+ if (i in array) {
var element = array[i];
f(element, i, array);
}
}
} else {
for (var i = 0; i < length; i++) {
- if (HAS_INDEX(array, i, is_array)) {
+ if (i in array) {
var element = array[i];
%_Call(f, receiver, element, i, array);
}
@@ -1268,11 +1068,10 @@ function ArrayForEach(f, receiver) {
function InnerArraySome(f, receiver, array, length) {
- if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
+ if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
- var is_array = IS_ARRAY(array);
for (var i = 0; i < length; i++) {
- if (HAS_INDEX(array, i, is_array)) {
+ if (i in array) {
var element = array[i];
if (%_Call(f, receiver, element, i, array)) return true;
}
@@ -1295,11 +1094,10 @@ function ArraySome(f, receiver) {
function InnerArrayEvery(f, receiver, array, length) {
- if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
+ if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
- var is_array = IS_ARRAY(array);
for (var i = 0; i < length; i++) {
- if (HAS_INDEX(array, i, is_array)) {
+ if (i in array) {
var element = array[i];
if (!%_Call(f, receiver, element, i, array)) return false;
}
@@ -1325,91 +1123,24 @@ function ArrayMap(f, receiver) {
// loop will not affect the looping and side effects are visible.
var array = TO_OBJECT(this);
var length = TO_LENGTH(array.length);
- if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
+ if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
var result = ArraySpeciesCreate(array, length);
- var is_array = IS_ARRAY(array);
for (var i = 0; i < length; i++) {
- if (HAS_INDEX(array, i, is_array)) {
+ if (i in array) {
var element = array[i];
- DefineIndexedProperty(result, i, %_Call(f, receiver, element, i, array));
+ %CreateDataProperty(result, i, %_Call(f, receiver, element, i, array));
}
}
return result;
}
-// For .indexOf, we don't need to pass in the number of arguments
-// at the callsite since ToInteger(undefined) == 0; however, for
-// .lastIndexOf, we need to pass it, since the behavior for passing
-// undefined is 0 but for not including the argument is length-1.
-function InnerArrayIndexOf(array, element, index, length) {
- if (length == 0) return -1;
- if (IS_UNDEFINED(index)) {
- index = 0;
- } else {
- index = TO_INTEGER(index) + 0; // Add 0 to convert -0 to 0
- // If index is negative, index from the end of the array.
- if (index < 0) {
- index = length + index;
- // If index is still negative, search the entire array.
- if (index < 0) index = 0;
- }
- }
- var min = index;
- var max = length;
- if (UseSparseVariant(array, length, IS_ARRAY(array), max - min)) {
- %NormalizeElements(array);
- var indices = %GetArrayKeys(array, length);
- if (IS_NUMBER(indices)) {
- // It's an interval.
- max = indices; // Capped by length already.
- // Fall through to loop below.
- } else {
- if (indices.length == 0) return -1;
- // Get all the keys in sorted order.
- var sortedKeys = GetSortedArrayKeys(array, indices);
- var n = sortedKeys.length;
- var i = 0;
- while (i < n && sortedKeys[i] < index) i++;
- while (i < n) {
- var key = sortedKeys[i];
- if (array[key] === element) return key;
- i++;
- }
- return -1;
- }
- }
- // Lookup through the array.
- if (!IS_UNDEFINED(element)) {
- for (var i = min; i < max; i++) {
- if (array[i] === element) return i;
- }
- return -1;
- }
- // Lookup through the array.
- for (var i = min; i < max; i++) {
- if (IS_UNDEFINED(array[i]) && i in array) {
- return i;
- }
- }
- return -1;
-}
-
-
-function ArrayIndexOf(element, index) {
- CHECK_OBJECT_COERCIBLE(this, "Array.prototype.indexOf");
-
- var length = TO_LENGTH(this.length);
- return InnerArrayIndexOf(this, element, index, length);
-}
-
-
function InnerArrayLastIndexOf(array, element, index, length, argumentsLength) {
if (length == 0) return -1;
if (argumentsLength < 2) {
index = length - 1;
} else {
- index = TO_INTEGER(index) + 0; // Add 0 to convert -0 to 0
+ index = INVERT_NEG_ZERO(TO_INTEGER(index));
// If index is negative, index from end of the array.
if (index < 0) index += length;
// If index is still negative, do not search the array.
@@ -1465,23 +1196,22 @@ function ArrayLastIndexOf(element, index) {
function InnerArrayReduce(callback, current, array, length, argumentsLength) {
if (!IS_CALLABLE(callback)) {
- throw MakeTypeError(kCalledNonCallable, callback);
+ throw %make_type_error(kCalledNonCallable, callback);
}
- var is_array = IS_ARRAY(array);
var i = 0;
find_initial: if (argumentsLength < 2) {
for (; i < length; i++) {
- if (HAS_INDEX(array, i, is_array)) {
+ if (i in array) {
current = array[i++];
break find_initial;
}
}
- throw MakeTypeError(kReduceNoInitial);
+ throw %make_type_error(kReduceNoInitial);
}
for (; i < length; i++) {
- if (HAS_INDEX(array, i, is_array)) {
+ if (i in array) {
var element = array[i];
current = callback(current, element, i, array);
}
@@ -1505,23 +1235,22 @@ function ArrayReduce(callback, current) {
function InnerArrayReduceRight(callback, current, array, length,
argumentsLength) {
if (!IS_CALLABLE(callback)) {
- throw MakeTypeError(kCalledNonCallable, callback);
+ throw %make_type_error(kCalledNonCallable, callback);
}
- var is_array = IS_ARRAY(array);
var i = length - 1;
find_initial: if (argumentsLength < 2) {
for (; i >= 0; i--) {
- if (HAS_INDEX(array, i, is_array)) {
+ if (i in array) {
current = array[i--];
break find_initial;
}
}
- throw MakeTypeError(kReduceNoInitial);
+ throw %make_type_error(kReduceNoInitial);
}
for (; i >= 0; i--) {
- if (HAS_INDEX(array, i, is_array)) {
+ if (i in array) {
var element = array[i];
current = callback(current, element, i, array);
}
@@ -1603,7 +1332,7 @@ function ArrayCopyWithin(target, start, end) {
function InnerArrayFind(predicate, thisArg, array, length) {
if (!IS_CALLABLE(predicate)) {
- throw MakeTypeError(kCalledNonCallable, predicate);
+ throw %make_type_error(kCalledNonCallable, predicate);
}
for (var i = 0; i < length; i++) {
@@ -1630,7 +1359,7 @@ function ArrayFind(predicate, thisArg) {
function InnerArrayFindIndex(predicate, thisArg, array, length) {
if (!IS_CALLABLE(predicate)) {
- throw MakeTypeError(kCalledNonCallable, predicate);
+ throw %make_type_error(kCalledNonCallable, predicate);
}
for (var i = 0; i < length; i++) {
@@ -1675,7 +1404,7 @@ function InnerArrayFill(value, start, end, array, length) {
}
if ((end - i) > 0 && %object_is_frozen(array)) {
- throw MakeTypeError(kArrayFunctionsOnFrozen);
+ throw %make_type_error(kArrayFunctionsOnFrozen);
}
for (; i < end; i++)
@@ -1695,58 +1424,6 @@ function ArrayFill(value, start, end) {
}
-function InnerArrayIncludes(searchElement, fromIndex, array, length) {
- if (length === 0) {
- return false;
- }
-
- var n = TO_INTEGER(fromIndex);
-
- var k;
- if (n >= 0) {
- k = n;
- } else {
- k = length + n;
- if (k < 0) {
- k = 0;
- }
- }
-
- while (k < length) {
- var elementK = array[k];
- if (%SameValueZero(searchElement, elementK)) {
- return true;
- }
-
- ++k;
- }
-
- return false;
-}
-
-
-// ES2016 draft, section 22.1.3.11
-function ArrayIncludes(searchElement, fromIndex) {
- CHECK_OBJECT_COERCIBLE(this, "Array.prototype.includes");
-
- var array = TO_OBJECT(this);
- var length = TO_LENGTH(array.length);
-
- return InnerArrayIncludes(searchElement, fromIndex, array, length);
-}
-
-
-function AddArrayElement(constructor, array, i, value) {
- if (constructor === GlobalArray) {
- AddIndexedProperty(array, i, value);
- } else {
- ObjectDefineProperty(array, i, {
- value: value, writable: true, configurable: true, enumerable: true
- });
- }
-}
-
-
// ES6, draft 10-14-14, section 22.1.2.1
function ArrayFrom(arrayLike, mapfn, receiver) {
var items = TO_OBJECT(arrayLike);
@@ -1754,7 +1431,7 @@ function ArrayFrom(arrayLike, mapfn, receiver) {
if (mapping) {
if (!IS_CALLABLE(mapfn)) {
- throw MakeTypeError(kCalledNonCallable, mapfn);
+ throw %make_type_error(kCalledNonCallable, mapfn);
}
}
@@ -1775,7 +1452,7 @@ function ArrayFrom(arrayLike, mapfn, receiver) {
} else {
mappedValue = nextValue;
}
- AddArrayElement(this, result, k, mappedValue);
+ %CreateDataProperty(result, k, mappedValue);
k++;
}
result.length = k;
@@ -1791,7 +1468,7 @@ function ArrayFrom(arrayLike, mapfn, receiver) {
} else {
mappedValue = nextValue;
}
- AddArrayElement(this, result, k, mappedValue);
+ %CreateDataProperty(result, k, mappedValue);
}
result.length = k;
@@ -1807,12 +1484,18 @@ function ArrayOf(...args) {
// TODO: Implement IsConstructor (ES6 section 7.2.5)
var array = %IsConstructor(constructor) ? new constructor(length) : [];
for (var i = 0; i < length; i++) {
- AddArrayElement(constructor, array, i, args[i]);
+ %CreateDataProperty(array, i, args[i]);
}
array.length = length;
return array;
}
+
+function ArraySpecies() {
+ return this;
+}
+
+
// -------------------------------------------------------------------
// Set up non-enumerable constructor property on the Array.prototype
@@ -1828,6 +1511,7 @@ var unscopables = {
fill: true,
find: true,
findIndex: true,
+ includes: true,
keys: true,
};
@@ -1876,7 +1560,7 @@ utils.InstallFunctions(GlobalArray.prototype, DONT_ENUM, [
"some", getFunction("some", ArraySome, 1),
"every", getFunction("every", ArrayEvery, 1),
"map", getFunction("map", ArrayMap, 1),
- "indexOf", getFunction("indexOf", ArrayIndexOf, 1),
+ "indexOf", getFunction("indexOf", null, 1),
"lastIndexOf", getFunction("lastIndexOf", ArrayLastIndexOf, 1),
"reduce", getFunction("reduce", ArrayReduce, 1),
"reduceRight", getFunction("reduceRight", ArrayReduceRight, 1),
@@ -1884,16 +1568,18 @@ utils.InstallFunctions(GlobalArray.prototype, DONT_ENUM, [
"find", getFunction("find", ArrayFind, 1),
"findIndex", getFunction("findIndex", ArrayFindIndex, 1),
"fill", getFunction("fill", ArrayFill, 1),
- "includes", getFunction("includes", ArrayIncludes, 1),
+ "includes", getFunction("includes", null, 1)
]);
+utils.InstallGetter(GlobalArray, speciesSymbol, ArraySpecies);
+
%FinishArrayPrototypeSetup(GlobalArray.prototype);
// The internal Array prototype doesn't need to be fancy, since it's never
// exposed to user code.
// Adding only the functions that are actually used.
utils.SetUpLockedPrototype(InternalArray, GlobalArray(), [
- "indexOf", getFunction("indexOf", ArrayIndexOf),
+ "indexOf", getFunction("indexOf", null),
"join", getFunction("join", ArrayJoin),
"pop", getFunction("pop", ArrayPop),
"push", getFunction("push", ArrayPush),
@@ -1925,7 +1611,6 @@ utils.SetUpLockedPrototype(extrasUtils.InternalPackedArray, GlobalArray(), [
utils.Export(function(to) {
to.ArrayFrom = ArrayFrom;
- to.ArrayIndexOf = ArrayIndexOf;
to.ArrayJoin = ArrayJoin;
to.ArrayPush = ArrayPush;
to.ArrayToString = ArrayToString;
@@ -1936,8 +1621,6 @@ utils.Export(function(to) {
to.InnerArrayFind = InnerArrayFind;
to.InnerArrayFindIndex = InnerArrayFindIndex;
to.InnerArrayForEach = InnerArrayForEach;
- to.InnerArrayIncludes = InnerArrayIncludes;
- to.InnerArrayIndexOf = InnerArrayIndexOf;
to.InnerArrayJoin = InnerArrayJoin;
to.InnerArrayLastIndexOf = InnerArrayLastIndexOf;
to.InnerArrayReduce = InnerArrayReduce;
@@ -1946,10 +1629,6 @@ utils.Export(function(to) {
to.InnerArraySort = InnerArraySort;
to.InnerArrayToLocaleString = InnerArrayToLocaleString;
to.PackedArrayReverse = PackedArrayReverse;
- to.Stack = Stack;
- to.StackHas = StackHas;
- to.StackPush = StackPush;
- to.StackPop = StackPop;
});
%InstallToContext([