Merge V8 at 3.7.12.28
Bug: 5688872
Change-Id: Iddb40cae44d51a2b449f2858951e0472771f5981
diff --git a/src/array.js b/src/array.js
index 98fe3ac..3d8e278 100644
--- a/src/array.js
+++ b/src/array.js
@@ -201,17 +201,14 @@
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 @@
// 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 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 @@
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 @@
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 @@
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 @@
["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 @@
["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 @@
["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 @@
["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 @@
["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 @@
["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 @@
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 @@
["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 @@
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 @@
// 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),