Skip to content

js: Take a component as input, not interfaces #373

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 13, 2022

Conversation

alexcrichton
Copy link
Member

This commit is the implementation of #314 for the JS host generator.
The commit here covers basically everything in that issue for JS except
it generates a slightly different structure of the JS output. Otherwise
the main highlights are:

  • The JS host generator no longer implements the core Generator trait
    since it doesn't really fit in the component-as-input world. For now I
    created an InterfaceGenerator trait since similar functionality is
    used just not precisely the same. I expect that this will get iterated
    on over time as worlds and other host generators take shape.

  • The wasmtime-environ crate from Wasmtime itself, typically a "private"
    dependency of Wasmtime, is used to parse the input component and
    generate an instantiate function in JS. Wasmtime does all the heavy
    lifting of creating a linear list of initializers for the component
    and this empowers the generator to simply generate JS that is the list
    of initializers.

  • The wit-component crate is used to "extract" the Interface
    descriptions from the input component. This is used to generate type
    information for TypeScript as well as types for lifting/lowering.
    Internally a correlation is done from a lowering/lifting to an
    Interface function to connect the dots when instantiating a component.

Lots of pieces needed updating here such as the runtime tests, the
wit-bindgen CLI tool, and the demo web page. These are all updated for
the new structure of the JS host generator.

Overall this surprisingly went much more smoothly than I expected. With
wit-bindgen being able to extract Interface representations from a
component most of the prior JS host code generation was able to be
reused. Along the way I also felt that the addition of "worlds" would
have relatively obvious insertion points and would be relatively easily
handled in all the places.

The demo and runtime tests are proof enough to me at least that this all
works internally, and this feels like a solid foundation to iterate from
with the addition of worlds and continued support for JS hosts.

@alexcrichton
Copy link
Member Author

Procedurally this is built on #372 and additionally depends on bytecodealliance/wasmtime#5053, so will want to hold off on merging until those are both in.

Copy link
Contributor

@pchickey pchickey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

review still in progress, just pushing these easy ones

Copy link
Contributor

@pchickey pchickey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome, lets ship it. I spent some time going through this with @guybedford and we satisfied a bunch of curiosity we had about why the generated code looks like it does.

This commit is the implementation of bytecodealliance#314 for the JS host generator.
The commit here covers basically everything in that issue for JS except
it generates a slightly different structure of the JS output. Otherwise
the main highlights are:

* The JS host generator no longer implements the core `Generator` trait
  since it doesn't really fit in the component-as-input world. For now I
  created an `InterfaceGenerator` trait since similar functionality is
  used just not precisely the same. I expect that this will get iterated
  on over time as worlds and other host generators take shape.

* The `wasmtime-environ` crate from Wasmtime itself, typically a "private"
  dependency of Wasmtime, is used to parse the input component and
  generate an `instantiate` function in JS. Wasmtime does all the heavy
  lifting of creating a linear list of initializers for the component
  and this empowers the generator to simply generate JS that is the list
  of initializers.

* The `wit-component` crate is used to "extract" the `Interface`
  descriptions from the input component. This is used to generate type
  information for TypeScript as well as types for lifting/lowering.
  Internally a correlation is done from a lowering/lifting to an
  `Interface` function to connect the dots when instantiating a component.

Lots of pieces needed updating here such as the runtime tests, the
`wit-bindgen` CLI tool, and the demo web page. These are all updated for
the new structure of the JS host generator.

Overall this surprisingly went much more smoothly than I expected. With
`wit-bindgen` being able to extract `Interface` representations from a
component most of the prior JS host code generation was able to be
reused. Along the way I also felt that the addition of "worlds" would
have relatively obvious insertion points and would be relatively easily
handled in all the places.

The demo and runtime tests are proof enough to me at least that this all
works internally, and this feels like a solid foundation to iterate from
with the addition of worlds and continued support for JS hosts.
* Pull in latest `wasmtime` where `main` now works
* Add a `testwasi` implementation for JS and use it in all tests
* Add a dummy `printf` to a C test to ensure it imports `testwasi` like
  the other languages.
* Add a `fd_fdstat_get` stub to make C happy
* Update `fd_write` to only work for fd 1
@alexcrichton alexcrichton merged commit 4934194 into bytecodealliance:main Oct 13, 2022
@alexcrichton alexcrichton deleted the rewrite-js branch October 13, 2022 21:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants