- From: Ryan Sleevi <sleevi@google.com>
- Date: Mon, 17 Mar 2014 18:37:42 -0700
- To: Boris Zbarsky <bzbarsky@mit.edu>
- Cc: "public-webcrypto@w3.org" <public-webcrypto@w3.org>
- Message-ID: <CACvaWvaREqNHFGMqa29tCqX2fmSxwwZnVrDs=aXWEgB8XANRXw@mail.gmail.com>
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