jrandolf edited PR #14871.
jrandolf has marked PR #14871 as ready for review.
jrandolf requested cfallin for a review on PR #14871.
jrandolf removed the review request for wasmtime-core-reviewers from PR #14871.
jrandolf requested wasmtime-core-reviewers for a review on PR #14871.
jrandolf edited PR #14871:
Using a resource handle with a different static type than the one it was created with trapped, even when both static types are bound to the same resource type at runtime. The canonical ABI compares the runtime types (
h.rt is not t.rt), so this makes Wasmtime compare them too when the static types differ. Equal static types work as before.For example, this fixes passing a handle between two imports of the same interface whose resources the host defines with the same
ResourceType, and between two imports of a subcomponent that were given the same resource. Handles of different runtime types still trap, with a new message.Closes #14861
<details>
<summary>LLM summary of the changes</summary>The problem
Each entry in a component instance's handle table records the static resource type (
TypeResourceTableIndex) it was created with, andTypedResource::reptrapped whenever a handle was used with any other static type. The canonical ABI instead checksh.rt is not t.rt, comparing runtime resource types. So a handle has to be accepted wherever the static types differ but are bound to the same runtime type. Two cases hit this:
- A component imports the same interface under two names (for example with
implements), and the host defines the resource of both imports with the sameResourceType. A handle obtained through one import and passed to the other trapped, with a message calling the host resource "guest-defined".- A component passes one resource to a subcomponent for two of its imports. Wasmtime gives each import its own static type even though both refer to the same resource, so a handle obtained as one and used as the other trapped.
The check (
vm/component/resources.rs,vm/component/handle_table.rs)
TypedResource::reptakes asame_typepredicate. A component handle is accepted if its static type equals the one it's used with (unchanged fast path) or ifsame_typesays the two are the same runtime type.ResourceTables::same_typemaps both static types to theirResourceIndexand compares the runtimeResourceTypes of those in the instance. A resource that has no runtime type yet is distinct from every other resource.HandleTable::resource_rep,resource_lendandremove_resourcetake the predicate and pass it through, which coversresource.rep,resource.drop, and liftingownandborrowhandles.- The handle table is still chosen from the type the handle is used with. Every handle in a table was created with a type belonging to that table's instance, so this doesn't change.
Plumbing (
vm/component.rs,func/options.rs,store.rs)
ResourceTables::guestnow also carries the instance's runtime resource types. A newComponentInstance::instance_states_and_resource_typesreturns them along with the instance states and types, and the two places that buildResourceTablesuse it.instance_statesis now a wrapper around it.Error message
ResourceTypeMismatchused to say which kind of resource was expected and found, which was wrong for host resources stored in a component's table. It now says "handle index N used with the wrong type, found a handle to a different resource type". The upstream component-model tests check the old wording, socrates/wastmaps it to the new one, as it already does for a few other spec messages.resources.wastand themismatch_intrinsicstest are updated to the new wording.Destructors
The canonical ABI ties a destructor to the runtime resource type, but in Wasmtime each
LinkerInstance::resourcedefinition has its own destructor. When a handle created through one import is dropped through another, the destructor of the import it's dropped through runs.LinkerInstance::resourcedocuments this, and thenamed_importsdocs ofbindgen!say that resources are shared between imports and that the id passed to a method, includingdrop, identifies the import being called.Behavior change
This only makes programs work that trapped before. Handles of different runtime types, such as guest resources of different instances or different host types, still trap.
Tests
tests/all/component_model/resources.rs: the newhandle_between_imports_of_same_host_typeimports one interface asprimaryandsecondary, creates a handle throughprimary, and passes it to and drops it throughsecondary. With the same host type for both, it succeeds andsecondary's destructor runs once. With different host types, it traps with the new message.- The subcomponent case isn't covered by a test.
</details>
jrandolf commented on PR #14871:
We don't have a concrete need for this, so I'm closing it.
:cross_mark: jrandolf closed without merge PR #14871.
Last updated: Oct 31 2026 at 23:03 UTC