Feature/adding missing instance methods#623
Conversation
The `handle` param doc only said "the path of the function to retrieve",
leaving the accepted name formats to guesswork. Spell them out: plain
kebab-case export names, fully-qualified interface names including
namespace, package and version (e.g. "ns:pkg/iface@0.1.0"), and
canonical-ABI mangled resource function names ("[constructor]r",
"[method]r.f", "[static]r.f"), plus an example combining interface and
resource-constructor lookup.
saulecabrera
left a comment
There was a problem hiding this comment.
Looks reasonable to me. Left some comments inline.
| /// Passing an +own<T>+ {Resource} into a function parameter transfers | ||
| /// ownership of the underlying resource to the callee. Using the same | ||
| /// {Resource} object afterwards (including calling {#resource_drop} on it) | ||
| /// may then raise, since the store-side handle it pointed to no longer | ||
| /// belongs to the host. |
There was a problem hiding this comment.
| /// Passing an +own<T>+ {Resource} into a function parameter transfers | |
| /// ownership of the underlying resource to the callee. Using the same | |
| /// {Resource} object afterwards (including calling {#resource_drop} on it) | |
| /// may then raise, since the store-side handle it pointed to no longer | |
| /// belongs to the host. | |
| /// Passing an +own<T>+ {Resource} into a function transfers ownership of the | |
| /// underlying resource to the callee. Once the call returns, this {Resource} | |
| /// object is a dangling handle; it still exists, but the store-side resource | |
| /// it referred to now belongs to the guest. Calling {#resource_drop} on it, or | |
| /// passing it into another call, may then raise. (+borrow<T>+ parameters do not | |
| /// transfer ownership, the same {Resource} stays valid and reusable.) | |
There was a problem hiding this comment.
Can we consider tightening the documentation here? Specifically to be more clear around the when is the resource no longer valid: I find the usage of "afterwards" to be ambiguous in this context.
There was a problem hiding this comment.
Also, from what I can see there is no test covering this case? Can you add a test that covers it?
| Some(current_store) | ||
| if resource.store().as_value().as_raw() | ||
| == current_store.as_value().as_raw() => | ||
| { | ||
| Ok(Val::Resource(resource.get()?)) | ||
| } | ||
| Some(_) => { | ||
| err!("Resource belongs to a different Store than the one being called into") | ||
| } |
There was a problem hiding this comment.
Can we fold in the error case (when the stores differ) in the first branch?. This is minor, but I think it shows the error case clearer.
|
LGTM. We can land this after solving the conflicts. |
I think the conflict is stale, I rebased on main to be able to fast-forward for a clean tree and it merges without conflict locally. The main side of the diff references context_mut()? (the pre-Magnus-migration API), which no longer exists on main - it was removed in #531. I've never have this case so I don't know what to do, is it safe to accept my changes even if the conflict is stale or is it undefined behaviour ? |
Instance previously only exposed #get_func, making it impossible to fully drive a component that exports a WIT `resource` (e.g. a constructor plus instance methods) from Ruby: there was no way to look up the resource's exported type, and Val::Resource/Type::Own/Type::Borrow conversions were hard `not_implemented!` stubs. - Instance#get_resource wraps wasmtime's method of the same name; the shared lookup helper now internally prefers get_export_index over get_export since the ComponentItem the latter returns is never used. - New Wasmtime::Component::Resource wraps ResourceAny + its owning Store, requiring an explicit #resource_drop (wasmtime requires every ResourceAny, even borrows, to be explicitly dropped; there's no safe GC finalizer hook for re-entering a Store during collection). - New Wasmtime::Component::ResourceType wraps the matching wasmtime type; it is inert Copy data with no Store dependency, so unlike Resource it needs no GC mark. - convert.rs now lifts/lowers resource values for the Func::invoke path (calling exported functions), and guards against passing a Resource obtained from one Store into a call on a different Store, which would otherwise silently index into the wrong store's resource table. - Host-defined import functions (Linker#root.func_new) still don't support resources in either direction; that path never had a Ruby-visible Store handle to thread through, and stays out of scope here. Address review feedback on Component::Resource - Clarify that an own<T> Resource becomes a dangling handle after a call transfers ownership. - Refactor the Store mismatch branch in rb_to_component_val to be clearer. - Add a test covering the dangling-handle behavior after an own<T> transfer.
522ffd9 to
15441be
Compare
This PR aims to enable users of the gem to use resources and to improve the get_func docs to talk about the canonical way to point to a function [ "packagename/interface@x.x.x" , "[constructor]my-resource" ].
One caveat is that the GC won't free a resource in order to avoid double freeing or freeing before intended so we have to free by hand using resource drop.
Example :
i made this after #619
_store became store because the store parameter went from unused to used: resource lift/lower in convert.rs now needs it to wrap returned Val::Resource values with their owning store and to reject resources passed into calls on a different store.