Lifeblossom opened issue #7883:
Test Case
https://github.com/Lifeblossom/wasmtime-resource-paremeter-bug-report
Wit file:
package component:bug-report; world example { import resource2-interface; import resource1-interface; } interface resource1-interface { create: func() -> resource1; resource resource1; } interface resource2-interface { use resource1-interface.{resource1}; create-resource2: func(resource1: resource1) -> resource2; do-stuff: func(resource1: resource1, resource2: resource2) -> resource2; resource resource2; }
Steps to Reproduce
- Clone repository
- Run cargo component build
- Run cargo test --test test
Test that compares returned resource instances will run
Expected Results
Test passes
Actual Results
Test failes on resource2 comparison - that means that
create-resource2
returned the same value two times.Versions and Environment
Wasmtime version or commit: 17.0.0
Operating system: Windows 11
Architecture: amd64
Extra Info
Test also includes method that uses both resource1 and resource2. You can comment out
ensure!(res2_1 != res2_2);
which causes this method to run. Invocation results in following error:Error: unknown handle index 0
Lifeblossom edited issue #7883:
Test Case
https://github.com/Lifeblossom/wasmtime-resource-paremeter-bug-report
Wit file:
package component:bug-report; world example { import resource2-interface; import resource1-interface; } interface resource1-interface { create: func() -> resource1; resource resource1; } interface resource2-interface { use resource1-interface.{resource1}; create-resource2: func(resource1: resource1) -> resource2; do-stuff: func(resource1: resource1, resource2: resource2) -> resource2; resource resource2; }
Steps to Reproduce
- Clone repository
- Run cargo component build
- Run cargo test --test test
Test that compares returned resource instances will run
Expected Results
Test passes
Actual Results
Test failes on resource2 comparison - that means that
create-resource2
returned the same value two times.Versions and Environment
Wasmtime version or commit: 17.0.0
Operating system: Windows 11
Architecture: amd64
Extra Info
Test also includes method that uses both resource1 and resource2. You can comment out
ensure!(res2_1 != res2_2);
which causes this method to run. Invocation results in following error:Error: unknown handle index 0
```[tasklist]
Tasks
~~~
Lifeblossom edited issue #7883:
Test Case
https://github.com/Lifeblossom/wasmtime-resource-paremeter-bug-report
Wit file:
package component:bug-report; world example { import resource2-interface; import resource1-interface; } interface resource1-interface { create: func() -> resource1; resource resource1; } interface resource2-interface { use resource1-interface.{resource1}; create-resource2: func(resource1: resource1) -> resource2; do-stuff: func(resource1: resource1, resource2: resource2) -> resource2; resource resource2; }
Steps to Reproduce
- Clone repository
- Run cargo component build
- Run cargo test --test test
Test that compares returned resource instances will run
Expected Results
Test passes
Actual Results
Test failes on resource2 comparison - that means that
create-resource2
returned the same value two times.Versions and Environment
Wasmtime version or commit: 17.0.0
Operating system: Windows 11
Architecture: amd64
Extra Info
Test also includes method that uses both resource1 and resource2. You can comment out
ensure!(res2_1 != res2_2);
which causes this method to run. Invocation results in following error:Error: unknown handle index 0
Lifeblossom edited issue #7883:
Test Case
https://github.com/Lifeblossom/wasmtime-resource-paremeter-bug-report
Wit file:
package component:bug-report; world example { import resource2-interface; import resource1-interface; } interface resource1-interface { create: func() -> resource1; resource resource1; } interface resource2-interface { use resource1-interface.{resource1}; create-resource2: func(resource1: resource1) -> resource2; do-stuff: func(resource1: resource1, resource2: resource2) -> resource2; resource resource2; }
Steps to Reproduce
- Clone repository
- Run cargo component build
- Run cargo test --test test
Test that compares returned resource instances will run
Expected Results
Test passes
Actual Results
Test failes on resource2 comparison - that means that
create-resource2
returned the same value two times.Versions and Environment
Wasmtime version or commit: 17.0.0
Operating system: Windows 11
Architecture: amd64
Extra Info
Test also includes method that uses both resource1 and resource2. You can comment out
ensure!(res2_1 != res2_2);
which causes this method to run. Invocation results in following error:Error: unknown handle index 0
Other findings
When using debugger bothres2_1
andres_2_2
have idx0
, but whenres_1_1
is replaced withres_1_2
it is1
. So I guess the resource id is taken from resource that was used as parameter.
alexcrichton commented on issue #7883:
Thank you for the report and the reproduction, it was very thorough! I was able to reproduce this and after digging into it I've opened up https://github.com/bytecodealliance/wasmtime/pull/7902 which is sort of a fix and sort of not.
The root issue here is that on this line I suspect you intended
res1_2
instead ofres1_1
. Otherwise what you're attempting to do is to reuse an resource previously consumed again, which is not valid to do. The reason #7902 fixes this is that the resuse of a consumed resource now triggers a runtime error instead of silently allowing it.Much of this comes because we've found it difficult historically to map resource types into Rust's type system. For example you might expect an owned value for resources but that has unfortunately not played out well so that's not how they work. Resources are instead and index into something owned by the store which means that they can suffer ABA and use-after-free style patterns (not in the unsound sense of use-after-free, moreso in the like-this-example-use-the-same-thing-twice sense).
I'll note that this also means that equality between resources is somewhat loose at best. Resource equality doesn't take into account the
rep
that the underlying resource was created with. Additionally equality doesn't mean much with consumed resources like in this case because once an index is consumed then anything else could take it.In any case I hope that's all able to help at least unblock you, but if you have further questions I can try to answer them here.
Lifeblossom commented on issue #7883:
It wasn't a typo - I didn't knew that
borrow
exists and since bindings allowed to me use resource multiple times I've assumed that this will be handled properly (as in resource won't be used).
Now when I think about it on the other side I get Resource<something> object which also is kinda suprising in this context. I would expect to just get the object without any wrapper (since the object is used by my function I can just drop it).
Lifeblossom edited a comment on issue #7883:
It wasn't a typo - I didn't know that
borrow
exists and since bindings allowed to me use resource multiple times I've assumed that this will be handled properly (as in resource won't be used).
Now when I think about it on the other side I get Resource<something> object which also is kinda suprising in this context. I would expect to just get the object without any wrapper (since the object is used by my function I can just drop it).
alexcrichton commented on issue #7883:
Indeed designing embedding APIs is not easy!
ResourceAny
andResource<T>
are the best we could figure out for now on the host side. If you've got suggestions about how to improve though please let us know!
alexcrichton closed issue #7883:
Test Case
https://github.com/Lifeblossom/wasmtime-resource-paremeter-bug-report
Wit file:
package component:bug-report; world example { import resource2-interface; import resource1-interface; } interface resource1-interface { create: func() -> resource1; resource resource1; } interface resource2-interface { use resource1-interface.{resource1}; create-resource2: func(resource1: resource1) -> resource2; do-stuff: func(resource1: resource1, resource2: resource2) -> resource2; resource resource2; }
Steps to Reproduce
- Clone repository
- Run cargo component build
- Run cargo test --test test
Test that compares returned resource instances will run
Expected Results
Test passes
Actual Results
Test failes on resource2 comparison - that means that
create-resource2
returned the same value two times.Versions and Environment
Wasmtime version or commit: 17.0.0
Operating system: Windows 11
Architecture: amd64
Extra Info
Test also includes method that uses both resource1 and resource2. You can comment out
ensure!(res2_1 != res2_2);
which causes this method to run. Invocation results in following error:Error: unknown handle index 0
Other findings
When using debugger bothres2_1
andres_2_2
have idx0
, but whenres_1_1
is replaced withres_1_2
it is1
. So I guess the resource id is taken from resource that was used as parameter.
Last updated: Dec 23 2024 at 12:05 UTC