@@ -18,8 +18,8 @@ use itertools::Itertools;
18
18
use proc_macro2:: { Ident , TokenStream } ;
19
19
use quote:: { format_ident, quote} ;
20
20
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 } ;
23
23
use crate :: rtypes;
24
24
25
25
/// Construct a string that can be used "on the wire" to identify a
@@ -151,25 +151,16 @@ pub fn emit_hl_unmarshal_toplevel_value(
151
151
}
152
152
}
153
153
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
- }
166
154
/// Find the resource index that the given Handleable refers to.
167
155
///
168
156
/// Precondition: this type variable does refer to a resource type
169
157
pub fn resolve_handleable_to_resource ( s : & mut State , ht : & Handleable ) -> u32 {
170
158
match ht {
171
159
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
173
164
}
174
165
_ => panic ! ( "impossible handleable in type" ) ,
175
166
}
@@ -338,9 +329,29 @@ pub fn emit_hl_unmarshal_value(s: &mut State, id: Ident, vt: &Value) -> TokenStr
338
329
log:: debug!( "resolved ht to r (2) {:?} {:?}" , ht, vi) ;
339
330
if s. is_guest {
340
331
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
+ }
344
355
}
345
356
} else {
346
357
let rid = format_ident ! ( "resource{}" , vi) ;
@@ -358,7 +369,11 @@ pub fn emit_hl_unmarshal_value(s: &mut State, id: Ident, vt: &Value) -> TokenStr
358
369
let Some ( Tyvar :: Bound ( n) ) = tv else {
359
370
panic ! ( "impossible tyvar" )
360
371
} ;
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 {
362
377
panic ! ( "unresolvable tyvar (2)" ) ;
363
378
} ;
364
379
let vt = vt. clone ( ) ;
@@ -644,7 +659,9 @@ pub fn emit_hl_marshal_value(s: &mut State, id: Ident, vt: &Value) -> TokenStrea
644
659
let rid = format_ident ! ( "resource{}" , vi) ;
645
660
quote ! {
646
661
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) ;
648
665
alloc:: vec:: Vec :: from( u32 :: to_ne_bytes( i as u32 ) )
649
666
}
650
667
}
@@ -653,7 +670,11 @@ pub fn emit_hl_marshal_value(s: &mut State, id: Ident, vt: &Value) -> TokenStrea
653
670
let Some ( Tyvar :: Bound ( n) ) = tv else {
654
671
panic ! ( "impossible tyvar" )
655
672
} ;
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 {
657
678
panic ! ( "unresolvable tyvar (2)" ) ;
658
679
} ;
659
680
let vt = vt. clone ( ) ;
@@ -668,7 +689,20 @@ pub fn emit_hl_marshal_value(s: &mut State, id: Ident, vt: &Value) -> TokenStrea
668
689
/// [`crate::rtypes`] module) of the given value type.
669
690
pub fn emit_hl_unmarshal_param ( s : & mut State , id : Ident , pt : & Value ) -> TokenStream {
670
691
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
+ }
672
706
}
673
707
674
708
/// Emit code to unmarshal the result of a function with result type
0 commit comments