diff options
| author | Ben Murdoch <benm@google.com> | 2012-03-05 11:04:45 +0000 |
|---|---|---|
| committer | Ben Murdoch <benm@google.com> | 2012-04-11 15:39:56 +0100 |
| commit | 592a9fc1d8ea420377a2e7efd0600e20b058be2b (patch) | |
| tree | 23fe22995f4f9056a96266d169d49426a5e745d7 /src/array.js | |
| parent | e25ed7434cc3a061dd965ad25b923bca153aed94 (diff) | |
| download | android_external_v8-592a9fc1d8ea420377a2e7efd0600e20b058be2b.tar.gz android_external_v8-592a9fc1d8ea420377a2e7efd0600e20b058be2b.tar.bz2 android_external_v8-592a9fc1d8ea420377a2e7efd0600e20b058be2b.zip | |
Merge V8 at 3.7.12.28
Bug: 5688872
Change-Id: Iddb40cae44d51a2b449f2858951e0472771f5981
Diffstat (limited to 'src/array.js')
| -rw-r--r-- | src/array.js | 188 |
1 files changed, 117 insertions, 71 deletions
diff --git a/src/array.js b/src/array.js index 98fe3ac7..3d8e278b 100644 --- a/src/array.js +++ b/src/array.js @@ -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, seciton 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); @@ -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; + var current = array[i]; + if (!IS_UNDEFINED(current) || i in array) { + if (%_CallFunction(receiver, current, i, array, f)) { + accumulator[accumulator_length++] = current; } } } + %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); + var current = array[i]; + if (!IS_UNDEFINED(current) || i in array) { + %_CallFunction(receiver, current, 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; + var current = array[i]; + if (!IS_UNDEFINED(current) || i in array) { + if (%_CallFunction(receiver, current, 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; + var current = array[i]; + if (!IS_UNDEFINED(current) || i in array) { + if (!%_CallFunction(receiver, current, 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); + var current = array[i]; + if (!IS_UNDEFINED(current) || i in array) { + accumulator[i] = %_CallFunction(receiver, current, 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); + var element = array[i]; + if (!IS_UNDEFINED(element) || i in array) { + 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); + var element = array[i]; + if (!IS_UNDEFINED(element) || i in array) { + current = %_CallFunction(receiver, current, element, i, array, callback); } } return current; @@ -1342,7 +1388,7 @@ function SetUpArray() { // 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), |
