wapc / wapc-rs

waPC Rust monorepo
Apache License 2.0
75 stars 9 forks source link

module hotswapping problem #50

Closed Kerosin3 closed 1 year ago

Kerosin3 commented 1 year ago

Hello! I'm trying to perform a simple task inside a wasm module (calcing hash of a data supplied) and also preforming hot module-switching. The problem is that I'm not getting an expected results. There are no errors neither in log, nor in the app, still, I get the output as if just one module was instantiated, debug log shows that only I am calling only the first module (modules functionality slightly differs, so I should have a different output after deserialization).

Can you tell me if I am doing something wrong based on the code or based on running the example I supplied? here is a fork with example I wrote. (just run cargo run -p wasmtime-provider --example wasmtime-hash-mreplace something in wasmtime-provider)

https://github.com/Kerosin3/wapc-rs-m/tree/develop

jsoverson commented 1 year ago

@Kerosin3 Thanks for the issue! The hotswapping implementation has been around for ages. I (and apparently others) haven't exercised it in a while. It looks like the implementation retains a reference to the original guest call function so every subsequent send will use the original module's export.

Change the implementation of replace() in wasmtime-provider to the following to fix it:

  fn replace(
    &mut self,
    module: &[u8],
  ) -> std::result::Result<(), Box<(dyn std::error::Error + Send + Sync + 'static)>> {
    info!(
      "HOT SWAP - Replacing existing WebAssembly module with new buffer, {} bytes",
      module.len()
    );

    let module = Module::new(&self.engine, module)?;
    self.module = module;
    self.instance_pre = self.linker.instantiate_pre(&self.module)?;
    let new_instance = self.instance_pre.instantiate(&mut self.store)?;
    if let Some(inner) = self.inner.as_mut() {
      *inner.instance.write() = new_instance;
      let gc = guest_call_fn(&mut self.store, &inner.instance)?;
      inner.guest_call_fn = gc;
    }

    Ok(self.initialize()?)
  }
Kerosin3 commented 1 year ago

That worked out! I've also created a pull request with the exmple I wrote, you may fing it usefull the project. https://github.com/wapc/wapc-rs/pull/51