Add support to wit-component to polyfill WASI #338
Add support to wit-component to polyfill WASI #338alexcrichton merged 10 commits intobytecodealliance:mainfrom
Conversation
|
Some procedural notes:
|
|
It's also worth saying that my goal is that the |
|
Ok @pchickey this is ready to go. I've verified that this works locally with a larger integration with:
|
|
Ok the most recent commit is a pretty bad hack around finding the stack pointer (searching the name section). I was hoping that better could be done but I'm not sure we can at this time. At the very least this should enable C & Rust to be used to write these adapter modules. |
pchickey
left a comment
There was a problem hiding this comment.
I think I need a little more help understanding the validator, but the tests look good to me
This commit is an addition to the `wit-component` tool to be able to
polyfill WASI imports today using `wasi_snapshot_preview1` with a
component-model-using interface in the future. This is a large extension
to the functionality of `wit-component` internally since the generated
component is much "fancier".
The support in this commit is modeled as the addition of "adapter
modules" into the `wit-component` tool. An adapter module is understood
to translate from some core-wasm ABI into a component-model using ABI.
The intention is that for any previous API prior to the component model
an adapter module could be written which would translate from the prior
API to the new API. For example in WASI today there is:
(@interface func (export "random_get")
(param $buf (@WitX pointer u8))
(param $buf_len $size)
(result $error (expected (error $errno)))
)
whereas a component-model-using API would look more like:
random-get: func(size: u32) -> list<u8>
This component-model version can be adapted with a module such as:
(module $wasi_snapshot_preview1
(import "new-wasi" "random_get" (func $new_random_get (param i32 i32)))
(import "env" "memory" (memory 0))
(global $last_ptr (mut i32) i32.const 0)
(func (export "random_get") (param i32 i32) (result i32)
;; store buffer pointer in a saved global for `cabi_realloc`
;; later
(global.set $last_ptr (local.get 0))
;; 1st argument: the `size: u32`
local.get 1
;; 2nd argument: return pointer for `list<u8>`
i32.const 8
call $new_random_get
;; return a "success" return code
i32.const 0
)
;; When the canonical ABI allocates space for the list return value
;; return the original buffer pointer to place it directly in the
;; target buffer
(func (export "cabi_realloc") (param i32 i32 i32 i32) (result i32)
global.get $last_ptr)
)
Using this adapter module the internal structure of the generated
component can be done such that everything is wired up in all the right
places meaning that when the original module calls
`wasi_snapshot_preview1::random_get` it actually calls this shim module
which then calls the actual `new-wasi::random_get` import. There's a few
details I'm glossing over here like the stack used by the shim module
but this suffices to describe the general shape.
My plan in the future is to use this support to generate a component
from all test cases that this repository supports. That means that,
specifically for `wit-bindgen` tests, a fresh new interface representing
"future WASI" will be created and the WASI functions used by tests will
be adapted via this adapter module. In this manner components will now
be generated for all tests and then the next step is bytecodealliance#314, actually
ingesting these components into hosts.
Should help with debugging structure ideally
This unfortunately suffers greatly from false negatives, but at this time it's unclear if this can be done better.
|
Oops sorry I forgot to write documentation for the new structures, but I've added that all now. |
This commit is the next step in integrating `wasm32-wasi`, `wit-bindgen`, tests, and components all together. Tests are now again compiled with `wasm32-wasi` and use a repo-specific adapter module (with support from bytecodealliance#338) to support transforming the final module into an actual component. In supporting this feature the support from bytecodealliance#331 is refactored into a new `extract` Rust module so the functionality can be shared between the ingestion of the main module as well as ingestion of adapter modules. Adapter modules now are also supported on the CLI as a standalone file without having to specify other options. Note that the actual `wasi_snapshot_preview1.wasm` adapter is non-functional in this commit and doesn't do anything fancy. The tests in this repository don't really need all that much and I suspect all we'll really need to implement is `fd_write` for fd 1 (as that's stdout).
This commit is an addition to the
wit-componenttool to be able topolyfill WASI imports today using
wasi_snapshot_preview1with acomponent-model-using interface in the future. This is a large extension
to the functionality of
wit-componentinternally since the generatedcomponent is much "fancier".
The support in this commit is modeled as the addition of "adapter
modules" into the
wit-componenttool. An adapter module is understoodto translate from some core-wasm ABI into a component-model using ABI.
The intention is that for any previous API prior to the component model
an adapter module could be written which would translate from the prior
API to the new API. For example in WASI today there is:
whereas a component-model-using API would look more like:
This component-model version can be adapted with a module such as:
Using this adapter module the internal structure of the generated
component can be done such that everything is wired up in all the right
places meaning that when the original module calls
wasi_snapshot_preview1::random_getit actually calls this shim modulewhich then calls the actual
new-wasi::random_getimport. There's a fewdetails I'm glossing over here like the stack used by the shim module
but this suffices to describe the general shape.
My plan in the future is to use this support to generate a component
from all test cases that this repository supports. That means that,
specifically for
wit-bindgentests, a fresh new interface representing"future WASI" will be created and the WASI functions used by tests will
be adapted via this adapter module. In this manner components will now
be generated for all tests and then the next step is #314, actually
ingesting these components into hosts.