

Re: Arrays in WebIDL aren't making sense to me so far

From: Cameron McCormack <cam@mcc.id.au>
Date: Tue, 03 Apr 2012 09:34:38 +1000
Message-ID: <4F7A378E.3060904@mcc.id.au>
To: Boris Zbarsky <bzbarsky@MIT.EDU>
Boris Zbarsky:
> I was reading the array sections of WebIDL, and I had two questions.
> 1)  The spec says that for platform array objects the [[Extensible]]
> property is always true.  Why is that, exactly?  Shouldn't one be able
> to Object.seal() or Object.preventExtensions() platform array objects?
> It's doable for other platform objects, afaict...

If a platform array object is not [[Extensible]], is not a fixed length 
array, and the array gets longer, what happens?  Does the length 
property reflect the new longer value but not expose the additional 
array index properties with its [[GetOwnProperty]]?  It seemed simpler 
to disallow this.

(I wonder now whether I've done the same thing for objects with indexed 
properties, though...)

> 2)  http://dev.w3.org/2006/webapi/WebIDL/#idl-array says that arrays are
> passed by reference and that "Passing an array to a platform object
> could result in that array being modified by the object."  However
> http://dev.w3.org/2006/webapi/WebIDL/#es-array says that converting an
> ES value to an IDL array always allocates a new array.  I'm not sure how
> to reconcile these two statements; at the moment I'm assuming that the
> informative text at the first link is in error and the normative
> requirements are correct: arrays are passed by value but returned by
> reference.  Is that right?

I think the confusions is because I'm using "array" in two different 
senses.  The set of values for an IDL array type T[] are just references 
to platform array objects of that element type.  When you pass in a JS 
Array object, the JS value is converted to the IDL type by creating a 
new platform array object from the values in the JS Array.  So if you had

   interface A {
     attribute long[] x;

where x is defined to just store and return the same value, nothing 
special, then:

   var y = [1, 2, 3];
   myA.x = y;
   assert(myA.x == myA.x);
   assert(myA.x != y);
   myA.x[0] = 4;
   assert(y[0] == 1);
   assert(myA.x[0] == 4);

The statement that says "passing an array to a platform object could 
result in that array being modified by the object" is referring to the 
IDL array type, not a JS array.  For example:

   interface B {
     long[] range(unsigned long min, unsigned long max);
     void incrementAll(long[] a);

Let's say range returns a reference to a newly created IDL array (so in 
the ECMAScript binding this means a new platform array object) with 
values from min to max.  The statement is saying that if you pass an IDL 
array value to incrementAll, then the object might modify that array:

   var a1 = myB.range(1, 5);
   assert(a1[0] == 1);
   assert(a1[0] == 2);

   var a2 = [1, 2, 3, 4, 5];
   assert(a2[0] == 1);

The second call to incrementAll creates a new IDL array value from the 
JS Array object and then operates on that.
Received on Monday, 2 April 2012 23:35:11 UTC
