-
Notifications
You must be signed in to change notification settings - Fork 178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error on creating a resource with a list of tuples in variant #817
Comments
Thanks for the report, but there's quite a lot behind this issue which isn't here and might be where the issue is from reading over this. Nothing looks awry from reading over this but I'm not sure for example where the If you could provide a reproducible example for this that'd be a great start! |
The I've made a repo that reproduces the issue in as little code I could: https://github.com/Exotik850/wit-resource-fail |
How did you build Also, to confirm, is the error you're seeing this:
If so that indicates what's probably a bug in the guest and/or corruption there because invalid utf-8 is being passed somewhere by accident. |
Hmm, that's quite strange, It works on my work laptop but not my home computer, both running windows 11. |
Turns out I forgot to have |
Hm I wonder if you're perhaps running into a rustc issue in that case? I'm also not sure how, though. Do you have a way to build |
After fiddling with it for a while I think I'm getting close to something, if I initialize the string that would go into the tomlvalue beforehand like this:
it jumbles it before the variant is sent over to the host:
But when initialized in the same line as the tomlvalue like this:
It doesn't let the toml for the string be initialized at all:
This happens on both my laptop and my desktop, and the most recent changes have been pushed to the MRE |
Can you provide details on how to build this all from source to reproduce the error you're seeing on both systems? Basically what repos at what commits are used and what commands are done to run this. |
There's a readme in this repo that has all of the commands to build the wasm and then run the host. Swapping between the commented out lines in the |
Ah ok this is definitely a bug in the generated bindings and what's amounting to UB/use-after-free. Looking at the generated code I see: 91 impl Toml {
92 #[allow(unused_unsafe, clippy::all)]
93 /// Creates a value in table and returns the handle
94 pub fn new(value: TomlValue) -> Self {
95 #[allow(unused_imports)]
96 use wit_bindgen::rt::{alloc, string::String, vec::Vec};
97 unsafe {
98 let mut cleanup_list = Vec::new();
99 let (result4_0, result4_1, result4_2) = match value {
100 TomlValue::String(e) => {
101 let vec0 = e;
102 let ptr0 = vec0.as_ptr() as i32;
103 let len0 = vec0.len() as i32;
104 (0i32, ptr0, len0)
105 }
... where the string |
This commit fixes an soundness issue in the Rust code generator's generated code. Previously unsound code was generated when: * An import had a parameter * That had either a list or a variant of an aggregate where: * Where one field was a `list<T>` or `string` * And another field was an owned resource In this situation the Rust generator uses an "owned" type for the argument, such as `MyStruct`. This is done to reflect how ownership of the resource in the argument is lost when the function is called. The problem with this, however, is that the rest of bindings generation assumes that imported arguments are all "borrowed" meaning that raw pointers from lists/strings can be passed through to the canonical ABI. This is not the case here because the argument is owned, meaning that the generated code would record an argument to be passed to the canonical ABI and then promptly deallocate the argument. The fix here is preceded by a refactoring to how Rust manages owned types to make the fix possible. The general idea for the fix though is that while `x: MyStruct` is the argument to the function all references internally are through `&x` to ensure that it remains rooted as an argument, preserving all pointers to lists and such. This unfortunately means that ownership can no longer model movement of resources and instead interior mutability must be used (since we have to move out of `&Resource<T>` since everything is borrowed). Fixing that, however, is probably not worth the complexity at this time. Closes bytecodealliance#817 Closes bytecodealliance/wasmtime#7951
Ok I have gotten around to really digging into this and I've confirmed with your repository that it's fixed by #846. Thank you again for taking the time to open this issue and work with me debugging it, I very much appreciate it! |
Absolutely! Glad I could be of help 😊 |
This commit fixes an soundness issue in the Rust code generator's generated code. Previously unsound code was generated when: * An import had a parameter * That had either a list or a variant of an aggregate where: * Where one field was a `list<T>` or `string` * And another field was an owned resource In this situation the Rust generator uses an "owned" type for the argument, such as `MyStruct`. This is done to reflect how ownership of the resource in the argument is lost when the function is called. The problem with this, however, is that the rest of bindings generation assumes that imported arguments are all "borrowed" meaning that raw pointers from lists/strings can be passed through to the canonical ABI. This is not the case here because the argument is owned, meaning that the generated code would record an argument to be passed to the canonical ABI and then promptly deallocate the argument. The fix here is preceded by a refactoring to how Rust manages owned types to make the fix possible. The general idea for the fix though is that while `x: MyStruct` is the argument to the function all references internally are through `&x` to ensure that it remains rooted as an argument, preserving all pointers to lists and such. This unfortunately means that ownership can no longer model movement of resources and instead interior mutability must be used (since we have to move out of `&Resource<T>` since everything is borrowed). Fixing that, however, is probably not worth the complexity at this time. Closes bytecodealliance#817 Closes bytecodealliance/wasmtime#7951
* Refactor how Rust handles ownership This commit is the next in a long line of refactors to try to model how the Rust generator handles ownership. The Rust generator has an `ownership` knob for deciding how to render types. The Rust generator additionally models ownership of resources/lists in params/results of imports/exports. Putting all of this together has led to many attempts to wrangle this in a form that's understandable but every time a bug comes up I feel like I don't understand what's going on. I've made another attempt in this commit. Here the goal is to centralize knowledge about types as much as possible. Instead of being spread out over a few methods everything is hopefully now centralized in a single type and a single "main method". All other little pieces stem from these two and are modeled to be relatively simple compared to the "main method". Whether or not this stands the test of time we'll see. This does change generated code in some situations as can be seen by the test that was updated. Nothing major should be changed, but a few more borrows are now required in places which probably should have been borrows before. More comments are found in the code about specific changes made here. * Fix unsoundness in generated Rust code This commit fixes an soundness issue in the Rust code generator's generated code. Previously unsound code was generated when: * An import had a parameter * That had either a list or a variant of an aggregate where: * Where one field was a `list<T>` or `string` * And another field was an owned resource In this situation the Rust generator uses an "owned" type for the argument, such as `MyStruct`. This is done to reflect how ownership of the resource in the argument is lost when the function is called. The problem with this, however, is that the rest of bindings generation assumes that imported arguments are all "borrowed" meaning that raw pointers from lists/strings can be passed through to the canonical ABI. This is not the case here because the argument is owned, meaning that the generated code would record an argument to be passed to the canonical ABI and then promptly deallocate the argument. The fix here is preceded by a refactoring to how Rust manages owned types to make the fix possible. The general idea for the fix though is that while `x: MyStruct` is the argument to the function all references internally are through `&x` to ensure that it remains rooted as an argument, preserving all pointers to lists and such. This unfortunately means that ownership can no longer model movement of resources and instead interior mutability must be used (since we have to move out of `&Resource<T>` since everything is borrowed). Fixing that, however, is probably not worth the complexity at this time. Closes #817 Closes bytecodealliance/wasmtime#7951
Working on this pr and whenever I create a resource with a list of tuples inside of a variant like so:
the wit representation of the resource:
This is the implementation of the resource, the bindings just call these functions:
It throws this error when calling the constructor of the function with table values like so:
The error isn't very helpful as to what went wrong:
I thought it was because it was a list of resources at first, but when it's initialized with an array object it works just fine, and
even when the implementation and signature are changed to be a
list<tuple<string, string>>
, it will cause the same error.I would like to try and fix this if I can, but I don't even know where to start 😅
The text was updated successfully, but these errors were encountered: