Index: src/array.js |
=================================================================== |
--- src/array.js (revision 413) |
+++ src/array.js (working copy) |
@@ -132,13 +132,13 @@ |
// Make sure to pop the visited array no matter what happens. |
if (is_array) visited_arrays.pop(); |
} |
-}; |
+} |
function ConvertToString(e) { |
if (e == null) return ''; |
else return ToString(e); |
-}; |
+} |
function ConvertToLocaleString(e) { |
@@ -153,7 +153,7 @@ |
else |
return ToString(e); |
} |
-}; |
+} |
// This function implements the optimized splice implementation that can use |
@@ -196,7 +196,7 @@ |
} |
} |
} |
-}; |
+} |
// This function implements the optimized splice implementation that can use |
@@ -258,7 +258,7 @@ |
} |
// Move contents of new_array into this array |
%MoveArrayContents(new_array, array); |
-}; |
+} |
// This is part of the old simple-minded splice. We are using it either |
@@ -274,7 +274,7 @@ |
if (!IS_UNDEFINED(current) || index in array) |
deleted_elements[i] = current; |
} |
-}; |
+} |
function SimpleMove(array, start_i, del_count, len, num_additional_args) { |
@@ -314,7 +314,7 @@ |
} |
} |
} |
-}; |
+} |
// ------------------------------------------------------------------- |
@@ -325,7 +325,7 @@ |
throw new $TypeError('Array.prototype.toString is not generic'); |
} |
return Join(this, this.length, ',', ConvertToString); |
-}; |
+} |
function ArrayToLocaleString() { |
@@ -333,14 +333,14 @@ |
throw new $TypeError('Array.prototype.toString is not generic'); |
} |
return Join(this, this.length, ',', ConvertToLocaleString); |
-}; |
+} |
function ArrayJoin(separator) { |
if (IS_UNDEFINED(separator)) separator = ','; |
else separator = ToString(separator); |
return Join(this, ToUint32(this.length), separator, ConvertToString); |
-}; |
+} |
// Removes the last element from the array and returns it. See |
@@ -356,7 +356,7 @@ |
this.length = n; |
delete this[n]; |
return value; |
-}; |
+} |
// Appends the arguments to the end of the array and returns the new |
@@ -369,7 +369,7 @@ |
} |
this.length = n + m; |
return this.length; |
-}; |
+} |
function ArrayConcat(arg1) { // length == 1 |
@@ -415,7 +415,7 @@ |
A.length = n; // may contain empty arrays |
return A; |
-}; |
+} |
// For implementing reverse() on large, sparse arrays. |
@@ -490,105 +490,105 @@ |
} |
} |
return this; |
-}; |
+} |
function ArrayShift() { |
var len = ToUint32(this.length); |
- |
+ |
if (len === 0) { |
this.length = 0; |
return; |
} |
- |
+ |
var first = this[0]; |
- |
+ |
if (IS_ARRAY(this)) |
SmartMove(this, 0, 1, len, 0); |
else |
SimpleMove(this, 0, 1, len, 0); |
- |
+ |
this.length = len - 1; |
- |
+ |
return first; |
-}; |
+} |
function ArrayUnshift(arg1) { // length == 1 |
var len = ToUint32(this.length); |
var num_arguments = %_ArgumentsLength(); |
- |
+ |
if (IS_ARRAY(this)) |
SmartMove(this, 0, 0, len, num_arguments); |
else |
SimpleMove(this, 0, 0, len, num_arguments); |
- |
+ |
for (var i = 0; i < num_arguments; i++) { |
this[i] = %_Arguments(i); |
} |
- |
+ |
this.length = len + num_arguments; |
- |
+ |
return len + num_arguments; |
-}; |
+} |
function ArraySlice(start, end) { |
var len = ToUint32(this.length); |
var start_i = TO_INTEGER(start); |
var end_i = len; |
- |
+ |
if (end !== void 0) end_i = TO_INTEGER(end); |
- |
+ |
if (start_i < 0) { |
start_i += len; |
if (start_i < 0) start_i = 0; |
} else { |
if (start_i > len) start_i = len; |
} |
- |
+ |
if (end_i < 0) { |
end_i += len; |
if (end_i < 0) end_i = 0; |
} else { |
if (end_i > len) end_i = len; |
} |
- |
+ |
var result = []; |
- |
- if (end_i < start_i) |
- return result; |
- |
- if (IS_ARRAY(this)) |
+ |
+ if (end_i < start_i) return result; |
+ |
+ if (IS_ARRAY(this)) { |
SmartSlice(this, start_i, end_i - start_i, len, result); |
- else |
+ } else { |
SimpleSlice(this, start_i, end_i - start_i, len, result); |
- |
+ } |
+ |
result.length = end_i - start_i; |
- |
+ |
return result; |
-}; |
+} |
function ArraySplice(start, delete_count) { |
var num_arguments = %_ArgumentsLength(); |
- |
+ |
// SpiderMonkey and KJS return undefined in the case where no |
// arguments are given instead of using the implicit undefined |
// arguments. This does not follow ECMA-262, but we do the same for |
// compatibility. |
if (num_arguments == 0) return; |
- |
+ |
var len = ToUint32(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; |
} |
- |
+ |
// SpiderMonkey and KJS treat the case where no delete count is |
// given differently from when an undefined delete count is given. |
// This does not follow ECMA-262, but we do the same for |
@@ -601,18 +601,18 @@ |
} else { |
del_count = len - start_i; |
} |
- |
+ |
var deleted_elements = []; |
deleted_elements.length = del_count; |
- |
+ |
// Number of elements to add. |
var num_additional_args = 0; |
if (num_arguments > 2) { |
num_additional_args = num_arguments - 2; |
} |
- |
+ |
var use_simple_splice = true; |
- |
+ |
if (IS_ARRAY(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 |
@@ -622,7 +622,7 @@ |
use_simple_splice = false; |
} |
} |
- |
+ |
if (use_simple_splice) { |
SimpleSlice(this, start_i, del_count, len, deleted_elements); |
SimpleMove(this, start_i, del_count, len, num_additional_args); |
@@ -630,7 +630,7 @@ |
SmartSlice(this, start_i, del_count, len, deleted_elements); |
SmartMove(this, start_i, del_count, len, num_additional_args); |
} |
- |
+ |
// Insert the arguments into the resulting array in |
// place of the deleted elements. |
var i = start_i; |
@@ -640,10 +640,10 @@ |
this[i++] = %_Arguments(arguments_index++); |
} |
this.length = len - del_count + num_additional_args; |
- |
+ |
// Return the deleted elements. |
return deleted_elements; |
-}; |
+} |
function ArraySort(comparefn) { |
@@ -651,7 +651,7 @@ |
// For short (length <= 22) arrays, insertion sort is used for efficiency. |
var custom_compare = IS_FUNCTION(comparefn); |
- |
+ |
function Compare(x,y) { |
if (custom_compare) { |
return comparefn.call(null, x, y); |
@@ -760,13 +760,12 @@ |
} |
return this; |
-}; |
+} |
// The following functions cannot be made efficient on sparse arrays while |
// preserving the semantics, since the calls to the receiver function can add |
// or delete elements from the array. |
- |
function ArrayFilter(f, receiver) { |
if (!IS_FUNCTION(f)) { |
throw MakeTypeError('called_non_callable', [ f ]); |
@@ -782,7 +781,7 @@ |
} |
} |
return result; |
-}; |
+} |
function ArrayForEach(f, receiver) { |
@@ -798,7 +797,7 @@ |
f.call(receiver, current, i, this); |
} |
} |
-}; |
+} |
// Executes the function once for each element present in the |
@@ -817,7 +816,7 @@ |
} |
} |
return false; |
-}; |
+} |
function ArrayEvery(f, receiver) { |
@@ -833,9 +832,9 @@ |
if (!f.call(receiver, current, i, this)) return false; |
} |
} |
- |
+ |
return true; |
-}; |
+} |
function ArrayMap(f, receiver) { |
@@ -853,7 +852,7 @@ |
} |
} |
return result; |
-}; |
+} |
function ArrayIndexOf(element, index) { |
@@ -875,7 +874,7 @@ |
} |
} |
return -1; |
-}; |
+} |
function ArrayLastIndexOf(element, index) { |
@@ -898,52 +897,59 @@ |
} |
} |
return -1; |
-}; |
+} |
// ------------------------------------------------------------------- |
-function InstallProperties(prototype, attributes, properties) { |
- for (var key in properties) { |
- %AddProperty(prototype, key, properties[key], attributes); |
+function InstallFunctions(prototype, attributes, functions) { |
+ for (var i = 0; i < functions.length; i += 2) { |
+ var key = functions[i]; |
+ var f = functions[i + 1]; |
+ %FunctionSetName(f, key); |
+ %AddProperty(prototype, key, f, attributes); |
} |
-}; |
+} |
function UpdateFunctionLengths(lengths) { |
for (var key in lengths) { |
%FunctionSetLength(this[key], lengths[key]); |
} |
-}; |
+} |
// ------------------------------------------------------------------- |
function SetupArray() { |
- // Setup non-enumerable properties of the Array.prototype object. |
- InstallProperties($Array.prototype, DONT_ENUM, { |
- constructor: $Array, |
- toString: ArrayToString, |
- toLocaleString: ArrayToLocaleString, |
- join: ArrayJoin, |
- pop: ArrayPop, |
- push: ArrayPush, |
- concat: ArrayConcat, |
- reverse: ArrayReverse, |
- shift: ArrayShift, |
- unshift: ArrayUnshift, |
- slice: ArraySlice, |
- splice: ArraySplice, |
- sort: ArraySort, |
- filter: ArrayFilter, |
- forEach: ArrayForEach, |
- some: ArraySome, |
- every: ArrayEvery, |
- map: ArrayMap, |
- indexOf: ArrayIndexOf, |
- lastIndexOf: ArrayLastIndexOf |
- }); |
+ // Setup non-enumerable constructor property on the Array.prototype |
+ // object. |
+ %AddProperty($Array.prototype, "constructor", $Array, DONT_ENUM); |
+ // Setup non-enumerable functions of the Array.prototype object and |
+ // set their names. |
+ InstallFunctions($Array.prototype, DONT_ENUM, $Array( |
+ "toString", ArrayToString, |
+ "toLocaleString", ArrayToLocaleString, |
+ "join", ArrayJoin, |
+ "pop", ArrayPop, |
+ "push", ArrayPush, |
+ "concat", ArrayConcat, |
+ "reverse", ArrayReverse, |
+ "shift", ArrayShift, |
+ "unshift", ArrayUnshift, |
+ "slice", ArraySlice, |
+ "splice", ArraySplice, |
+ "sort", ArraySort, |
+ "filter", ArrayFilter, |
+ "forEach", ArrayForEach, |
+ "some", ArraySome, |
+ "every", ArrayEvery, |
+ "map", ArrayMap, |
+ "indexOf", ArrayIndexOf, |
+ "lastIndexOf", ArrayLastIndexOf |
+ )); |
+ |
// Manipulate the length of some of the functions to meet |
// expectations set by ECMA-262 or Mozilla. |
UpdateFunctionLengths({ |
@@ -956,7 +962,7 @@ |
ArrayLastIndexOf: 1, |
ArrayPush: 1 |
}); |
-}; |
+} |
SetupArray(); |