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:
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)))?;
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");
- Always obtaining the error
Error: failed to get caller's exported memory
atadd.call
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.
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:
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)))?;
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");
- Always obtaining the error
Error: failed to get caller's exported memory
atadd.call
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:
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.
davxy commented on issue #1934:
Hi there. I'm interested as well :)
Preamble:
- I have a two modules, A and B, and I like to use B as a shared library.
- A is tiny and contains only the code that implements the application business logic.
- B is huge and contains all the std library functions and utilities
In particular, I'm trying to:
- share the memory between two modules => DONE
- call a function of module A from module B => DONE
- prevent A from statically link the std library stuff, eg. allocator code => NOT DONE (how we can do that?)
- prevent that an allocation in module A clash with an allocation in module B => NOT DOVE (I suppose that can be resolved by the point 3 by letting B using the allocator in A.
Any ideas?
Thanks for you awesome work, David
davxy edited a comment on issue #1934:
Hi there. I'm interested as well :)
Preamble:
- I have two modules, A and B, and I like to use B as a shared library.
- A is tiny and contains only the code that implements the application business logic.
- B is huge and contains all the std library functions and utilities
In particular, I'm trying to:
- share the memory between two modules => DONE
- call a function of module A from module B => DONE
- prevent A from statically link the std library stuff, eg. allocator code => NOT DONE (how we can do that?)
- prevent that an allocation in module A clash with an allocation in module B => NOT DOVE (I suppose that can be resolved by the point 3 by letting B using the allocator in A.
Any ideas?
Thanks for you awesome work, David
davxy edited a comment on issue #1934:
Hi there. I'm interested as well :)
Preamble:
- I have two modules, A and B, and I like to use B as a shared library.
- A is tiny and contains only the code that implements the application business logic.
- B is huge and contains all the std library functions and utilities
In particular, I'm trying to:
- share the memory between two modules => DONE
- call a function of module A from module B => DONE
- prevent A from statically link the std library stuff, eg. allocator code => NOT DONE (how we can do that?)
- prevent that an allocation in module A clash with an allocation in module B => NOT DONE (I suppose that can be resolved by the point 3 by letting B using the allocator in A.
Any ideas?
Thanks for you awesome work, David
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/
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.
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