@@ -17,7 +17,7 @@ limitations under the License.
17
17
use alloc:: string:: ToString ;
18
18
use alloc:: vec:: Vec ;
19
19
use alloc:: { format, vec} ;
20
- use core:: ops:: Deref ;
20
+ use core:: ops:: { Deref , DerefMut } ;
21
21
22
22
use hyperlight_common:: flatbuffer_wrappers:: function_call:: FunctionCall ;
23
23
use hyperlight_common:: flatbuffer_wrappers:: function_types:: {
@@ -32,59 +32,95 @@ use hyperlight_guest_bin::host_comm::print_output_with_host_print;
32
32
use spin:: Mutex ;
33
33
use wasmtime:: { Config , Engine , Linker , Module , Store , Val } ;
34
34
35
+ use crate :: hostfuncs:: take_hostfunc_allocated_addrs;
35
36
use crate :: { hostfuncs, marshal, platform, wasip1} ;
36
37
38
+ // Set by transition to WasmSandbox (by init_wasm_runtime)
37
39
static CUR_ENGINE : Mutex < Option < Engine > > = Mutex :: new ( None ) ;
38
40
static CUR_LINKER : Mutex < Option < Linker < ( ) > > > = Mutex :: new ( None ) ;
41
+ // Set by transition to LoadedWasmSandbox (by load_wasm_module/load_wasm_module_phys)
39
42
static 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 ) ;
40
45
41
46
#[ 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 (
45
50
ErrorCode :: GuestError ,
46
- "Wasm runtime is not initialized " . to_string ( ) ,
51
+ "No wasm store available " . to_string ( ) ,
47
52
) ) ?;
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 (
50
55
ErrorCode :: GuestError ,
51
- "impossible: wasm runtime has no valid linker " . to_string ( ) ,
56
+ "No wasm instance available " . to_string ( ) ,
52
57
) ) ?;
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
+
60
59
let func = instance
61
- . get_func ( & mut store, & function_call. function_name )
60
+ . get_func ( & mut * store, & function_call. function_name )
62
61
. ok_or ( HyperlightGuestError :: new (
63
62
ErrorCode :: GuestError ,
64
63
"Function not found" . to_string ( ) ,
65
64
) ) ?;
65
+
66
66
let mut w_params = vec ! [ ] ;
67
+ let mut allocated_addrs = vec ! [ ] ;
67
68
for f_param in ( function_call. parameters )
68
69
. as_ref ( )
69
70
. unwrap_or ( & vec ! [ ] )
70
71
. iter ( )
71
72
{
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,
74
75
|ctx, name| instance. get_export ( ctx, name) ,
75
76
f_param,
77
+ & mut allocated_addrs,
76
78
) ?) ;
77
79
}
78
80
let is_void = ReturnType :: Void == function_call. expected_return_type ;
79
81
let n_results = if is_void { 0 } else { 1 } ;
80
82
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,
84
86
|ctx, name| instance. get_export ( ctx, name) ,
85
87
function_call. expected_return_type ,
86
88
& 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,
87
96
)
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
88
124
}
89
125
90
126
fn init_wasm_runtime ( ) -> Result < Vec < u8 > > {
@@ -124,8 +160,19 @@ fn load_wasm_module(function_call: &FunctionCall) -> Result<Vec<u8>> {
124
160
& function_call. parameters . as_ref ( ) . unwrap ( ) [ 1 ] ,
125
161
& * CUR_ENGINE . lock ( ) ,
126
162
) {
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
+
127
169
let module = unsafe { Module :: deserialize ( engine, wasm_bytes) ? } ;
170
+ let mut store = Store :: new ( engine, ( ) ) ;
171
+ let instance = linker. instantiate ( & mut store, & module) ?;
172
+
128
173
* CUR_MODULE . lock ( ) = Some ( module) ;
174
+ * CUR_STORE . lock ( ) = Some ( store) ;
175
+ * CUR_INSTANCE . lock ( ) = Some ( instance) ;
129
176
Ok ( get_flatbuffer_result :: < i32 > ( 0 ) )
130
177
} else {
131
178
Err ( HyperlightGuestError :: new (
@@ -141,8 +188,19 @@ fn load_wasm_module_phys(function_call: &FunctionCall) -> Result<Vec<u8>> {
141
188
& function_call. parameters . as_ref ( ) . unwrap ( ) [ 1 ] ,
142
189
& * CUR_ENGINE . lock ( ) ,
143
190
) {
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
+
144
197
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
+
145
201
* CUR_MODULE . lock ( ) = Some ( module) ;
202
+ * CUR_STORE . lock ( ) = Some ( store) ;
203
+ * CUR_INSTANCE . lock ( ) = Some ( instance) ;
146
204
Ok ( get_flatbuffer_result :: < ( ) > ( ( ) ) )
147
205
} else {
148
206
Err ( HyperlightGuestError :: new (
0 commit comments