diff options
| author | Ben Murdoch <benm@google.com> | 2012-04-12 10:51:47 +0100 |
|---|---|---|
| committer | Ben Murdoch <benm@google.com> | 2012-04-16 16:41:38 +0100 |
| commit | 3ef787dbeca8a5fb1086949cda830dccee07bfbd (patch) | |
| tree | 0a22edd97aa148abffdd405c585b22213fccbc82 /src/array.js | |
| parent | 85b71799222b55eb5dd74ea26efe0c64ab655c8c (diff) | |
| download | android_external_v8-3ef787dbeca8a5fb1086949cda830dccee07bfbd.tar.gz android_external_v8-3ef787dbeca8a5fb1086949cda830dccee07bfbd.tar.bz2 android_external_v8-3ef787dbeca8a5fb1086949cda830dccee07bfbd.zip | |
Merge V8 at 3.9.24.13
Bug: 5688872
Change-Id: Id0aa8d23375030494d3189c31774059c0f5398fc
Diffstat (limited to 'src/array.js')
| -rw-r--r-- | src/array.js | 214 |
1 files changed, 130 insertions, 84 deletions
diff --git a/src/array.js b/src/array.js index 98fe3ac7..daa75d57 100644 --- a/src/array.js +++ b/src/array.js @@ -27,7 +27,7 @@ // This file relies on the fact that the following declarations have been made // in runtime.js: -// const $Array = global.Array; +// var $Array = global.Array; // ------------------------------------------------------------------- @@ -201,17 +201,14 @@ function ConvertToString(x) { function ConvertToLocaleString(e) { - if (e == null) { + if (IS_NULL_OR_UNDEFINED(e)) { return ''; } else { - // e_obj's toLocaleString might be overwritten, check if it is a function. - // Call ToString if toLocaleString is not a function. - // See issue 877615. + // According to ES5, section 15.4.4.3, the toLocaleString conversion + // must throw a TypeError if ToObject(e).toLocaleString isn't + // callable. var e_obj = ToObject(e); - if (IS_SPEC_FUNCTION(e_obj.toLocaleString)) - return ToString(e_obj.toLocaleString()); - else - return ToString(e); + return %ToString(e_obj.toLocaleString()); } } @@ -331,8 +328,9 @@ function SimpleSlice(array, start_i, del_count, len, deleted_elements) { // would be the appropriate test. We follow KJS in consulting the // prototype. var current = array[index]; - if (!IS_UNDEFINED(current) || index in array) + if (!IS_UNDEFINED(current) || index in array) { deleted_elements[i] = current; + } } } @@ -381,18 +379,31 @@ function SimpleMove(array, start_i, del_count, len, num_additional_args) { function ArrayToString() { - if (!IS_ARRAY(this)) { - throw new $TypeError('Array.prototype.toString is not generic'); + var array; + var func; + if (IS_ARRAY(this)) { + func = this.join; + if (func === ArrayJoin) { + return Join(this, this.length, ',', ConvertToString); + } + array = this; + } else { + array = ToObject(this); + func = array.join; } - return Join(this, this.length, ',', ConvertToString); + if (!IS_SPEC_FUNCTION(func)) { + return %_CallFunction(array, ObjectToString); + } + return %_CallFunction(array, func); } function ArrayToLocaleString() { - if (!IS_ARRAY(this)) { - throw new $TypeError('Array.prototype.toString is not generic'); - } - return Join(this, this.length, ',', ConvertToLocaleString); + var array = ToObject(this); + var arrayLen = array.length; + var len = TO_UINT32(arrayLen); + if (len === 0) return ""; + return Join(array, len, ',', ConvertToLocaleString); } @@ -485,12 +496,12 @@ function SparseReverse(array, len) { if (j_complement <= i) { high = j; - while (keys[--high_counter] == j); + while (keys[--high_counter] == j) { } low = j_complement; } if (j_complement >= i) { low = i; - while (keys[++low_counter] == i); + while (keys[++low_counter] == i) { } high = len - i - 1; } @@ -566,10 +577,11 @@ function ArrayShift() { var first = this[0]; - if (IS_ARRAY(this)) + if (IS_ARRAY(this)) { SmartMove(this, 0, 1, len, 0); - else + } else { SimpleMove(this, 0, 1, len, 0); + } this.length = len - 1; @@ -586,10 +598,11 @@ function ArrayUnshift(arg1) { // length == 1 var len = TO_UINT32(this.length); var num_arguments = %_ArgumentsLength(); - if (IS_ARRAY(this)) + if (IS_ARRAY(this)) { SmartMove(this, 0, 0, len, num_arguments); - else + } else { SimpleMove(this, 0, 0, len, num_arguments); + } for (var i = 0; i < num_arguments; i++) { this[i] = %_Arguments(i); @@ -744,7 +757,7 @@ function ArraySort(comparefn) { } var receiver = %GetDefaultReceiver(comparefn); - function InsertionSort(a, from, to) { + var InsertionSort = function InsertionSort(a, from, to) { for (var i = from + 1; i < to; i++) { var element = a[i]; for (var j = i - 1; j >= from; j--) { @@ -758,9 +771,9 @@ function ArraySort(comparefn) { } a[j + 1] = element; } - } + }; - function QuickSort(a, from, to) { + var QuickSort = function QuickSort(a, from, to) { // Insertion sort is faster for short arrays. if (to - from <= 10) { InsertionSort(a, from, to); @@ -828,12 +841,12 @@ function ArraySort(comparefn) { } QuickSort(a, from, low_end); QuickSort(a, high_start, to); - } + }; // Copy elements in the range 0..length from obj's prototype chain // to obj itself, if obj has holes. Return one more than the maximal index // of a prototype property. - function CopyFromPrototype(obj, length) { + var CopyFromPrototype = function CopyFromPrototype(obj, length) { var max = 0; for (var proto = obj.__proto__; proto; proto = proto.__proto__) { var indices = %GetArrayKeys(proto, length); @@ -860,12 +873,12 @@ function ArraySort(comparefn) { } } return max; - } + }; // Set a value of "undefined" on all indices in the range from..to // where a prototype of obj has an element. I.e., shadow all prototype // elements in that range. - function ShadowPrototypeElements(obj, from, to) { + var ShadowPrototypeElements = function(obj, from, to) { for (var proto = obj.__proto__; proto; proto = proto.__proto__) { var indices = %GetArrayKeys(proto, to); if (indices.length > 0) { @@ -888,9 +901,9 @@ function ArraySort(comparefn) { } } } - } + }; - function SafeRemoveArrayHoles(obj) { + var SafeRemoveArrayHoles = function SafeRemoveArrayHoles(obj) { // Copy defined elements from the end to fill in all holes and undefineds // in the beginning of the array. Write undefineds and holes at the end // after loop is finished. @@ -945,7 +958,7 @@ function ArraySort(comparefn) { // Return the number of defined elements. return first_undefined; - } + }; var length = TO_UINT32(this.length); if (length < 2) return this; @@ -993,25 +1006,32 @@ 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; + } else if (!IS_SPEC_OBJECT(receiver)) { + receiver = ToObject(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; + + var result = new $Array(); + var accumulator = new InternalArray(); + var accumulator_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)) { - result[result_length++] = current; + if (i in array) { + var element = array[i]; + if (%_CallFunction(receiver, element, i, array, f)) { + accumulator[accumulator_length++] = element; } } } + %MoveArrayContents(accumulator, result); return result; } @@ -1022,19 +1042,24 @@ 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; + } else if (!IS_SPEC_OBJECT(receiver)) { + receiver = ToObject(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); + if (i in array) { + var element = array[i]; + %_CallFunction(receiver, element, i, array, f); } } } @@ -1048,19 +1073,24 @@ 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; + } else if (!IS_SPEC_OBJECT(receiver)) { + receiver = ToObject(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; + if (i in array) { + var element = array[i]; + if (%_CallFunction(receiver, element, i, array, f)) return true; } } return false; @@ -1073,19 +1103,24 @@ 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; + } else if (!IS_SPEC_OBJECT(receiver)) { + receiver = ToObject(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; + if (i in array) { + var element = array[i]; + if (!%_CallFunction(receiver, element, i, array, f)) return false; } } return true; @@ -1097,21 +1132,26 @@ 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; + } else if (!IS_SPEC_OBJECT(receiver)) { + receiver = ToObject(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); + if (i in array) { + var element = array[i]; + accumulator[i] = %_CallFunction(receiver, element, i, array, f); } } %MoveArrayContents(accumulator, result); @@ -1245,19 +1285,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; } @@ -1267,9 +1308,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); + if (i in array) { + var element = array[i]; + current = %_CallFunction(receiver, current, element, i, array, callback); } } return current; @@ -1281,15 +1322,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; } @@ -1299,9 +1345,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); + if (i in array) { + var element = array[i]; + current = %_CallFunction(receiver, current, element, i, array, callback); } } return current; @@ -1327,7 +1373,7 @@ function SetUpArray() { var specialFunctions = %SpecialArrayFunctions({}); - function getFunction(name, jsBuiltin, len) { + var getFunction = function(name, jsBuiltin, len) { var f = jsBuiltin; if (specialFunctions.hasOwnProperty(name)) { f = specialFunctions[name]; @@ -1336,13 +1382,13 @@ function SetUpArray() { %FunctionSetLength(f, len); } return f; - } + }; // Set up non-enumerable functions of the Array.prototype object and // set their names. // Manipulate the length of some of the functions to meet // expectations set by ECMA-262 or Mozilla. - InstallFunctionsOnHiddenPrototype($Array.prototype, DONT_ENUM, $Array( + InstallFunctions($Array.prototype, DONT_ENUM, $Array( "toString", getFunction("toString", ArrayToString), "toLocaleString", getFunction("toLocaleString", ArrayToLocaleString), "join", getFunction("join", ArrayJoin), |
