In default wasmtime 6.0.1 I can use Linker::func_wrap
to define a host function taking a Caller
as a parameter, on which the host function can call get_export
https://docs.rs/wasmtime/latest/wasmtime/struct.Caller.html#method.get_export and consecutively get a Memory
handle via https://docs.rs/wasmtime/latest/wasmtime/enum.Extern.html#method.into_memory
Component LinkerInstance::func_wrap
https://docs.rs/wasmtime/latest/wasmtime/component/struct.LinkerInstance.html#method.func_wrap , however, expects the closure to take https://docs.rs/wasmtime/latest/wasmtime/struct.StoreContextMut.html as the parameter, which does not provide access to any of the exports
Moreover, the ExportInstance
itself does not seem to provide means to get anything other than a function, module or an instance https://docs.rs/wasmtime/latest/wasmtime/component/struct.ExportInstance.html
Is there a way for a host function to access the guest's memory in the component-model and if so, how?
There is no means by which the underlying linear memory can be accessed with the component model because the abstraction layer of components encapsulates these implementation details of the core wasm module.
Could you expand a bit more on what you need the original linear memory for?
I'd like to support a "syscall-like" interface, where a guest is passing a pointer and a length to the host via the host function and the host writes to it. That works fine in default wasmtime using Memory::write
https://docs.rs/wasmtime/latest/wasmtime/struct.Memory.html#method.write
Essentially this is for backwards-compatiblity with existing Wasm modules while we transition to component model fully
For reference, here's how it works in "default" https://github.com/wasmCloud/wasmCloud/blob/a2ccbb2e1786d2251951f953bdc7f0cca1d8e9fa/src/actor.rs#L88-L483 and I'd like to be able to expose the same ABI to component
Ok that makes sense, and for that functionality you'll have to model it differently in the component model. I'd recommend looking into preview2's API design along with the preview1-to-preview2 adapter in the preview2-prototyping repository
Right, so looking at https://github.com/bytecodealliance/preview2-prototyping it seems that what it does is it takes a WebAssembly module using preview1 ABI and turns that into a component - what I want to do is essentially reversed, where I want to take an existing WebAssembly component, embed a "translation layer" to the legacy ABI and run that on a host, which would be able to parse the resulting WebAssembly, but still interact with it through the legacy ABI
Does this make sense?
That makes sense, yes, but currently that's not possible. The abstration level and layer of the component model is such that you can't acquire an underlying linear memory from the host's point of view. From the host's point of view it must communicate with component model types, e.g. things like list<u8>
and such
The rough analogy is that if you had something like an HTTP RPC protocol or something like that you can't make an RPC for "please fill in this buffer" because you can't get written to by some remote system, for example.
In other words, component interfaces should always be virtualizable, i.e. implementable by another component with no special powers to inspect another component's memory.
Of course, you could do it ptrace-style where the component exports a function that takes an offset and a length and returns a list<u8>
of the memory at that location (and another one that writes a list<u8> to a given offset) :)
I see, thank you so much for your answers!
Just a simple WIT like that actually suffices:
interface host {
host-call: func(binding: string, namespace: string, operation: string, payload: list<u8>) -> result<list<u8>, string>
}
default world actor {
import host: self.host
export guest-call: func(operation: string, payload: list<u8>) -> result<list<u8>, string>
}
So we'll go the "componentization" route instead :rocket:
Last updated: Dec 23 2024 at 13:07 UTC