@@ -17,7 +17,7 @@ limitations under the License.
1717use alloc:: string:: ToString ;
1818use alloc:: vec:: Vec ;
1919use alloc:: { format, vec} ;
20- use core:: ops:: Deref ;
20+ use core:: ops:: { Deref , DerefMut } ;
2121
2222use hyperlight_common:: flatbuffer_wrappers:: function_call:: FunctionCall ;
2323use hyperlight_common:: flatbuffer_wrappers:: function_types:: {
@@ -32,59 +32,95 @@ use hyperlight_guest_bin::host_comm::print_output_with_host_print;
3232use spin:: Mutex ;
3333use wasmtime:: { Config , Engine , Linker , Module , Store , Val } ;
3434
35+ use crate :: hostfuncs:: take_hostfunc_allocated_addrs;
3536use crate :: { hostfuncs, marshal, platform, wasip1} ;
3637
38+ // Set by transition to WasmSandbox (by init_wasm_runtime)
3739static CUR_ENGINE : Mutex < Option < Engine > > = Mutex :: new ( None ) ;
3840static CUR_LINKER : Mutex < Option < Linker < ( ) > > > = Mutex :: new ( None ) ;
41+ // Set by transition to LoadedWasmSandbox (by load_wasm_module/load_wasm_module_phys)
3942static CUR_MODULE : Mutex < Option < Module > > = Mutex :: new ( None ) ;
43+ static CUR_STORE : Mutex < Option < Store < ( ) > > > = Mutex :: new ( None ) ;
44+ static CUR_INSTANCE : Mutex < Option < wasmtime:: Instance > > = Mutex :: new ( None ) ;
4045
4146#[ no_mangle]
42- pub fn guest_dispatch_function ( function_call : & FunctionCall ) -> Result < Vec < u8 > > {
43- let engine = CUR_ENGINE . lock ( ) ;
44- let engine = engine . deref ( ) . as_ref ( ) . ok_or ( HyperlightGuestError :: new (
47+ pub fn guest_dispatch_function ( function_call : FunctionCall ) -> Result < Vec < u8 > > {
48+ let mut store = CUR_STORE . lock ( ) ;
49+ let store = store . deref_mut ( ) . as_mut ( ) . ok_or ( HyperlightGuestError :: new (
4550 ErrorCode :: GuestError ,
46- "Wasm runtime is not initialized " . to_string ( ) ,
51+ "No wasm store available " . to_string ( ) ,
4752 ) ) ?;
48- let linker = CUR_LINKER . lock ( ) ;
49- let linker = linker . deref ( ) . as_ref ( ) . ok_or ( HyperlightGuestError :: new (
53+ let instance = CUR_INSTANCE . lock ( ) ;
54+ let instance = instance . deref ( ) . as_ref ( ) . ok_or ( HyperlightGuestError :: new (
5055 ErrorCode :: GuestError ,
51- "impossible: wasm runtime has no valid linker " . to_string ( ) ,
56+ "No wasm instance available " . to_string ( ) ,
5257 ) ) ?;
53- let module = CUR_MODULE . lock ( ) ;
54- let module = module. deref ( ) . as_ref ( ) . ok_or ( HyperlightGuestError :: new (
55- ErrorCode :: GuestError ,
56- "No wasm module loaded" . to_string ( ) ,
57- ) ) ?;
58- let mut store = Store :: new ( engine, ( ) ) ;
59- let instance = linker. instantiate ( & mut store, module) ?;
58+
6059 let func = instance
61- . get_func ( & mut store, & function_call. function_name )
60+ . get_func ( & mut * store, & function_call. function_name )
6261 . ok_or ( HyperlightGuestError :: new (
6362 ErrorCode :: GuestError ,
6463 "Function not found" . to_string ( ) ,
6564 ) ) ?;
65+
6666 let mut w_params = vec ! [ ] ;
67+ let mut allocated_addrs = vec ! [ ] ;
6768 for f_param in ( function_call. parameters )
6869 . as_ref ( )
6970 . unwrap_or ( & vec ! [ ] )
7071 . iter ( )
7172 {
72- w_params. push ( marshal:: hl_param_to_val (
73- & mut store,
73+ w_params. push ( marshal:: hl_param_to_val_with_tracking (
74+ & mut * store,
7475 |ctx, name| instance. get_export ( ctx, name) ,
7576 f_param,
77+ & mut allocated_addrs,
7678 ) ?) ;
7779 }
7880 let is_void = ReturnType :: Void == function_call. expected_return_type ;
7981 let n_results = if is_void { 0 } else { 1 } ;
8082 let mut results = vec ! [ Val :: I32 ( 0 ) ; n_results] ;
81- func. call ( & mut store, & w_params, & mut results) ?;
82- marshal:: val_to_hl_result (
83- & mut store,
83+ func. call ( & mut * store, & w_params, & mut results) ?;
84+ let result = marshal:: val_to_hl_result (
85+ & mut * store,
8486 |ctx, name| instance. get_export ( ctx, name) ,
8587 function_call. expected_return_type ,
8688 & results,
89+ ) ;
90+
91+ // Free memory allocated during marshalling of hyperlight parameters into wasm parameters
92+ marshal:: free_allocated_addrs (
93+ & mut * store,
94+ |ctx, name| instance. get_export ( ctx, name) ,
95+ & allocated_addrs,
8796 )
97+ . map_err ( |e| {
98+ HyperlightGuestError :: new (
99+ ErrorCode :: GuestError ,
100+ format ! ( "Failed to free memory allocated for params: {:?}" , e) ,
101+ )
102+ } ) ?;
103+
104+ // Free memory allocated by marshalling host function return values into wasm values
105+ let hostfunc_addrs = take_hostfunc_allocated_addrs ( ) ;
106+ if !hostfunc_addrs. is_empty ( ) {
107+ marshal:: free_allocated_addrs (
108+ & mut * store,
109+ |ctx, name| instance. get_export ( ctx, name) ,
110+ & hostfunc_addrs,
111+ )
112+ . map_err ( |e| {
113+ HyperlightGuestError :: new (
114+ ErrorCode :: GuestError ,
115+ format ! (
116+ "Failed to free memory allocated for host function returns: {:?}" ,
117+ e
118+ ) ,
119+ )
120+ } ) ?;
121+ }
122+
123+ result
88124}
89125
90126fn init_wasm_runtime ( ) -> Result < Vec < u8 > > {
@@ -124,8 +160,19 @@ fn load_wasm_module(function_call: &FunctionCall) -> Result<Vec<u8>> {
124160 & function_call. parameters . as_ref ( ) . unwrap ( ) [ 1 ] ,
125161 & * CUR_ENGINE . lock ( ) ,
126162 ) {
163+ let linker = CUR_LINKER . lock ( ) ;
164+ let linker = linker. deref ( ) . as_ref ( ) . ok_or ( HyperlightGuestError :: new (
165+ ErrorCode :: GuestError ,
166+ "impossible: wasm runtime has no valid linker" . to_string ( ) ,
167+ ) ) ?;
168+
127169 let module = unsafe { Module :: deserialize ( engine, wasm_bytes) ? } ;
170+ let mut store = Store :: new ( engine, ( ) ) ;
171+ let instance = linker. instantiate ( & mut store, & module) ?;
172+
128173 * CUR_MODULE . lock ( ) = Some ( module) ;
174+ * CUR_STORE . lock ( ) = Some ( store) ;
175+ * CUR_INSTANCE . lock ( ) = Some ( instance) ;
129176 Ok ( get_flatbuffer_result :: < i32 > ( 0 ) )
130177 } else {
131178 Err ( HyperlightGuestError :: new (
@@ -141,8 +188,19 @@ fn load_wasm_module_phys(function_call: &FunctionCall) -> Result<Vec<u8>> {
141188 & function_call. parameters . as_ref ( ) . unwrap ( ) [ 1 ] ,
142189 & * CUR_ENGINE . lock ( ) ,
143190 ) {
191+ let linker = CUR_LINKER . lock ( ) ;
192+ let linker = linker. deref ( ) . as_ref ( ) . ok_or ( HyperlightGuestError :: new (
193+ ErrorCode :: GuestError ,
194+ "impossible: wasm runtime has no valid linker" . to_string ( ) ,
195+ ) ) ?;
196+
144197 let module = unsafe { Module :: deserialize_raw ( engine, platform:: map_buffer ( * phys, * len) ) ? } ;
198+ let mut store = Store :: new ( engine, ( ) ) ;
199+ let instance = linker. instantiate ( & mut store, & module) ?;
200+
145201 * CUR_MODULE . lock ( ) = Some ( module) ;
202+ * CUR_STORE . lock ( ) = Some ( store) ;
203+ * CUR_INSTANCE . lock ( ) = Some ( instance) ;
146204 Ok ( get_flatbuffer_result :: < ( ) > ( ( ) ) )
147205 } else {
148206 Err ( HyperlightGuestError :: new (
0 commit comments