Bug 860965 - Part 2: Add Array.build. (r=nmatsakis)

This commit is contained in:
Shu-yu Guo 2013-07-22 16:12:07 -07:00
parent 91b4c3d28c
commit c66aa2de55
4 changed files with 59 additions and 3 deletions

View File

@ -1281,13 +1281,27 @@ function ArrayFilterPar(func, mode) {
}
/**
* "Comprehension form": This is the function invoked for |Array.buildPar(len,
* fn)| It creates a new array with length |len| where index |i| is equal to
* |fn(i)|.
* "Comprehension form": This is the function invoked for
* |Array.{build,buildPar}(len, fn)| It creates a new array with length |len|
* where index |i| is equal to |fn(i)|.
*
* The final |mode| argument is an internal argument used only during our
* unit-testing.
*/
function ArrayStaticBuild(length, func) {
if (!IS_UINT32(length))
ThrowError(JSMSG_BAD_ARRAY_LENGTH);
if (!IsCallable(func))
ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(1, func));
var buffer = NewDenseArray(length);
for (var i = 0; i < length; i++)
UnsafePutElements(buffer, i, func(i));
return buffer;
}
function ArrayStaticBuildPar(length, func, mode) {
if (!IS_UINT32(length))
ThrowError(JSMSG_BAD_ARRAY_LENGTH);

View File

@ -0,0 +1,20 @@
// Array.build basics
load(libdir + "asserts.js");
load(libdir + "eqArrayHelper.js");
function myBuild(l, f) {
var a = [];
for (var i = 0; i < l; i++)
a.push(f(i));
return a;
}
// Test that build returns an identical, but new array.
var a1 = [];
for (var i = 0; i < 100; i++)
a1[i] = Math.random();
var a2 = Array.build(a1.length, (i) => a1[i]);
assertEq(a1 === a2, false);
assertEqArray(a2, a1);

View File

@ -0,0 +1,21 @@
// Check superficial features of Array.build.
load(libdir + "asserts.js");
var desc = Object.getOwnPropertyDescriptor(Array, "build");
assertEq(desc.configurable, true);
assertEq(desc.enumerable, false);
assertEq(desc.writable, true);
assertEq(Array.build.length, 2);
assertThrowsInstanceOf(() => new Array.build(), TypeError); // not a constructor
// Must pass a function to second argument.
for (let v of [undefined, null, false, "cow"])
assertThrowsInstanceOf(() => Array.build(1, v), TypeError);
// The first argument must be a legal length.
assertThrowsInstanceOf(() => Array.build(-1, function() {}), RangeError);
// When the this-value passed in is not a constructor, the result is an array.
for (let v of [undefined, null, false, "cow"])
assertEq(Array.isArray(Array.build.call(v, 1, function() {})), true);

View File

@ -2833,6 +2833,7 @@ static const JSFunctionSpec array_static_methods[] = {
{"some", {NULL, NULL}, 2,0, "ArrayStaticSome"},
{"reduce", {NULL, NULL}, 2,0, "ArrayStaticReduce"},
{"reduceRight", {NULL, NULL}, 2,0, "ArrayStaticReduceRight"},
{"build", {NULL, NULL}, 2,0, "ArrayStaticBuild"},
JS_FN("of", array_of, 0,0),
#ifdef ENABLE_PARALLEL_JS