Stream: git-wasmtime

Topic: wasmtime / issue #1934 Share memory between linked modules


view this post on Zulip Wasmtime GitHub notifications bot (Aug 26 2021 at 17:29):

willygroup commented on issue #1934:

Hi!
There are any progress on shared memory between linked modules?
I'm trying to create a "WasmMachine" that links an "sdk module" that contains some wrapper to host_functions and a secondary module that calls the sdk functions.

I would like call from a the secondary wasm (sources in rust) the sdk functions passing just pointers to a shared linear memory.
Something like this (is basically the linker example):

`
let engine = Engine::default();
let mut linker = Linker::new(&engine);
let mut store = Store::new(&engine, ());

let wasm_module = Module::from_file(&engine, MODULE_WASM)?;
let sdk_module = Module::from_file(&engine, SDK_WASM)?;

linker.func_wrap("host", "log", host_log)?;

// Memory from host
// let mem = Memory::new(&mut store, MemoryType::new(Limits::new(17, None)))?;
// linker.define("env", "memory", mem)?;

let sdk_module = linker.instantiate(&mut store, &sdk_module)?;

// Using the sdk-memory
let mem = sdk_module
    .get_memory(&mut store, "memory")
    .expect("Expected 'memory' not found");
linker.define("env", "memory", mem)?;

linker.instance(&mut store, "wasm-sdk", sdk_module)?;

let wasm_module = linker.instantiate(&mut store, &wasm_module)?;

let add = wasm_module.get_typed_func::<(i32, i32), i32, _>(&mut store, "add")?;

let res = add.call(&mut store, (41, 1))?;

println!("res_add: {}", res);`

I'm trying in two ways:

  1. Compiling the wasm module with the flag --import-memory" and then creating a host memory like this:
    let mem = Memory::new(&mut store, MemoryType::new(Limits::new(17, None)))?;

  2. Compiling just the secondary module with the flag --import-memory" and then export the memory from the sdk_module and using it for the secondary module.
    let mem = sdk_module .get_memory(&mut store, "memory") .expect("Expected 'memory' not found");

view this post on Zulip Wasmtime GitHub notifications bot (Aug 26 2021 at 17:38):

bjorn3 commented on issue #1934:

While I am not sure why wasmtime gives an error, even if it doesn't --import-memory is not enough to make this work. --import-memory only causes the wasm module to import an externally provided memory. It will still overwrite part of it with it's data segment. This is almost guaranteed to overwrite the part of the linear memory to which the exporting wasm module has written it's data segment, causing corruption. I am not sure if the LLVM toolchain has an option to move the location where the data segment is imported to ensure that it doesn't conflict between the wasm modules. In addition the heap allocator of each wasm module likely expects to be the only allocator operating on the linear memory which may cause both allocators to give the same part of the memory to callers in both wasm modules.

view this post on Zulip Wasmtime GitHub notifications bot (Aug 27 2021 at 00:04):

alexcrichton edited a comment on issue #1934:

Hi!
There are any progress on shared memory between linked modules?
I'm trying to create a "WasmMachine" that links an "sdk module" that contains some wrapper to host_functions and a secondary module that calls the sdk functions.

I would like call from a the secondary wasm (sources in rust) the sdk functions passing just pointers to a shared linear memory.
Something like this (is basically the linker example):

    let engine = Engine::default();
    let mut linker = Linker::new(&engine);
    let mut store = Store::new(&engine, ());

    let wasm_module = Module::from_file(&engine, MODULE_WASM)?;
    let sdk_module = Module::from_file(&engine, SDK_WASM)?;

    linker.func_wrap("host", "log", host_log)?;

    // Memory from host
    // let mem = Memory::new(&mut store, MemoryType::new(Limits::new(17, None)))?;
    // linker.define("env", "memory", mem)?;

    let sdk_module = linker.instantiate(&mut store, &sdk_module)?;

    // Using the sdk-memory
    let mem = sdk_module
        .get_memory(&mut store, "memory")
        .expect("Expected 'memory' not found");
    linker.define("env", "memory", mem)?;

    linker.instance(&mut store, "wasm-sdk", sdk_module)?;

    let wasm_module = linker.instantiate(&mut store, &wasm_module)?;

    let add = wasm_module.get_typed_func::<(i32, i32), i32, _>(&mut store, "add")?;

    let res = add.call(&mut store, (41, 1))?;

    println!("res_add: {}", res);

I'm trying in two ways:

  1. Compiling the wasm module with the flag --import-memory" and then creating a host memory like this:
    let mem = Memory::new(&mut store, MemoryType::new(Limits::new(17, None)))?;

  2. Compiling just the secondary module with the flag --import-memory" and then export the memory from the sdk_module and using it for the secondary module.
    let mem = sdk_module .get_memory(&mut store, "memory") .expect("Expected 'memory' not found");

view this post on Zulip Wasmtime GitHub notifications bot (Aug 30 2021 at 06:48):

willygroup commented on issue #1934:

Thanks for the reply.
I managed to import the same memory for both modules and this looks "almost" to work if I don't mess too much with the memory allocation :D
There is no way to tell a module to use the allocator from another module?
Like this is not very useful linking modules for my project :disappointed:

view this post on Zulip Wasmtime GitHub notifications bot (Aug 30 2021 at 07:37):

bjorn3 commented on issue #1934:

There is no way to tell a module to use the allocator from another module?

Maybe if you only link a single wasm module against the allocator and then let the other link against the allocator functions of the first? As for how to achieve this, I have no idea.

view this post on Zulip Wasmtime GitHub notifications bot (Aug 31 2021 at 08:59):

davxy commented on issue #1934:

Hi there. I'm interested as well :)

Preamble:

In particular, I'm trying to:

Any ideas?

Thanks for you awesome work, David

view this post on Zulip Wasmtime GitHub notifications bot (Aug 31 2021 at 09:00):

davxy edited a comment on issue #1934:

Hi there. I'm interested as well :)

Preamble:

In particular, I'm trying to:

Any ideas?

Thanks for you awesome work, David

view this post on Zulip Wasmtime GitHub notifications bot (Aug 31 2021 at 09:00):

davxy edited a comment on issue #1934:

Hi there. I'm interested as well :)

Preamble:

In particular, I'm trying to:

Any ideas?

Thanks for you awesome work, David

view this post on Zulip Wasmtime GitHub notifications bot (Aug 31 2021 at 09:11):

bjorn3 commented on issue #1934:

It seems that there is a tool convention for dynamic libraries<sup>[1]</sup>, but it is a work in progress and requires either using emscripten, which only runs on the web, or parsing a "dylink" section when loading to determine which dynamic libraries to load and then some additional code to actually link them. [2] gives some more information on how to make it work. At the time of writing of that article there were a couple of bugs in LLVM and lld. I don't know if they are all fixed yet.

[1]: https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md
[2]: https://iandouglasscott.com/2019/07/18/experimenting-with-webassembly-dynamic-linking-with-clang/

view this post on Zulip Wasmtime GitHub notifications bot (May 05 2022 at 16:54):

alexcrichton commented on issue #1934:

I'm going to close this since this issue is quite old at this point and in general the problems here are toolchain-related rather than Wasmtime related.

view this post on Zulip Wasmtime GitHub notifications bot (May 05 2022 at 16:54):

alexcrichton closed issue #1934:

I've tried to experiment with linking several wasm modules together (https://github.com/bytecodealliance/wasmtime/blob/master/examples/linking.rs). It works but it seems the memory isn't "shared". For instance it is impossible to send a string between modules. Am I missing something? Thanks!


Last updated: Dec 23 2024 at 12:05 UTC