Re: WebIDL usage for Algorithms

On Thu, Mar 13, 2014 at 11:45 AM, Boris Zbarsky <bzbarsky@mit.edu> wrote:

> Richard asked me to comment in this thread.  My apologies for the lack of
> sane threading/quoting; I wasn't subscribed to the list...
>
>
> On Tue, Mar 11, 2014 at 3:07 PM, Mark Watson <watsonm@netflix.com> wrote:
>
>  even type mapping to IDL "any" can throw an exception.
>>
>
> I believe this is incorrect.  http://heycam.github.io/webidl/#es-anydoesn't mention any cases when it would, and certainly Gecko's
> implementation doesn't.
>
> Converting an ES value to an IDL "object" type can in fact throw if the
> passed-in value is a primitive, though.


Just to make sure - are you advocating for "any" as the type, on this
basis, or are you still advocating for "object", for the reason below.


>
>
>  It does seem that, longer term, it would make sense for WebIDL to
>> incorporate Promises explicitly
>>
>
> It already has, in the spec.  Browser implementations may not have caught
> up yet; this is a recent change.
>
> For example, http://heycam.github.io/webidl/#es-operations explicitly
> says that if an exception is thrown at any point during the steps defined
> for the function and the return type is a promise type, then the exception
> is caught and a promise rejected with that exception is returned.
>
> So in your spec you should be able to just write:
>
>   typedef (object or DOMString) AlgorithmIdentifier;
> ...
>
>   Promise<any> encrypt(AlgorithmIdentifier algorithm,
>                        Key key,
>                        CryptoOperationData data);
>
> and calling encrypt would never throw per current WebIDL spec (modulo
> things like out of memory exceptions, naturally; you can't exactly return a
> promise in that situation).  You do NOT have to explicitly do anything with
> "key" and "data" as the spec tries to do right now; they will be converted
> to the relevant WebIDL types before the method returns, but any resulting
> errors will be reported async via the returned promise that wraps the
> thrown exception.
>

SGTM. I missed that handler in the Operations case.


>
> What you _will_ have to do by hand, as things stand, is to explicitly call
> out when, if an object is passed, it is converted to the various WebIDL
> dictionary types the specification uses.  Since conversion to a WebIDL
> dictionary type can have side-effects, its ordering with other things needs
> to be precisely defined to avoid creating racy behavior. Doing it async is
> not the way to go, in my opinion; you want to go ahead and do it before you
> create the promise and get to the "asynchronously perform the remaining
> steps" bit.  That is, the "algorithm normalization" bit will happen
> synchronously before the method returns, but any exceptions from it will be
> reported asynchronously via the returned Promise.


> One way to do this in your spec is probably to have an Algorithm
> dictionary type that just has a "name" attribute, to have a bunch of more
> specific dictionary types that do _not_ inherit from Algorithm or contain a
> "name" attribute, to manually invoke the "convert to an IDL dictionary
> type" algorithm from http://heycam.github.io/webidl/#es-dictionary at the
> right points, and then pass (Algorithm, OtherDictionary) pairs to anything
> that needs the name in addition to the information from the other
> dictionary.  You _could_ make the other dictionaries inherit from
> Algorithm, but then you have to worry about the getter for the "name"
> property on the object not being idempotent and what your spec should do if
> it returns a different value the second time around.
>
> Ryan's proposal for synchronously creating a snapshot of the object passed
> in seems to me to be more complicated to specify than the above, for what
> it's worth, though I welcome him to prove me wrong with a concrete proposal
> about how it should work.


I'm not sure I fully grok your concern here or what you're proposing as an
alternative.

The asynchronous nature is already going to be a problem for ArrayBuffers -
which we MUST take a structured clone of the data BEFORE we can return the
promise (rejected or not), otherwise the caller can potentially mutate
them. In practice, treating it as a Transferrable isn't as useful, because
that only works on the ArrayBuffer - not the ArrayBufferView. Further, the
structured clone ensures we don't run into any headaches with things like
DefineOwnProperty getters being invoked at odd times, later in the process.

On a spec level, can we not simply state that you invoke the structured
clone algorithm on /alg/, letting o be the internal object created from
such clone. Then, at later points, as needed, you convert o to the IDL
dictionary type D, then normalize over D?

Isn't this essentially the same as what you mean by (Algorithm,
OtherDictionary) pairs - except it's instead (Algorithm, o), where o is the
structured clone, and it's converted to OtherDictionary as needed?


>
>
>  WebIDL could consider having Dictionary IDL types carry with them a
>> reference to the original object so that downcasts are possible.
>>
>
> That's true.  You have to be careful, because of the side-effects issue,
> but it might be possible to do this sort of thing.  Please send mail to
> public-script-coord?  I agree that dictionary inheritance is pretty weird
> in WebIDL right now...
>
> Hope that helps,
> Boris
>
>

Received on Tuesday, 18 March 2014 01:38:10 UTC