wasmerio / wasmer

🚀 The leading Wasm Runtime supporting WASIX and WASI
https://wasmer.io
MIT License
18.87k stars 807 forks source link

wai-bindgen-wasmer 0.4 doesn't compile #3888

Open kajacx opened 1 year ago

kajacx commented 1 year ago

Describe the bug

Using the latest published version of wai-bindgen-wasmer which is 0.4.0, doesn't work correctly. Trying to pass a list of structs is a compile error.

Steps to reproduce

Clone this repo at the list-of-structs-is-compile-error tag for a reproducible example. Run cargo run in the with-wai-sys folder to see the compile error.

In the example, this wai file is used:

pass-color-list: func(colors: list<color>) -> list<color>

record color {
  r: float32,
  b: float32,
  g: float32,
}

And imported with:

wai_bindgen_wasmer::export!("../protocol-host.wai");

Expected behavior

Bindings should generate correctly without an error.

Actual behavior

There is a compile error in the generated bindings: cannot borrowstoreas mutable because it is also borrowed as immutable

Additional context

Older version of wai-bindgen-wasmer worked correctly, but it used wasmer 3.1. The new version of wai-bindgen-wasmer is using wasmer 3.3, but is not migrated properly. There was a breaking change from wasmer 3.1 to 3.3:

Also, going from wasmer 3.1 to 3.3 is a breaking change. In 3.1, MemoryView::new (link):

impl<'a> MemoryView<'a> {
    pub(crate) fn new(memory: &'a Memory, store: &impl AsStoreRef) -> Self { ... }

But in 3.3 (link):

impl<'a> MemoryView<'a> {
    pub(crate) fn new(memory: &Memory, store: &'a impl AsStoreRef) -> Self {
kajacx commented 1 year ago

Good news everyone! It turns out that there is an existing function for this case:

    /// Borrows a new mutable reference of both the attached Store and host state
    pub fn data_and_store_mut(&mut self) -> (&mut T, StoreMut) {
        let data = self.func_env.as_mut(&mut self.store_mut) as *mut T;
        // telling the borrow check to close his eyes here
        // this is still relatively safe to do as func_env are
        // stored in a specific vec of Store, separate from the other objects
        // and not really directly accessible with the StoreMut
        let data = unsafe { &mut *data };
        (data, self.store_mut.as_store_mut())
    }

I will work on PR tomorrow.

kajacx commented 1 year ago

I have created a draft pull request: https://github.com/wasmerio/wai/pull/42

I need help with deciding on how to manage the new versions of wasmer and wasix in the imports, see the PR for more details.