- 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