Open guybedford opened 1 year ago
This seems akin to how DOMException interface objects inherit from %Error%. I don’t see how defining an AbstractModuleSource Web IDL interface would help with it — that would create a collision instead.
(i.e. if an “Error” interface had been defined, that wouldn’t mean its interface objects were %Error% — it would only mean its interface objects happen to have the same name. The globalThis.Error
property would end up redefined to refer to these other Web IDL objects instead of the %Error% intrinsic during InitializeHostDefinedRealm, which is when define the global property references happens.)
I can imagine a new extended attribute for interfaces explaining both cases, e.g.
[Exposed=*, Serializable, IntrinsicHeritage="%Error%"]
interface DOMException { /*...*/ };
[LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet), IntrinsicHeritage="%AbstractModuleSource%"]
interface Module { /*...*/ };
~I think that would also clean up how the existing case like this works, where it’s defined declaratively but isn’t actually integrated with the imperative steps for creating interface objects (a vestige from how the Web IDL spec used to be written?).~ It actually is in the imperative steps too I just realized — there’s a one-off call-out for DOMException in step 4 of “create an interface object”, which is correct ... but smells stinky, and it would be extra weird to add another unique case here rather than address it with a generic mechanism.
(The absent step for setting the [[Prototype]] of the constructor could likely be addressed at the same time.)
Good points. We probably should support both %AbstractModuleSource%
and %AbstractModuleSource.prototype%
chains here yes.
Perhaps that would mean two new attributes then?
[Exposed=*, Serializable, InstrinsicParent="%Error%", IntrinsicPrototypeParent="%Error.prototype%"]
interface DOMException { /*...*/ };
[LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet), IntrinsicParent="%AbstractModuleSource%", IntrinsicPrototypeParent="%AbstractModuleSource.prototype%"]
interface Module { /*...*/ };
It's quite a lot of machinery for a single case though that only possibly simplifies DOMException. Have there been other cases of this sort of thing?
While DOMException is an exception, we do have a similar thing for namespaces
in the console spec at https://console.spec.whatwg.org/#console-namespace where it overrides the default prototype from the https://webidl.spec.whatwg.org/#namespace-object steps effectively with a comment. Perhaps we could use a similar approach.
I wonder if @yuki3 or @saschanaz have thoughts about this.
My very personal preference is to define things systematically rather than defining things with ad-hoc rules (so, I tend to like the idea of [IntrinsicHeritage]). Having said that...
I understand I'm talking about a sort of ...politics?... and not design of software, architecture, etc. Purely technically talking, [IntrinsicHeritage] looks good. I understand %X.prototype% is different from %X%.prototype, but [IntrinsicPrototypeParent] looks a bit overkilling/redundant (we don't want to support totally different inheritances for interface objects and prototype objects but it looks possible). Can we implicitly assume %X.prototype% inheritance, too?
In summary, my preference is: 1. special rule (no extended attribute) is enough (and good in total imho), 2. either of [IntrinsicHeritage] or [IntrinsicParent] + [IntrinsicPrototypeParent].
DOMException
that would then fix #1107 too.Declarative comment / prose text “overrides” both have an unclear relationship to the imperative realm-initializing algorithms in Web IDL (when do the “overrides” happen?) and make it impossible for tooling that consumes Web IDL fragments to know about exceptional cases without hard-coding knowledge of them. Since I work on that kind of tooling, I’m biased to prefer an extended attribute solution.
In the past I think some EAs that aren’t quite “legacy” were given the Legacy
prefix to discourage new “unbridled” usage?
[Edit: @yuki3, what would you think of making the permitted values for such an extended attribute an explicit enumeration defined by Web IDL? This might have the effect of keeping the Web IDL spec a bottleneck-by-design that prevents unaudited proliferation in specs that shouldn’t really be using this; extending a new intrinsic would always mean opening an issue here.]
If a non-IDL solution is used, then it would suggest to me that the existing imperative step for taking care of DOMException...
...would want to be removed? Or is the idea that the “create an interface object” algorithm would introduce a new step like this for WebAssembly.Module
even though the interface is defined elsewhere?
BTW I think there is another example of this that’s also in WebAssembly? The NativeError-template Error classes. I’m unsure if they would benefit, but they do use use %Error%/%Error.prototype%.
Would it be possible to directly permit intrinsic inheritance for interfaces of the form:
interface DOMException : %Error% { ... }
interface Module : %AbstractModuleSource% { ... }
where this restricts intrinsic inheritance to be a specific case only - ie these must be well-defined intrinsic objects being subclassed, hopefully avoiding some kind of arbitrary object subclassing.
and then this intrinsic inheritance could itself be defined to include both the constructor and prototype inheritance chains, effectively in line with JS class inheritance.
Edit: I suppose it is not much different from a unified attribute, so this is more of a syntax question.
Adding a new syntax is more expensive to the infra than the extended attribute option. Given that the latter is already being questioned as there are only few cases, I doubt we would go that path.
In addition to what @saschanaz said, new Web IDL syntax probably wouldn’t make sense here because this is really about the ES binding (which is what the extended attributes defined by Web IDL are for).
Okay, so it sounds like if anything it would be a single attribute with some handling for class-like behaviours. If we restricted the attribute to only applying to JS intrinsics though would that mitigate concerns of overuse? Or would such an approach still need to be better motivated?
I think we've gotten a pretty clear signal from multiple implementers that prose-based overrides for these rare cases is preferred?
@domenic It does look like that — two implementors stated a preference for prose, and I’m not an implementor (at least not in a sense that I would expect to count towards such a decision).
About when prose text "overrides" happens, I think it's nice to have something like "run an interface-specific configuration algorithm" in the imperative realm-initializing algorithms in Web IDL, and let each spec define "run an interface-specific configuration algorithm". This way has already been used in several places, right?
Just as a random idea; It might make sense and be helpful to have an extended attribute like [InterfaceSpecificConfiguration] in order to indicate that the interface has its own unique prose text "overrides". For example, we can use the extended attribute to cross-check whether we appropriately hard-code the behavior.
I'm skeptical about getting rid of hard-coded behaviors even if [IntrinsicHeritage] were introduced (e.g. Location's valueOf, HTMLAllCollection's [[Call]]). I don't think it will be helpful in case of Chromium. However, I don't have a strong objection especially when it will be very helpful for other people and/or projects. The concern about [IntrinsicParent] + [IntrinsicPrototypeParent] will remain, though.
EDIT: And it's welcome to restrict the coverage of [IntrinsicHeritage] in order to prevent abuse. :)
The Source Phase Imports proposal requires that objects returned for the source phase must inherit from the new
AbstractModuleSource
intrinsic in their prototype chain.In order for the WebAssembly ESM Integration to express this inheritance in WebIDL, once Stage 3 is obtained for the proposal, we need to determine how to represent this intrinsic inheritance for
AbstractModuleSource
.Creating this as a new tracking issue for this
interface type definitionquestion.