@@ -196,9 +196,10 @@ impl<'i> InterfaceGenerator<'i> {
196196 . map ( |( resource, ( trait_name, ..) ) | ( resource. unwrap ( ) , trait_name. as_str ( ) ) ) ,
197197 )
198198 }
199+ let rt = self . r#gen . runtime_path ( ) . to_string ( ) ;
199200
200201 for ( resource, ( trait_name, methods) ) in traits. iter ( ) {
201- uwriteln ! ( self . src, "pub trait {trait_name}: 'static {{" ) ;
202+ uwriteln ! ( self . src, "pub trait {trait_name}: {rt}::Resource {{" ) ;
202203 let resource = resource. unwrap ( ) ;
203204 let resource_name = self . resolve . types [ resource] . name . as_ref ( ) . unwrap ( ) ;
204205 let ( _, interface_name) = interface. unwrap ( ) ;
@@ -239,6 +240,55 @@ fn _resource_rep(handle: u32) -> *mut u8
239240
240241 "#
241242 ) ;
243+ let box_path = self . path_to_box ( ) ;
244+ uwriteln ! (
245+ self . src,
246+ r#"
247+ /// Place this resource's representation into a location with a stable pointer,
248+ /// returning a pointer to that location.
249+ ///
250+ /// This method is used to place `val` on the heap, for example, or possibly in
251+ /// an arena. The returned pointer must remain valid for the lifetime of this
252+ /// resource. The default implementation of this metho will place `val` onto the
253+ /// heap with `Box`. The returned pointer will be deallocated by the sibling
254+ /// `resource_from_raw_` function.
255+ ///
256+ /// # Safety
257+ ///
258+ /// Note that this method is not `unsafe` to call, but it is `unsafe` to
259+ /// define. When overriding this method you must additionally override the
260+ /// `resource_from_raw_` to insert an appropriate deallocation for the returned
261+ /// pointer. In the future this might become a default associated trait bound,
262+ /// but that's not stable in Rust right now.
263+ #[doc(hidden)]
264+ unsafe fn resource_into_raw_(val: Self::Rep) -> *mut Self::Rep
265+ {{
266+ {box_path}::into_raw({box_path}::new(val))
267+ }}
268+
269+ /// Consumes and deallocates a pointer previously returned by
270+ /// `resource_into_raw_`.
271+ ///
272+ /// This function is used to deallocate resources and allocations associated
273+ /// with the allocation routine when creating a resource. The default
274+ /// implementation of this method will read `handle`'s value and deallocate it
275+ /// as a `Box`.
276+ ///
277+ /// Note that when overriding this method you'll almost surely want to override
278+ /// `resource_into_raw_` as well.
279+ ///
280+ /// # Safety
281+ ///
282+ /// This method is only safe to call with pointers previously created by
283+ /// `resource_into_raw_`. For more information see `Box::from_raw` for examples.
284+ #[doc(hidden)]
285+ unsafe fn resource_from_raw_(handle: *mut Self::Rep) -> Self::Rep
286+ {{
287+ *unsafe {{ {box_path}::from_raw(handle) }}
288+ }}
289+
290+ "#
291+ ) ;
242292 for method in methods {
243293 self . src . push_str ( method) ;
244294 }
@@ -2716,7 +2766,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
27162766 Identifier :: World ( _) => unimplemented ! ( "resource exports from worlds" ) ,
27172767 Identifier :: StreamOrFuturePayload => unreachable ! ( ) ,
27182768 } ;
2719- let box_path = self . path_to_box ( ) ;
2769+ let rt = self . r#gen . runtime_path ( ) ;
27202770 uwriteln ! (
27212771 self . src,
27222772 r#"
@@ -2726,8 +2776,6 @@ pub struct {camel} {{
27262776 handle: {resource}<{camel}>,
27272777}}
27282778
2729- type _{camel}Rep<T> = Option<T>;
2730-
27312779impl {camel} {{
27322780 /// Creates a new resource from the specified representation.
27332781 ///
@@ -2736,31 +2784,30 @@ impl {camel} {{
27362784 /// create a handle. The owned handle is then returned as `{camel}`.
27372785 pub fn new<T: Guest{camel}>(val: T) -> Self {{
27382786 Self::type_guard::<T>();
2739- let val: _{camel}Rep<T> = Some(val);
2740- let ptr: *mut _{camel}Rep<T> =
2741- {box_path}::into_raw({box_path}::new(val));
2787+ let rep = <T::Rep as {rt}::ResourceRep<T>>::rep_new(val);
27422788 unsafe {{
2789+ let ptr = T::resource_into_raw_(rep);
27432790 Self::from_handle(T::_resource_new(ptr.cast()))
27442791 }}
27452792 }}
27462793
27472794 /// Gets access to the underlying `T` which represents this resource.
27482795 pub fn get<T: Guest{camel}>(&self) -> &T {{
2749- let ptr = unsafe {{ &* self.as_ptr::<T>() }} ;
2750- ptr.as_ref().unwrap()
2796+ let ptr = self.as_ptr::<T>();
2797+ unsafe {{ <T::Rep as {rt}::ResourceRep<T>>::rep_as_ref(ptr) }}
27512798 }}
27522799
27532800 /// Gets mutable access to the underlying `T` which represents this
27542801 /// resource.
27552802 pub fn get_mut<T: Guest{camel}>(&mut self) -> &mut T {{
2756- let ptr = unsafe {{ &mut * self.as_ptr::<T>() }} ;
2757- ptr.as_mut().unwrap()
2803+ let ptr = self.as_ptr::<T>();
2804+ unsafe {{ <T::Rep as {rt}::ResourceRep<T>>::rep_as_mut(ptr) }}
27582805 }}
27592806
27602807 /// Consumes this resource and returns the underlying `T`.
27612808 pub fn into_inner<T: Guest{camel}>(self) -> T {{
2762- let ptr = unsafe {{ &mut * self.as_ptr::<T>() }} ;
2763- ptr.take().unwrap()
2809+ let ptr = self.as_ptr::<T>();
2810+ unsafe {{ <T::Rep as {rt}::ResourceRep<T>>::rep_take(ptr) }}
27642811 }}
27652812
27662813 #[doc(hidden)]
@@ -2783,7 +2830,7 @@ impl {camel} {{
27832830 // It's theoretically possible to implement the `Guest{camel}` trait twice
27842831 // so guard against using it with two different types here.
27852832 #[doc(hidden)]
2786- fn type_guard<T: 'static >() {{
2833+ fn type_guard<T: {rt}::Resource >() {{
27872834 use core::any::TypeId;
27882835 static mut LAST_TYPE: Option<TypeId> = None;
27892836 unsafe {{
@@ -2797,12 +2844,14 @@ impl {camel} {{
27972844 }}
27982845
27992846 #[doc(hidden)]
2800- pub unsafe fn dtor<T: 'static >(handle: *mut u8) {{
2847+ pub unsafe fn dtor<T: Guest{camel} >(handle: *mut u8) {{
28012848 Self::type_guard::<T>();
2802- let _ = unsafe {{ {box_path}::from_raw(handle as *mut _{camel}Rep<T>) }};
2849+ unsafe {{
2850+ let _rep = T::resource_from_raw_(handle.cast());
2851+ }}
28032852 }}
28042853
2805- fn as_ptr<T: Guest{camel}>(&self) -> *mut _{camel}Rep<T> {{
2854+ fn as_ptr<T: Guest{camel}>(&self) -> *mut T::Rep {{
28062855 {camel}::type_guard::<T>();
28072856 T::_resource_rep(self.handle()).cast()
28082857 }}
@@ -2813,29 +2862,29 @@ impl {camel} {{
28132862#[derive(Debug)]
28142863#[repr(transparent)]
28152864pub struct {camel}Borrow<'a> {{
2816- rep: *mut u8,
2865+ rep: *const u8,
28172866 _marker: core::marker::PhantomData<&'a {camel}>,
28182867}}
28192868
28202869impl<'a> {camel}Borrow<'a>{{
28212870 #[doc(hidden)]
2822- pub unsafe fn lift(rep: usize ) -> Self {{
2871+ pub unsafe fn lift(rep: *const u8 ) -> Self {{
28232872 Self {{
2824- rep: rep as *mut u8 ,
2873+ rep,
28252874 _marker: core::marker::PhantomData,
28262875 }}
28272876 }}
28282877
28292878 /// Gets access to the underlying `T` in this resource.
28302879 pub fn get<T: Guest{camel}>(&self) -> &'a T {{
2831- let ptr = unsafe {{ &mut * self.as_ptr::<T>() }} ;
2832- ptr.as_ref().unwrap()
2880+ let ptr = self.as_ptr::<T>();
2881+ unsafe {{ <T::Rep as {rt}::ResourceRep<T>>::rep_as_ref(ptr) }}
28332882 }}
28342883
28352884 // NB: mutable access is not allowed due to the component model allowing
28362885 // multiple borrows of the same resource.
28372886
2838- fn as_ptr<T: 'static >(&self) -> *mut _{camel}Rep<T> {{
2887+ fn as_ptr<T: Guest{camel} >(&self) -> *const T::Rep {{
28392888 {camel}::type_guard::<T>();
28402889 self.rep.cast()
28412890 }}
0 commit comments