Wanted: standard Array function to append an array's

Jeff Walden jwalden+es at MIT.EDU
Thu Jul 28 16:59:01 PDT 2011


On 07/27/2011 01:26 PM, John-David Dalton wrote:
> @Jeff In reply to
> https://mail.mozilla.org/pipermail/es-discuss/2011-July/016124.html,
> which engines have problems with `firstArray.push.apply(firstArray,
> secondArray)` ?
> Shouldn't a bug report be filed for the specific JS engine or the spec
> be clarified on the subject (String.fromCharCode too) instead of
> adding another method to Array.prototype?

Here's a testcase:

(function test() { var big =  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf]; while (true) { try { var before = big.length; big.push.apply(big, big); if (big.length !== before + before) throw before; } catch (e) { return big.length + ": " + e; } } })()

If the apply call throws an exception, a string consisting of the array length before the push failed, and the exception thrown, is returned.  If the push call doesn't push all the elements it should have pushed,a string consisting of the array length after the push, and the array length before the faulty push, is returned.

The testcase demonstrates failures with these engines:

SpiderMonkey's max argument-count is currently something like 480k, so pushing an array of 512k elements onto another array will only push the first 480k-ish.  (This is being changed so that an exception is thrown, shortly.  It has caused at least two quite unexpected bugs.  Probably someone else has stumbled across the problem before, but I don't know for sure.)

In v8 an exception is thrown sometime between secondArray having length 128k and 256k.

Nitro copied SpiderMonkey, although its max-arg-count isn't as high as SpiderMonkey's, so it will only push the first N elements of a really big array.

IE10 throws an exception for a push of the elements of an array somewhere between 128k and 256k.

IE9 throws similarly, except between 256k and 512k.

Of the major engines, only Opera seems to have no problems here.  I'm not sure why this is.  But ignoring Opera, everyone fails this.  And the reason, I believe, is not that it's a quality of implementation issue: it's that the general way to implement this butts up against ingrained implementation choices, and different engines will quite rationally behave in different ways in response.  push.apply is simply not a reliable substitute for a built-in method to push the contents of an array into another array.

Jeff


More information about the es-discuss mailing list