Stream: git-wasmtime

Topic: wasmtime / issue #7883 Running method that takes resource...


view this post on Zulip Wasmtime GitHub notifications bot (Feb 07 2024 at 01:29):

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

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

view this post on Zulip Wasmtime GitHub notifications bot (Feb 07 2024 at 01:29):

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

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

~~~

view this post on Zulip Wasmtime GitHub notifications bot (Feb 07 2024 at 01:29):

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

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

view this post on Zulip Wasmtime GitHub notifications bot (Feb 07 2024 at 01:51):

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

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 both res2_1 and res_2_2 have idx 0, but when res_1_1 is replaced with res_1_2 it is 1. So I guess the resource id is taken from resource that was used as parameter.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 09 2024 at 14:46):

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 of res1_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.

view this post on Zulip Wasmtime GitHub notifications bot (Feb 09 2024 at 18:15):

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).

view this post on Zulip Wasmtime GitHub notifications bot (Feb 09 2024 at 18:15):

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).

view this post on Zulip Wasmtime GitHub notifications bot (Feb 09 2024 at 18:47):

alexcrichton commented on issue #7883:

Indeed designing embedding APIs is not easy! ResourceAny and Resource<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!

view this post on Zulip Wasmtime GitHub notifications bot (Feb 12 2024 at 23:11):

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

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 both res2_1 and res_2_2 have idx 0, but when res_1_1 is replaced with res_1_2 it is 1. So I guess the resource id is taken from resource that was used as parameter.


Last updated: Nov 22 2024 at 17:03 UTC