@@ -3,7 +3,6 @@ use alloc::vec::Vec;
33use const_interpreter_loop:: run_const_span;
44use function_ref:: FunctionRef ;
55use interpreter_loop:: run;
6- use locals:: Locals ;
76use value_stack:: Stack ;
87
98use crate :: execution:: assert_validated:: UnwrapValidatedExt ;
@@ -119,84 +118,18 @@ where
119118 Ok ( FunctionRef { func_addr } )
120119 }
121120
121+ /// Invokes a function with the given parameters of type `Param`, and return types of type `Returns`.
122122 pub fn invoke < Param : InteropValueList , Returns : InteropValueList > (
123123 & mut self ,
124124 function_ref : & FunctionRef ,
125125 params : Param ,
126126 // store: &mut Store,
127127 ) -> Result < Returns , RuntimeError > {
128128 // TODO fix error
129- let store = self . store . as_ref ( ) . ok_or ( RuntimeError :: ModuleNotFound ) ?;
129+ let store = self . store . as_mut ( ) . ok_or ( RuntimeError :: ModuleNotFound ) ?;
130130
131131 let FunctionRef { func_addr } = * function_ref;
132- let func_inst = store
133- . functions
134- . get ( func_addr)
135- . ok_or ( RuntimeError :: FunctionNotFound ) ?;
136-
137- let module_addr = func_inst. module_addr ;
138-
139- // TODO handle this bad linear search that is unavoidable
140- let ( func_idx, _) = store. modules [ module_addr]
141- . func_addrs
142- . iter ( )
143- . enumerate ( )
144- . find ( |& ( _idx, addr) | * addr == func_addr)
145- . ok_or ( RuntimeError :: FunctionNotFound ) ?;
146-
147- let func_ty = func_inst. ty ( ) ;
148-
149- // Check correct function parameters and return types
150- if func_ty. params . valtypes != Param :: TYS {
151- panic ! ( "Invalid `Param` generics" ) ;
152- }
153- if func_ty. returns . valtypes != Returns :: TYS {
154- panic ! (
155- "Invalid `Returns` generics, expected {:?}" ,
156- func_ty. returns. valtypes
157- ) ;
158- }
159-
160- // Prepare a new stack with the locals for the entry function
161- let mut stack = Stack :: new ( ) ;
162- let locals = Locals :: new (
163- params. into_values ( ) . into_iter ( ) ,
164- func_inst. locals . iter ( ) . cloned ( ) ,
165- ) ;
166-
167- // setting `usize::MAX` as return address for the outermost function ensures that we
168- // observably fail upon errornoeusly continuing execution after that function returns.
169- stack. push_stackframe (
170- module_addr,
171- func_idx,
172- & func_ty,
173- locals,
174- usize:: MAX ,
175- usize:: MAX ,
176- ) ?;
177-
178- let mut current_module_idx = module_addr;
179-
180- // Run the interpreter
181- run (
182- & mut current_module_idx,
183- & mut stack,
184- EmptyHookSet ,
185- self . store . as_mut ( ) . unwrap_validated ( ) ,
186- ) ?;
187-
188- // Pop return values from stack
189- let return_values = Returns :: TYS
190- . iter ( )
191- . rev ( )
192- . map ( |ty| stack. pop_value ( * ty) )
193- . collect :: < Vec < Value > > ( ) ;
194-
195- // Values are reversed because they were popped from stack one-by-one. Now reverse them back
196- let reversed_values = return_values. into_iter ( ) . rev ( ) ;
197- let ret: Returns = Returns :: from_values ( reversed_values) ;
198- debug ! ( "Successfully invoked function" ) ;
199- Ok ( ret)
132+ store. invoke ( func_addr, params)
200133 }
201134
202135 /// Invokes a function with the given parameters, and return types which are not known at compile time.
@@ -208,142 +141,22 @@ where
208141 // store: &mut Store,
209142 ) -> Result < Vec < Value > , RuntimeError > {
210143 // TODO fix error
211- let store = self . store . as_ref ( ) . ok_or ( RuntimeError :: ModuleNotFound ) ?;
144+ let store = self . store . as_mut ( ) . ok_or ( RuntimeError :: ModuleNotFound ) ?;
212145
213146 let FunctionRef { func_addr } = * function_ref;
214- let func_inst = store
215- . functions
216- . get ( func_addr)
217- . ok_or ( RuntimeError :: FunctionNotFound ) ?;
218-
219- let module_addr = func_inst. module_addr ;
220-
221- // TODO handle this bad linear search that is unavoidable
222- let ( func_idx, _) = store. modules [ module_addr]
223- . func_addrs
224- . iter ( )
225- . enumerate ( )
226- . find ( |& ( _idx, addr) | * addr == func_addr)
227- . ok_or ( RuntimeError :: FunctionNotFound ) ?;
228-
229- let func_ty = func_inst. ty ( ) ;
230-
231- // Verify that the given parameters match the function parameters
232- let param_types = params. iter ( ) . map ( |v| v. to_ty ( ) ) . collect :: < Vec < _ > > ( ) ;
233-
234- if func_ty. params . valtypes != param_types {
235- panic ! ( "Invalid parameters for function" ) ;
236- }
237-
238- // Verify that the given return types match the function return types
239- if func_ty. returns . valtypes != ret_types {
240- panic ! ( "Invalid return types for function" ) ;
241- }
242-
243- // Prepare a new stack with the locals for the entry function
244- let mut stack = Stack :: new ( ) ;
245- let locals = Locals :: new ( params. into_iter ( ) , func_inst. locals . iter ( ) . cloned ( ) ) ;
246- stack. push_stackframe ( module_addr, func_idx, & func_ty, locals, 0 , 0 ) ?;
247-
248- let mut currrent_module_idx = module_addr;
249-
250- // Run the interpreter
251- run (
252- & mut currrent_module_idx,
253- & mut stack,
254- EmptyHookSet ,
255- self . store . as_mut ( ) . unwrap_validated ( ) ,
256- ) ?;
257-
258- // Pop return values from stack
259- let return_values = func_ty
260- . returns
261- . valtypes
262- . iter ( )
263- . rev ( )
264- . map ( |ty| stack. pop_value ( * ty) )
265- . collect :: < Vec < Value > > ( ) ;
266-
267- // Values are reversed because they were popped from stack one-by-one. Now reverse them back
268- let reversed_values = return_values. into_iter ( ) . rev ( ) ;
269- let ret = reversed_values. collect ( ) ;
270- debug ! ( "Successfully invoked function" ) ;
271- Ok ( ret)
147+ store. invoke_dynamic ( func_addr, params, ret_types)
272148 }
273149
274- /// Get the indicies of a module and function by their names.
275- ///
276- /// # Arguments
277- /// - `module_name`: The module in which to find the function.
278- /// - `function_name`: The name of the function to find inside the module. The function must be a local function and
279- /// not an import.
280- ///
281- /// # Returns
282- /// - `Ok((module_idx, func_idx))`, where `module_idx` is the internal index of the module inside the
283- /// [RuntimeInstance], and `func_idx` is the internal index of the function inside the module.
284- /// - `Err(RuntimeError::ModuleNotFound)`, if the module is not found.
285- /// - `Err(RuntimeError::FunctionNotFound`, if the function is not found within the module.
286- ///
150+ /// Invokes a function with the given parameters. The return types depend on the function signature.
287151 pub fn invoke_dynamic_unchecked_return_ty (
288152 & mut self ,
289153 function_ref : & FunctionRef ,
290154 params : Vec < Value > ,
291155 ) -> Result < Vec < Value > , RuntimeError > {
292156 // TODO fix error
293- let store = self . store . as_ref ( ) . ok_or ( RuntimeError :: ModuleNotFound ) ?;
157+ let store = self . store . as_mut ( ) . ok_or ( RuntimeError :: ModuleNotFound ) ?;
294158
295159 let FunctionRef { func_addr } = * function_ref;
296- let func_inst = store
297- . functions
298- . get ( func_addr)
299- . ok_or ( RuntimeError :: FunctionNotFound ) ?;
300-
301- let module_addr = func_inst. module_addr ;
302-
303- // TODO handle this bad linear search that is unavoidable
304- let ( func_idx, _) = store. modules [ module_addr]
305- . func_addrs
306- . iter ( )
307- . enumerate ( )
308- . find ( |& ( _idx, addr) | * addr == func_addr)
309- . ok_or ( RuntimeError :: FunctionNotFound ) ?;
310- let func_ty = func_inst. ty ( ) ;
311-
312- // Verify that the given parameters match the function parameters
313- let param_types = params. iter ( ) . map ( |v| v. to_ty ( ) ) . collect :: < Vec < _ > > ( ) ;
314-
315- if func_ty. params . valtypes != param_types {
316- panic ! ( "Invalid parameters for function" ) ;
317- }
318-
319- // Prepare a new stack with the locals for the entry function
320- let mut stack = Stack :: new ( ) ;
321- let locals = Locals :: new ( params. into_iter ( ) , func_inst. locals . iter ( ) . cloned ( ) ) ;
322- stack. push_stackframe ( module_addr, func_idx, & func_ty, locals, 0 , 0 ) ?;
323-
324- let mut currrent_module_idx = module_addr;
325-
326- // Run the interpreter
327- run (
328- & mut currrent_module_idx,
329- & mut stack,
330- EmptyHookSet ,
331- self . store . as_mut ( ) . unwrap_validated ( ) ,
332- ) ?;
333-
334- // Pop return values from stack
335- let return_values = func_ty
336- . returns
337- . valtypes
338- . iter ( )
339- . rev ( )
340- . map ( |ty| stack. pop_value ( * ty) )
341- . collect :: < Vec < Value > > ( ) ;
342-
343- // Values are reversed because they were popped from stack one-by-one. Now reverse them back
344- let reversed_values = return_values. into_iter ( ) . rev ( ) ;
345- let ret = reversed_values. collect ( ) ;
346- debug ! ( "Successfully invoked function" ) ;
347- Ok ( ret)
160+ store. invoke_dynamic_unchecked_return_ty ( func_addr, params)
348161 }
349162}
0 commit comments