I'm trying to use wiggle, and am hitting the issue that the first return has to be primitive. Is there a strong requirement for that, or is it just a current technical limitation? I'd love to be able to use anyhow::Result<()>
as my "errno" type by encoding the context chain in an (array string)
so, the return types in wiggle happen to be a weird thing thats not fully worked out yet.
the convention in witx that wasi and wiggle agree on is that the very first return type is an atomic value that can encode either success or an error condition (basically, posix errno)
all subsequent return types are only valid when the first is success
there is no support for using a more complex error type at the abi level.
i suggest you use an enum for error like wasi's errno
type.
Are there plans to make more complex error types possible, is it something that has been formally decided against, or is it just pending design?
definitely not formally decided against. we havent pursued it in part because we havent needed to (there are a bunch of other stuff higher priority)
(BTW, is there an issue tracker for witx/wiggle? AFAICT it appears to be split and lost between wasi and wasmtime)
the pending design is that, one day soon, interface types will make it possible to send more complex types across these boundaries
and witx isnt trying to be interface types quite yet, because its just not ready.
if you need something before then, we can figure out a way to fit it into the way things work currently
as far as issue tracking - this is a bit of a tricky thing. the witx crate lives in WebAssembly/WASI because its very useful for validating changes to the standard itself, autogenerating the markdown docs from the doc comments (so the canonical docs are just in one place), and so on.
so its a bit like the wasm reference interpreter, you are welcome to use other tools but this one is the official validator
Got it, thank you :) so I guess I'll just ignore that problem for now, currently my callbacks expose few error types so I can just expose an enum, even though it's much less good UX (well... or maybe I'll just have my callbacks directly log the errors for now, even though said errors may end up being worked around on the other side of the chain)
all of the tools that generate code using the witx crate live elsewhere. many of them are in the wasmtime repo.
the other aspect of error handling is the user error conversion facilities of wiggle
do you grok what UserErrorConversion
is up to in wasi-common?
Hmm so I guess things like "complex error types aren't supported" should be tracked in webassembly/wasi so it's not forgotten about?
yeah, if youd like. i promise we wont forget about it, but it is useful to put my thinking on the record in a reply to that issue and let others chime in as well.
I think so, it's the place where I'd have walked the context trace of my anyhow::Error to turn it into an (array string) so it gets in the metadata, to be decoded on the wasm side :)
Gotcha, thanks :) any github handle I should tag?
anyway, since you and i agree that complex error types are the correct way to do programming, wiggle supports you using them through the argument
errors: { errno => RichError }` syntax in the arguments to the wiggle::from_witx! macro.
im pchickey
on github but no need to cc, i read all issues going to WebAssembly/WASI
Hmmmmm... but that will lose all the error metadata when going through the wasm boundary, right?
(Right now I'm just converting to a boolean $success for testing purposes)
yes, but it gives you the opportunity to log it, or save it in your ctx for later retrieval
Oh right I hadn't thought of logging there, thank you :)
Aaand actually storing in the ctx and returning an u64 handle is the killer idea: this way I can skip the whole wasm stack and feed it back to the other side
so if you want to save the complex error into your ctx, then you can have a special function thats get_latest_error which has two results (result $error $errno) (result $latest_error $your_complex_error_type)
Oh that's even better :)
This way no need to add wasm-skipping logic
ah yeah if you use a u64 ident that identifies which error, then you can skip the terrible posix errno()
-style get_latest_error
semantics and make it something like (param $error_idx u64) (result $errno $errno) (result $rich_error $rich_error)
...
theres no threads yet, so latest_error will work fine, but its one of those things thats just warty anyway
Thank you for all these ideas! I'll try to sum that all in a wasi issue :) (not sure I'll give back an u64 yet though, as it'd mean having to deal with gcing unused errors)
true. my assumption would be that errors should be finite and instances short-lived enough that storing them for a while is fine. but your design may be different.
Yeah I'd rather have a long-lived instance, as I'm using wasm for configuration so changing instances would mean having to resetup it
right on. my job is to keep instances as short-lived as possible. if you're lucky, you'll be the one to find whatever weird edge cases happen when wiggle-borrow
hits internal overflows that i havent found yet
Nice :D I was kind of wondering whether I shouldn't automatically restart the instance every few hours of uptime or so, to avoid leaks in user configuration affecting the program, but it may be fun to try running for a few weeks and see if actual bad things happen :)
im certain that wiggle-borrow
could use automated testing and that performance (and maybe even correctness?) improvements can be made. but i dont have the time to work on that more just now.
Makes sense! There are always priorities, and I'm with you that lots of other things are more important than wiggle-borrow's performance right now :)
i need to run for the day and go... participate in democracy
Cool, good luck participating in democracy!
And have a nice day :)
Hmm... Coming back here, it looks to me like a callback basically cannot return an array or string, and thus that last_error cannot actually return all the data. (or at least, I haven't figured out how to allocate data in the guest memory)
Is this correct? Is there a way to actually do it?
Currently the best I could think of would be to:
But then I feel like I'm missing something... maybe?
The webassembly module is responsible for allocating memory. The embedder doesn't have any knowledge about the allocator used by the wasm module.
Makes sense, what I was thinking was about exposing the allocator from wasm. It's actually what I'm currently doing for other parts of the wasm FFI: allocate a memory block via an allocate
function, then write serialized data to it, and deserialize/deallocate on the other site of the ffi. It's certainly less performant, but it's also the currently best way I found to properly bind functions from wasm to host.
Anyway, hopefully when wiggle or wit support exposing callbacks from wasm to host, it'll probably be possible to industrialize this by having the allocator function return a GuestPtr. But even then that will probably require some more API surface to be able to use such arrays/strings properly from wasm side?
That said I guess it's surely all already on the roadmap to interface types, so it's probably not worth discussing too much at length I guess :)
Last updated: Dec 23 2024 at 12:05 UTC