@@ -18,8 +18,8 @@ use itertools::Itertools;
1818use proc_macro2:: { Ident , TokenStream } ;
1919use quote:: { format_ident, quote} ;
2020
21- use crate :: emit:: { State , kebab_to_cons, kebab_to_var} ;
22- use crate :: etypes:: { self , Defined , Handleable , TypeBound , Tyvar , Value } ;
21+ use crate :: emit:: { ResolvedBoundVar , State , kebab_to_cons, kebab_to_var} ;
22+ use crate :: etypes:: { self , Defined , Handleable , Tyvar , Value } ;
2323use crate :: rtypes;
2424
2525/// Construct a string that can be used "on the wire" to identify a
@@ -151,25 +151,16 @@ pub fn emit_hl_unmarshal_toplevel_value(
151151 }
152152}
153153
154- /// Find the resource index that the given type variable refers to.
155- ///
156- /// Precondition: this type variable does refer to a resource type
157- fn resolve_tyvar_to_resource ( s : & mut State , v : u32 ) -> u32 {
158- match s. bound_vars [ v as usize ] . bound {
159- TypeBound :: SubResource => v,
160- TypeBound :: Eq ( Defined :: Handleable ( Handleable :: Var ( Tyvar :: Bound ( vv) ) ) ) => {
161- resolve_tyvar_to_resource ( s, v + vv + 1 )
162- }
163- _ => panic ! ( "impossible: resource var is not resource" ) ,
164- }
165- }
166154/// Find the resource index that the given Handleable refers to.
167155///
168156/// Precondition: this type variable does refer to a resource type
169157pub fn resolve_handleable_to_resource ( s : & mut State , ht : & Handleable ) -> u32 {
170158 match ht {
171159 Handleable :: Var ( Tyvar :: Bound ( vi) ) => {
172- resolve_tyvar_to_resource ( s, s. var_offset as u32 + * vi)
160+ let ResolvedBoundVar :: Resource { rtidx } = s. resolve_bound_var ( * vi) else {
161+ panic ! ( "impossible: resource var is not resource" ) ;
162+ } ;
163+ rtidx
173164 }
174165 _ => panic ! ( "impossible handleable in type" ) ,
175166 }
@@ -338,9 +329,29 @@ pub fn emit_hl_unmarshal_value(s: &mut State, id: Ident, vt: &Value) -> TokenStr
338329 log:: debug!( "resolved ht to r (2) {:?} {:?}" , ht, vi) ;
339330 if s. is_guest {
340331 let rid = format_ident ! ( "HostResource{}" , vi) ;
341- quote ! {
342- let i = u32 :: from_ne_bytes( #id[ 0 ..4 ] . try_into( ) . unwrap( ) ) ;
343- ( :: wasmtime:: component:: Resource :: <#rid>:: new_borrow( i) , 4 )
332+ if s. is_wasmtime_guest {
333+ quote ! {
334+ let i = u32 :: from_ne_bytes( #id[ 0 ..4 ] . try_into( ) . unwrap( ) ) ;
335+ ( :: wasmtime:: component:: Resource :: <#rid>:: new_borrow( i) , 4 )
336+ }
337+ } else {
338+ // TODO: When we add the Drop impl (#810), we need
339+ // to make sure it does not get called here
340+ //
341+ // If we tried to actually return a reference
342+ // here, rustc would get mad about the temporary
343+ // constructed here not living long enough, so
344+ // instead we return the temporary and construct
345+ // the reference elsewhere. It might be a bit more
346+ // principled to have a separate
347+ // HostResourceXXBorrow struct that implements
348+ // AsRef<HostResourceXX> or something in the
349+ // future...
350+ quote ! {
351+ let i = u32 :: from_ne_bytes( #id[ 0 ..4 ] . try_into( ) . unwrap( ) ) ;
352+
353+ ( #rid { rep: i } , 4 )
354+ }
344355 }
345356 } else {
346357 let rid = format_ident ! ( "resource{}" , vi) ;
@@ -358,7 +369,11 @@ pub fn emit_hl_unmarshal_value(s: &mut State, id: Ident, vt: &Value) -> TokenStr
358369 let Some ( Tyvar :: Bound ( n) ) = tv else {
359370 panic ! ( "impossible tyvar" )
360371 } ;
361- let ( n, Some ( Defined :: Value ( vt) ) ) = s. resolve_tv ( * n) else {
372+ let ResolvedBoundVar :: Definite {
373+ final_bound_var : n,
374+ ty : Defined :: Value ( vt) ,
375+ } = s. resolve_bound_var ( * n)
376+ else {
362377 panic ! ( "unresolvable tyvar (2)" ) ;
363378 } ;
364379 let vt = vt. clone ( ) ;
@@ -644,7 +659,9 @@ pub fn emit_hl_marshal_value(s: &mut State, id: Ident, vt: &Value) -> TokenStrea
644659 let rid = format_ident ! ( "resource{}" , vi) ;
645660 quote ! {
646661 let i = rts. #rid. len( ) ;
647- rts. #rid. push_back( :: hyperlight_common:: resource:: ResourceEntry :: lend( #id) ) ;
662+ let ( lrg, re) = :: hyperlight_common:: resource:: ResourceEntry :: lend( #id) ;
663+ to_cleanup. push( Box :: new( lrg) ) ;
664+ rts. #rid. push_back( re) ;
648665 alloc:: vec:: Vec :: from( u32 :: to_ne_bytes( i as u32 ) )
649666 }
650667 }
@@ -653,7 +670,11 @@ pub fn emit_hl_marshal_value(s: &mut State, id: Ident, vt: &Value) -> TokenStrea
653670 let Some ( Tyvar :: Bound ( n) ) = tv else {
654671 panic ! ( "impossible tyvar" )
655672 } ;
656- let ( n, Some ( Defined :: Value ( vt) ) ) = s. resolve_tv ( * n) else {
673+ let ResolvedBoundVar :: Definite {
674+ final_bound_var : n,
675+ ty : Defined :: Value ( vt) ,
676+ } = s. resolve_bound_var ( * n)
677+ else {
657678 panic ! ( "unresolvable tyvar (2)" ) ;
658679 } ;
659680 let vt = vt. clone ( ) ;
@@ -668,7 +689,20 @@ pub fn emit_hl_marshal_value(s: &mut State, id: Ident, vt: &Value) -> TokenStrea
668689/// [`crate::rtypes`] module) of the given value type.
669690pub fn emit_hl_unmarshal_param ( s : & mut State , id : Ident , pt : & Value ) -> TokenStream {
670691 let toks = emit_hl_unmarshal_value ( s, id, pt) ;
671- quote ! { { #toks } . 0 }
692+ // Slight hack to avoid rust complaints about deserialised
693+ // resource borrow lifetimes.
694+ fn is_borrow ( vt : & Value ) -> bool {
695+ match vt {
696+ Value :: Borrow ( _) => true ,
697+ Value :: Var ( _, vt) => is_borrow ( vt) ,
698+ _ => false ,
699+ }
700+ }
701+ if s. is_guest && !s. is_wasmtime_guest && is_borrow ( pt) {
702+ quote ! { & ( { #toks } . 0 ) }
703+ } else {
704+ quote ! { { #toks } . 0 }
705+ }
672706}
673707
674708/// Emit code to unmarshal the result of a function with result type
0 commit comments