(don't miss the second part of my response)

On Jul 14, 2011, at 5:21 AM, Andrew Oakley wrote:

> I'm not sure the Array.prototype.concat algorithm (ยง 15.4.4.4) is quite
> right.
> 
> As far as I can see the length property of the result (A) is not
> explicitly set anywhere in the algorithm so we are relying on the
> [[DefineOwnProperty]] method of A to set the length for us when we add
> indexed properties to it.
> 
> If we pass "sparse" arrays to the function then I think the results
> should look like this:
> 
> [,,,,].concat([]) => [] (length 0)
> [,x,,].concat([]) => [,x] (length 2)
> 
> This is not what browsers do and is a significant change from ECMAScript
> 3 (which set the length of A at the end of the algorithm)
> 
> Is it reasonable to add another step at the end of the algorithm to make
> it match browser behaviour better:
> 
> Call the [[DefineOwnProperty]] internal method of A with arguments
> "length", Property Descriptor {[[Value]]: n}, and false.

Yes, this is a bug see 
https://mail.mozilla.org/pipermail/es5-discuss/2010-December/003852.html 
Now https://bugs.ecmascript.org/show_bug.cgi?id=129 

I guess it is time to fire up the ES5.1 Errata...

BTW, a [[Put]] for length at the end will work fine.

> 
> 
> The other complication I've spotted (I think it crops up elsewhere too)
> is what to do if n becomes larger than the maximum array index.  My
> reading of ECMAScript 3 says that we *should* throw a RangeError but
> nobody seems to do that.
> 
> Opera and Firefox seem to store n as a 32bit unsigned number - the
> length wraps and they start putting properties at the beginning of the
> array again.  I'm not sure what Chrome is doing (I can't find my values
> in the returned array), IE says "out of memory" and I got bored waiting
> for Safari.
> 

This appears to be a (possible) specification bug that first occurs in ES3 and 
which was not corrected in ES5.

I appears in concat and push. But no other algorithms.  The problem occurs when 
when a length value is incremented and then used as an array index without 
first applying ToUint32 to the value.  It only occurs concat and push because 
all the other algorithms are bounded by a length value that has had ToUint32 
applied to it.

It is probably a bug, because array index based operations generally warp 
around to 0 at 2^32.  I assume that the Firefox implementation was the  initial 
one and it reflects that behavior.  However, all array objects (ad generic 
array like objects) are permitted to have integer  property names >= 2^32.  
These properties are not reflected in the value of the 'length' property (when 
set by generic array methods for array-like objects).  So, there is a slim 
chance that the specified behavior was intentional in allowing concat and push 
to leak past the 2^32 element boundary. 

We have to possible courses of action:
   1) consider the specification to be correct as written. 
   2) consider this to be a spec. but that we correct in the errata and in 
future editions.

This is an edge case that probably never occurs in the real world so the choice 
probably has no real impact.  #1 is most consistent with the rest of the ES 
spec.  However, the 2^32 length wrap semantics of arrays is kind of bogus and 
it might be nice to try to eliminate it in the future.  #2 would be a step away 
from that.

this now bug: https://bugs.ecmascript.org/show_bug.cgi?id=131 

Allen






> -- 
> Andrew Oakley
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to