Issues with platform array objects in WebIDL

I've run into several issues with platform array objects that I think 
are worth addressing:

1)  Spec authors find them incredibly confusing.  It's common to see 
specs using them for arguments that are supposed to be JS arrays, where 
a sequence would make more sense (e.g. be faster).  It's also common to 
see specs using these as return values without specifying whether the 
same object is returned each time or not or what the modification 
behavior is (more on this below).  I'm not quite sure how to resolve 
this; perhaps more informative text and examples in the WebIDL spec? 
It's worth thinking carefully about the use cases here.  For example, 
are there good use cases so far for platform array object arguments?  (I 
suspect there are.)  Are there use cases for auto-coercion from JS 
arrays to a platform array object arguments?  (Not sure there are.) 
That sort of thing.  That would inform the explanatory text, if nothing 
else.

2)  There are actually three different kinds of objects that are all 
called "platform array objects" in WebIDL.  The expectation seems to be 
that spec prose in a spec using WebIDL will indicate which kind is used 
in which case, but in practice I have never seen a spec that uses 
platform array objects do so.

The three kinds of array objects are:

i)   Variable length (implies writable).
ii)  Fixed length but writable
iii) Readonly

Type (i) allows truncating or expanding the array (though it's not clear 
what happens when you expand it) and changing the values in the array. 
Type (ii) allows only changing the values but not the length, and Type 
(iii) doesn't allow any changes.

WebIDL says that unless otherwise specified typed arrays are not of type 
(i), but says nothing about (ii) vs (iii).

There are a number of issues due to the type of the platform array 
object not being annotated in the WebIDL.  For example, consider this IDL:

   [Constructor()] interface A {
     readonly attribute long[] myNumbers; // Returns a readonly object
   };
   [Constructor()] interface B {
     void getData(long[] putItHere); // Expects a variable length object
   };

and someone doing:

   (new B()).getData((new A()).myNumbers);

I would argue this should throw, but there's no way to determine that 
from the IDL, and nothing in WebIDL says it actually _will_ throw.

I would argue that platform array object arguments, if supported, should 
require explicit indication when the argument is not readonly, and the 
explicit indication should say whether they're fixed length.  Attempts 
to pass a readonly or fixed length array to a method that wants one that 
is writable or variable length respectively should throw.

I'm not sure what the right semantics are for return values.  Once 
again, I think they should require explicit indication of cases when the 
caller will be able to modify the array, so spec authors don't 
accidentally create specs that make private state modifiable.  But it 
could be argued that a "readonly" annotation here should also imply that 
the callee promises the platform array object won't change in the future 
or something...  I don't think that last would be desirable, for what 
it's worth.

Thoughts?

-Boris

Received on Tuesday, 31 July 2012 05:17:40 UTC