Skip to content

Commit

Permalink
Host resources wit-bindgen code generation (bytecodealliance#6886)
Browse files Browse the repository at this point in the history
* added trap to resource dtor

* basic resources

* fixed signature and trait bounds

* fixed static function

* fixed trait signature

* basic resources

* added result to resource drop

* reverted formatting

* added doc comment to resource `dtor`

* fixed merge issue

* fixed another merge issue

* added resource import codegen test

* Revert changes to `Cargo.lock`

* Update `Cargo.lock` with the wit-bindgen update

* Add `cargo vet` entries for new crates

* Restore old-style of printing types in bindgen

Avoid collecting resources-as-we-go in favor of doing that more
declaratively elsewhere. Additionally handle imported-vs-exported
resource via the order that interfaces are visited.

* Update the shape of resource traits:

* Use `&mut self` instead of `StoreContextMut`
* Make resource traits as supertraits of the `Host` trait generated for
  each resource.
* More uniformly handle types/returns with resource methods.
* Fix derivations of `Clone` and `Copy` for where handles are contained.

* Fix generation of handle typedefs

* Support resources-in-worlds

* Remove now-duplicate function

This is now the same as the preexisting `generate_function_trait_sig`

* Fix classifying handles as imported or exported

This determination happens by looking up the origin definition of a
resource, not the leaf possibly-aliased type.

* Fix chains-of-use of resources

Resources don't have their representation asserted since the bare type
itself doesn't implement `ComponentType`, but otherwise generate type
aliases the same way as other type aliases.

* Revert `Cargo.lock` changes

No need to update `wit-bindgen` to 0.10.0 just yet, that'll happen in a
future update if necessary.

* Add basic runtime tests for resources

* fixed merge issue

---------

Co-authored-by: Alex Crichton <alex@alexcrichton.com>
  • Loading branch information
2 people authored and eduardomourar committed Sep 6, 2023
1 parent 8b9e476 commit 9cf0ae4
Show file tree
Hide file tree
Showing 8 changed files with 702 additions and 68 deletions.
87 changes: 87 additions & 0 deletions crates/component-macro/tests/codegen/resources-import.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package foo:foo

interface resources {
resource bar {
constructor()
static-a: static func() -> u32
method-a: func() -> u32
}

bar-own-arg: func(x: own<bar>)
bar-borrow-arg: func(x: borrow<bar>)
bar-result: func() -> own<bar>

tuple-own-arg: func(x: tuple<own<bar>, u32>)
tuple-borrow-arg: func(x: tuple<own<bar>, u32>)
tuple-result: func() -> tuple<own<bar>, u32>

option-own-arg: func(x: option<own<bar>>)
option-borrow-arg: func(x: option<borrow<bar>>)
option-result: func() -> option<own<bar>>

result-own-arg: func(x: result<own<bar>>)
result-borrow-arg: func(x: result<borrow<bar>>)
result-result: func() -> result<own<bar>>

list-own-arg: func(x: list<own<bar>>)
list-borrow-arg: func(x: list<borrow<bar>>)
list-result: func() -> list<own<bar>>

record nested-own {
nested-bar: own<bar>
}

record nested-borrow {
nested-bar: borrow<bar>
}

record-own-arg: func(x: nested-own)
record-borrow-arg: func(x: nested-borrow)
record-result: func() -> nested-own

type some-handle = borrow<bar>
func-with-handle-typedef: func(x: some-handle)
}

world the-world {
import resources

resource world-resource {
constructor()

foo: func()
static-foo: static func()
}

import some-world-func: func() -> world-resource
export some-world-func2: func() -> world-resource

export uses-resource-transitively

import long-use-chain4
}

interface transitive-interface-with-resource {
resource foo
}

interface uses-resource-transitively {
use transitive-interface-with-resource.{foo}

handle: func(x: foo)
}

interface long-use-chain4 {
use long-use-chain3.{a}

foo: func() -> a
}
interface long-use-chain3 {
use long-use-chain2.{a}
}
interface long-use-chain2 {
use long-use-chain1.{a}
}
interface long-use-chain1 {
resource a
}
12 changes: 8 additions & 4 deletions crates/wasmtime/src/component/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,17 +396,21 @@ impl<T> LinkerInstance<'_, T> {
/// along with the representation of the resource that was just destroyed.
///
/// [`Resource<U>`]: crate::component::Resource
///
/// # Errors
///
/// The provided `dtor` closure returns an error if something goes wrong
/// when a guest calls the `dtor` to drop a `Resource<T>` such as
/// a runtime trap or a runtime limit being exceeded.
pub fn resource<U: 'static>(
&mut self,
name: &str,
dtor: impl Fn(StoreContextMut<'_, T>, u32) + Send + Sync + 'static,
dtor: impl Fn(StoreContextMut<'_, T>, u32) -> Result<()> + Send + Sync + 'static,
) -> Result<()> {
let name = self.strings.intern(name);
let dtor = Arc::new(crate::func::HostFunc::wrap(
&self.engine,
move |mut cx: crate::Caller<'_, T>, param: u32| {
dtor(cx.as_context_mut(), param);
},
move |mut cx: crate::Caller<'_, T>, param: u32| dtor(cx.as_context_mut(), param),
));
self.insert(name, Definition::Resource(ResourceType::host::<U>(), dtor))
}
Expand Down
4 changes: 3 additions & 1 deletion crates/wast/src/spectest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,11 @@ pub fn link_component_spectest<T>(linker: &mut component::Linker<T>) -> Result<(
move |_, rep| {
state.drops.fetch_add(1, SeqCst);
state.last_drop.store(rep, SeqCst);

Ok(())
}
})?;
i.resource::<Resource2>("resource2", |_, _| {})?;
i.resource::<Resource2>("resource2", |_, _| Ok(()))?;
// Currently the embedder API requires redefining the resource destructor
// here despite this being the same type as before, and fixing that is left
// for a future refactoring.
Expand Down
Loading

0 comments on commit 9cf0ae4

Please sign in to comment.