- From: Boris Zbarsky <bzbarsky@mit.edu>
- Date: Thu, 12 Jan 2017 13:55:02 -0500
- To: Domenic Denicola <d@domenic.me>
- Cc: public-script-coord <public-script-coord@w3.org>
On 1/11/17 6:11 PM, Domenic Denicola wrote: > What exact steps would go wrong in the spec if we used [AllowShared] Uint8Array, or [EnsureUTF16] DOMString, instead of MaybeSharedUint8Array/USVString? What are the problematic Web IDL snippets, JS inputs, and spec steps that we end up at? Consider the following IDL definitions: dictionary Dict { USVString member1; sequence<USVString> member2; }; interface Iface { void foo(optional Dict arg); void bar((Iface or USVString) arg); void baz(sequence<USVString> arg); void something(record<DOMString, USVString> arg); attribute USVString attr; }; How would we handle these using "[EnsureUTF16] DOMString" instead? It seems to me like we'd need the following: 1) The ability to specify [EnsureUTF16] on dictionary members. 2) The ability to specify [EnsureUTF16] on attributes. 3) The ability to specify [EnsureUTF16] on operation attributes. 4) Steps in https://heycam.github.io/webidl/#create-sequence-from-iterable to propagate through the [EnsureUTF16] to the element conversions. 5) Steps in https://heycam.github.io/webidl/#es-to-record to propagate through the [EnsureUTF16] to conversions. For the special case of USVString there's the additional complication of the key and value maybe wanting different behavior, but that's not a problem for [AllowShared]. It's hard to say whether https://heycam.github.io/webidl/#es-to-union to union would need changes too. It would depend on exactly how the phrasing went for the [EnsureUTF16] thing. If we add new parametrized types they would need to know about [EnsureUTF16] too. If we add more types parametrized on more than one type (a la record), things get pretty annoying. This is all on the spec end. On the implementation end, you obviously have to explicitly thread the [EnsureUTF16] thing and any other such flags through sequence conversions, record conversions, and union conversions. It makes things somewhat more complicated. > Why is this different than things like [Clamp] or [EnforceRange]? It's not. [Clamp] and [EnforceRange] have (1), (2), (3) above. They don't have (4) or (5). If you want to pass a sequence of clamped integers, you're out of luck. If you want to have a clamped integer in a union, you're out of luck too, because, for example, https://heycam.github.io/webidl/#Clamp says: The [Clamp] extended attribute must not appear on a read only attribute, or an attribute, operation argument or dictionary member that is not of an integer type. > Does [Clamp] also break down when trying to use it with union types? Well, it's not allowed to be specified on union types at the moment. If it were allowed, then in terms of the spec I think it would be OK, since you could make the argument that the value being converted in https://heycam.github.io/webidl/#abstract-opdef-converttoint is the value that was passed for the union type, and hence "V is being passed as an operation argument annotated with the [Clamp] extended attribute" or one of the other two conditions in step 6 is true. In terms of implementation, unions would need to know to pass through the "I was tagged with [Clamp] down to all their conversions". Note that you can't just build this into the union itself, because the same union can be used in both [Clamp] and non-[Clamp] situations, right? Consider: typedef (long or USVString) MyUnion; interface Iface { void foo([Clamp] MyUnion arg); void bar(MyUnion arg); }; A binding generator would presumably generate a single instance of MyUnion, which would have to have conditional behavior based on whether it's used in a [Clamp] or non-[Clamp] context. And also based on whether it's used in [EnforceRange]. And [EnsureUTF16], if that were a thing. > What spec surgery would be involved in fixing this whole situation? I think the above more or less describes it? > I guess the idea would be to make the extended attributes apply to the types instead of the arguments, but how exactly would that help? At that point, how is that really different from just having a different type? Unless you can combine the extended attributes, of course. But if they're mutually exclusive (and [Clamp] and [EnforceRange] are specified as mutually exclusive), there is no real semantic difference between that and a new type... There _can_ be the argument that you can apply [Clamp] to a bunch of different types, so you would get a sort of "type explosion" if you created separate types for all of those. So it might make sense to have [Clamp] that attaches directly to integer types, from that point of view. That would not have the "have to thread this information through" problem I describe above, of course, nor the "hey, we're parametrized over two types, which one should be clamped?" problem. Nor the "any time we add a new parametrized thing we have to teach it about all these frobs" problem. I hope that helps; happy to try to clarify anything above that's still being confusing. -Boris
Received on Thursday, 12 January 2017 18:55:37 UTC