Finish bindings generation for (implements ..)#13513
Conversation
This commit is the final step in finishing up the bindings generation
story for `bindgen!` w.r.t. the `(implement ...)` component model
feature. Namely `bindgen!` now has the option `named_imports: { ... }`
which generates a new top-level `named_imports` module with nested
modules within it. These nested modules are similar to the
default-generated ones except that they additionally take an extra "id"
parameter in all trait methods. The `add_to_linker` function
additionally takes both a `&Component` and a `lookup` function.
Putting all this together the expected flow is:
* Host decide they want to accept any number of `import a: b:c/d;` from
components at runtime. Bindings are generated with
`named_imports: { ... }` in the `bindgen!` invocation.
* Hosts switch from linker-per-engine to instead using a
linker-per-component. After the typical population of items within the
`Linker` next the host uses the
`named_imports::b::c::d::add_to_linker`, for example. Here the host
performs lookup from whatever string was found in the component to an
ID key that the host knows about. Upon success this key will be closed
over in all `add_to_linker` functions. Upon failure the
`add_to_linker` closure fails.
* This per-component linker is used to instantiate and create instances
as usual. At runtime when a named import is invoked the closed-over ID
is passed to the trait implementation as a parameter. Hosts can thus
disambiguate through which interface the component made a call through.
Some light tests are added throughout this showcasing the various
capabilities. This notably added a new `ComponentExtern::is_implements`
method to peform semver-matching automatically so hosts can generate
bindings with one version and still accept `implements` with other
slightly different but compatible versions.
One thing I didn't think about when we discussed this yesterday: how much overhead does this introduce for hosts with large numbers of components loaded? (I'm not sure how much of a real alternative to this design there is, but I'd at least like to understand the costs a bit better.) |
|
I always forget to correct that as well, but what hosts are doing right now is actually a linker-per-engine plus an instance-pre-per-component. This PR doesn't change the latter, still an instance-pre-per-component, and the main difference is that when creating an instance-pre-per-component the host will likely |
Assuming you mean |
|
Oops, yes! |
This commit is the final step in finishing up the bindings generation story for
bindgen!w.r.t. the(implement ...)component model feature. Namelybindgen!now has the optionnamed_imports: { ... }which generates a new top-levelnamed_importsmodule with nested modules within it. These nested modules are similar to the default-generated ones except that they additionally take an extra "id" parameter in all trait methods. Theadd_to_linkerfunction additionally takes both a&Componentand alookupfunction.Putting all this together the expected flow is:
Host decide they want to accept any number of
import a: b:c/d;from components at runtime. Bindings are generated withnamed_imports: { ... }in thebindgen!invocation.Hosts switch from linker-per-engine to instead using a linker-per-component. After the typical population of items within the
Linkernext the host uses thenamed_imports::b::c::d::add_to_linker, for example. Here the host performs lookup from whatever string was found in the component to an ID key that the host knows about. Upon success this key will be closed over in alladd_to_linkerfunctions. Upon failure theadd_to_linkerclosure fails.This per-component linker is used to instantiate and create instances as usual. At runtime when a named import is invoked the closed-over ID is passed to the trait implementation as a parameter. Hosts can thus disambiguate through which interface the component made a call through.
Some light tests are added throughout this showcasing the various capabilities. This notably added a new
ComponentExtern::is_implementsmethod to peform semver-matching automatically so hosts can generate bindings with one version and still acceptimplementswith other slightly different but compatible versions.