Closed magcius closed 5 years ago
For cases where there is a limited number of host-provided subclasses (e.g. DOMEvent
-> DOMMouseEvent
), this is implementable in the binding itself (e.g. some host-provided DOMMouseEvent* DOMEvent_as_DOMMouseEvent(DOMEvent*)
import generated from WebIDL)
This wouldn't solve cases with union types like HTMLCanvasElement::getContext
, but that's already a pretty nasty stretch for WebIDL's type system.
You seem to suggest adding a JS-specific instruction to Wasm itself. That it is not an option, because Wasm has to remain independent of embeddings. The only option is to import a respective helper from the environment. The host binding framework might provide some aid for doing that.
For the kind of checks IDL does you don't want instanceof btw, you need brand checks as only those work across globals (see also https://github.com/heycam/webidl/issues/97).
I don't think there's anything JS-specific about casting host objects from one kind to another. Perhaps my choice of instanceof
wording was poor, but there needs to exist some mechanism to translate DOMEvent*
to DOMMouseEvent*
and back. My preference is for this be runtime-checkable but we could simply make it trap instead on invalid cast.
If the solution is to generate host functions for every single type pair, that's fine, even if I think it's a bit strange.
We have definitely talked about a dynamic cast operator in the context of wasm GC types. If host types (like DOMEvent
and DOMMouseEvent
) are described as type imports (as previously discussed), then this could mostly fall out for free of the GC feature. Whether a cast from or to a host-type succeeds would, of course, be host defined (just like calling a host import).
However, with just the host binding feature, we don't have first-class reference types. We have talked (in CG meetings, not yet in this proposal) of having a copy_elem
opcode which copies from one table element into another (in a same or different table); this is just a basic necessity. If we dropped the restriction that the source/dest tables had to have the exact same element type, that would imply a host-defined check, symmetric to the abovementioned dynamic cast operator.
That works for me. I would also like to propose some way of testing this at runtime. Assuming there are no implicit conversions in copy_elem
, a can_copy_elem
opcode that takes the same arguments and returns 1
if the equivalent copy_elem
can be made and 0
otherwise would be a nice addition.
Hmm, interesting. Right, because if a failed conversion traps, and traps are "expensive", a non-trapping query makes sense.
Closing as out-of-date: these concepts don't map to the current proposal, which has evolved a lot since this issue was opened.
Host bindings, DOM in particular, use subclasses a lot. We would need some ability to do type discrimination. For instance, if I were to receive a
DOMEvent
object, I would likely want to be able to determine that this isDOMMouseEvent
, and be able to callDOMMouseEvent
-y things on it.The details on runtime typechecking in the current proposal are vague (it just says "Throw TypeError (as now) if the wrong type is stored in a Table." but does not elaborate on what "the wrong type" means). Assuming that this is a strict 1:1 type-check, we would need some way to do runtime type discrimination, and a way to cast from one type to another.
Possible idea: a
CAST
instruction which takes two table indexessrc
anddest
. The instruction checkssrc instanceof TableType(dest)
. If the check passes,1
is pushed to the stack and the object's address copied intodest
, so it exists in both tables. Otherwise,0
is pushed to the stack. Cleanup for bothsrc
anddest
is left to native code.A variant of the instruction which takes a table index and a typeidx might also be entertained, in case of
if (foo instanceof Type)
checks that have no need to access the resulting casted object.