@@ -20,6 +20,12 @@ pub struct ProfileOpts {
2020#[ folder = "providers/" ]
2121struct StandardProviders ;
2222
23+ pub fn uses_msgpack_provider ( module : & Module ) -> bool {
24+ module. imports ( ) . map ( |i| i. module ( ) ) . any ( |module| {
25+ module. starts_with ( "shopify_function_v" ) || module == "shopify_functions_javy_v2"
26+ } )
27+ }
28+
2329fn import_modules < T > (
2430 module : & Module ,
2531 engine : & Engine ,
@@ -28,8 +34,10 @@ fn import_modules<T>(
2834) {
2935 let imported_modules: HashSet < String > =
3036 module. imports ( ) . map ( |i| i. module ( ) . to_string ( ) ) . collect ( ) ;
37+
3138 imported_modules. iter ( ) . for_each ( |module_name| {
32- let imported_module_bytes = StandardProviders :: get ( & format ! ( "{module_name}.wasm" ) ) ;
39+ let provider_path = format ! ( "{module_name}.wasm" ) ;
40+ let imported_module_bytes = StandardProviders :: get ( & provider_path) ;
3341
3442 if let Some ( bytes) = imported_module_bytes {
3543 let imported_module = Module :: from_binary ( engine, & bytes. data )
@@ -38,20 +46,22 @@ fn import_modules<T>(
3846 let imported_module_instance = linker
3947 . instantiate ( & mut store, & imported_module)
4048 . expect ( "Failed to instantiate imported instance" ) ;
49+
4150 linker
4251 . instance ( & mut store, module_name, imported_module_instance)
4352 . expect ( "Failed to import module" ) ;
4453 }
4554 } ) ;
4655}
4756
48- #[ derive( Default ) ]
4957pub struct FunctionRunParams < ' a > {
5058 pub function_path : PathBuf ,
5159 pub input : BytesContainer ,
5260 pub export : & ' a str ,
5361 pub profile_opts : Option < & ' a ProfileOpts > ,
5462 pub scale_factor : f64 ,
63+ pub module : Module ,
64+ pub engine : Engine ,
5565}
5666
5767const STARTING_FUEL : u64 = u64:: MAX ;
@@ -114,18 +124,10 @@ pub fn run(params: FunctionRunParams) -> Result<FunctionRunResult> {
114124 export,
115125 profile_opts,
116126 scale_factor,
127+ engine,
128+ module,
117129 } = params;
118130
119- let engine = Engine :: new (
120- Config :: new ( )
121- . wasm_multi_memory ( true )
122- . wasm_threads ( false )
123- . consume_fuel ( true )
124- . epoch_interruption ( true ) ,
125- ) ?;
126- let module = Module :: from_file ( & engine, & function_path)
127- . map_err ( |e| anyhow ! ( "Couldn't load the Function {:?}: {}" , & function_path, e) ) ?;
128-
129131 let input_stream = MemoryInputPipe :: new ( input. raw . clone ( ) ) ;
130132 let output_stream = MemoryOutputPipe :: new ( usize:: MAX ) ;
131133 let error_stream = MemoryOutputPipe :: new ( usize:: MAX ) ;
@@ -201,11 +203,15 @@ pub fn run(params: FunctionRunParams) -> Result<FunctionRunResult> {
201203
202204 logs. extend_from_slice ( error_logs. as_bytes ( ) ) ;
203205
206+ let output_codec = input. codec ;
204207 let raw_output = output_stream
205208 . try_into_inner ( )
206209 . expect ( "Output stream reference still exists" ) ;
207-
208- let output = BytesContainer :: new ( BytesContainerType :: Output , input. codec , raw_output. to_vec ( ) ) ?;
210+ let output = BytesContainer :: new (
211+ BytesContainerType :: Output ,
212+ output_codec,
213+ raw_output. to_vec ( ) ,
214+ ) ?;
209215
210216 let name = function_path. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
211217 let size = function_path. metadata ( ) ?. len ( ) / 1024 ;
@@ -226,6 +232,21 @@ pub fn run(params: FunctionRunParams) -> Result<FunctionRunResult> {
226232 Ok ( function_run_result)
227233}
228234
235+ /// Creates a new Engine with our standard configuration.
236+ /// We use a dedicated function instead of making this the default configuration because:
237+ /// 1. It's more explicit about what configuration we're using
238+ /// 2. It keeps the door open for different configurations in the future without breaking changes
239+ /// 3. It makes it easier to find all places where we create an Engine
240+ pub fn new_engine ( ) -> Result < Engine > {
241+ Engine :: new (
242+ Config :: new ( )
243+ . wasm_multi_memory ( true )
244+ . wasm_threads ( false )
245+ . consume_fuel ( true )
246+ . epoch_interruption ( true ) ,
247+ )
248+ }
249+
229250#[ cfg( test) ]
230251mod tests {
231252 use colored:: Colorize ;
@@ -244,6 +265,9 @@ mod tests {
244265
245266 #[ test]
246267 fn test_js_function ( ) -> Result < ( ) > {
268+ let engine = new_engine ( ) ?;
269+ let module =
270+ Module :: from_file ( & engine, Path :: new ( "tests/fixtures/build/js_function.wasm" ) ) ?;
247271 let input = json_input ( include_bytes ! (
248272 "../tests/fixtures/input/js_function_input.json"
249273 ) ) ?;
@@ -252,7 +276,10 @@ mod tests {
252276 function_path : Path :: new ( "tests/fixtures/build/js_function.wasm" ) . to_path_buf ( ) ,
253277 input,
254278 export : DEFAULT_EXPORT ,
255- ..Default :: default ( )
279+ module,
280+ engine,
281+ scale_factor : 1.0 ,
282+ profile_opts : None ,
256283 } ) ?;
257284
258285 assert_eq ! ( function_run_result. memory_usage, 1280 ) ;
@@ -262,14 +289,22 @@ mod tests {
262289
263290 #[ test]
264291 fn test_js_v2_function ( ) -> Result < ( ) > {
292+ let engine = new_engine ( ) ?;
293+ let module = Module :: from_file (
294+ & engine,
295+ Path :: new ( "tests/fixtures/build/js_function_v2.wasm" ) ,
296+ ) ?;
265297 let input = json_input ( include_bytes ! (
266298 "../tests/fixtures/input/js_function_input.json"
267299 ) ) ?;
268300 let function_run_result = run ( FunctionRunParams {
269301 function_path : Path :: new ( "tests/fixtures/build/js_function_v2.wasm" ) . to_path_buf ( ) ,
270302 input,
271303 export : DEFAULT_EXPORT ,
272- ..Default :: default ( )
304+ module,
305+ engine,
306+ scale_factor : 1.0 ,
307+ profile_opts : None ,
273308 } ) ?;
274309
275310 assert_eq ! ( function_run_result. memory_usage, 1344 ) ;
@@ -278,6 +313,11 @@ mod tests {
278313
279314 #[ test]
280315 fn test_js_v3_function ( ) -> Result < ( ) > {
316+ let engine = new_engine ( ) ?;
317+ let module = Module :: from_file (
318+ & engine,
319+ Path :: new ( "tests/fixtures/build/js_function_v3.wasm" ) ,
320+ ) ?;
281321 let input = json_input ( include_bytes ! (
282322 "../tests/fixtures/input/js_function_input.json"
283323 ) ) ?;
@@ -286,7 +326,10 @@ mod tests {
286326 function_path : Path :: new ( "tests/fixtures/build/js_function_v3.wasm" ) . to_path_buf ( ) ,
287327 input,
288328 export : DEFAULT_EXPORT ,
289- ..Default :: default ( )
329+ module,
330+ engine,
331+ scale_factor : 1.0 ,
332+ profile_opts : None ,
290333 } ) ?;
291334
292335 assert_eq ! ( function_run_result. memory_usage, 1344 ) ;
@@ -295,6 +338,11 @@ mod tests {
295338
296339 #[ test]
297340 fn test_js_functions_javy_v1 ( ) -> Result < ( ) > {
341+ let engine = new_engine ( ) ?;
342+ let module = Module :: from_file (
343+ & engine,
344+ Path :: new ( "tests/fixtures/build/js_functions_javy_v1.wasm" ) ,
345+ ) ?;
298346 let input = json_input ( include_bytes ! (
299347 "../tests/fixtures/input/js_function_input.json"
300348 ) ) ?;
@@ -304,7 +352,10 @@ mod tests {
304352 . to_path_buf ( ) ,
305353 input,
306354 export : DEFAULT_EXPORT ,
307- ..Default :: default ( )
355+ module,
356+ engine,
357+ scale_factor : 1.0 ,
358+ profile_opts : None ,
308359 } ) ?;
309360
310361 assert_eq ! ( function_run_result. memory_usage, 1344 ) ;
@@ -313,11 +364,16 @@ mod tests {
313364
314365 #[ test]
315366 fn test_exit_code_zero ( ) -> Result < ( ) > {
367+ let engine = new_engine ( ) ?;
368+ let module = Module :: from_file ( & engine, Path :: new ( "tests/fixtures/build/exit_code.wasm" ) ) ?;
316369 let function_run_result = run ( FunctionRunParams {
317370 function_path : Path :: new ( "tests/fixtures/build/exit_code.wasm" ) . to_path_buf ( ) ,
318371 input : json_input ( & serde_json:: to_vec ( & json ! ( { "code" : 0 } ) ) ?) ?,
319372 export : DEFAULT_EXPORT ,
320- ..Default :: default ( )
373+ module,
374+ engine,
375+ scale_factor : 1.0 ,
376+ profile_opts : None ,
321377 } ) ?;
322378
323379 assert_eq ! ( function_run_result. logs, "" ) ;
@@ -326,11 +382,16 @@ mod tests {
326382
327383 #[ test]
328384 fn test_exit_code_one ( ) -> Result < ( ) > {
385+ let engine = new_engine ( ) ?;
386+ let module = Module :: from_file ( & engine, Path :: new ( "tests/fixtures/build/exit_code.wasm" ) ) ?;
329387 let function_run_result = run ( FunctionRunParams {
330388 function_path : Path :: new ( "tests/fixtures/build/exit_code.wasm" ) . to_path_buf ( ) ,
331389 input : json_input ( & serde_json:: to_vec ( & json ! ( { "code" : 1 } ) ) ?) ?,
332390 export : DEFAULT_EXPORT ,
333- ..Default :: default ( )
391+ module,
392+ engine,
393+ scale_factor : 1.0 ,
394+ profile_opts : None ,
334395 } ) ?;
335396
336397 assert_eq ! ( function_run_result. logs, "module exited with code: 1" ) ;
@@ -339,11 +400,19 @@ mod tests {
339400
340401 #[ test]
341402 fn test_linear_memory_usage_in_kb ( ) -> Result < ( ) > {
403+ let engine = new_engine ( ) ?;
404+ let module = Module :: from_file (
405+ & engine,
406+ Path :: new ( "tests/fixtures/build/linear_memory.wasm" ) ,
407+ ) ?;
342408 let function_run_result = run ( FunctionRunParams {
343409 function_path : Path :: new ( "tests/fixtures/build/linear_memory.wasm" ) . to_path_buf ( ) ,
344410 input : json_input ( & serde_json:: to_vec ( & json ! ( { } ) ) ?) ?,
345411 export : DEFAULT_EXPORT ,
346- ..Default :: default ( )
412+ module,
413+ engine,
414+ scale_factor : 1.0 ,
415+ profile_opts : None ,
347416 } ) ?;
348417
349418 assert_eq ! ( function_run_result. memory_usage, 12800 ) ; // 200 * 64KiB pages
@@ -352,12 +421,20 @@ mod tests {
352421
353422 #[ test]
354423 fn test_logs_truncation ( ) -> Result < ( ) > {
424+ let engine = new_engine ( ) ?;
425+ let module = Module :: from_file (
426+ & engine,
427+ Path :: new ( "tests/fixtures/build/log_truncation_function.wasm" ) ,
428+ ) ?;
355429 let function_run_result = run ( FunctionRunParams {
356430 input : json_input ( "{}" . as_bytes ( ) ) ?,
357431 function_path : Path :: new ( "tests/fixtures/build/log_truncation_function.wasm" )
358432 . to_path_buf ( ) ,
359433 export : DEFAULT_EXPORT ,
360- ..Default :: default ( )
434+ module,
435+ engine,
436+ scale_factor : 1.0 ,
437+ profile_opts : None ,
361438 } ) ?;
362439
363440 assert ! (
@@ -374,12 +451,16 @@ mod tests {
374451 #[ test]
375452 fn test_file_size_in_kb ( ) -> Result < ( ) > {
376453 let file_path = Path :: new ( "tests/fixtures/build/exit_code.wasm" ) ;
377-
454+ let engine = new_engine ( ) ?;
455+ let module = Module :: from_file ( & engine, file_path) ?;
378456 let function_run_result = run ( FunctionRunParams {
379457 function_path : file_path. to_path_buf ( ) ,
380458 input : json_input ( & serde_json:: to_vec ( & json ! ( { "code" : 0 } ) ) ?) ?,
381459 export : DEFAULT_EXPORT ,
382- ..Default :: default ( )
460+ module,
461+ engine,
462+ scale_factor : 1.0 ,
463+ profile_opts : None ,
383464 } ) ?;
384465
385466 assert_eq ! (
@@ -388,4 +469,33 @@ mod tests {
388469 ) ;
389470 Ok ( ( ) )
390471 }
472+
473+ #[ test]
474+ fn test_wasm_api_function ( ) -> Result < ( ) > {
475+ let engine = new_engine ( ) ?;
476+ let module = Module :: from_file (
477+ & engine,
478+ Path :: new ( "tests/fixtures/build/echo.trampolined.wasm" ) ,
479+ ) ?;
480+ let expected_input_value = json ! ( { "foo" : "echo" , "bar" : "test" } ) ;
481+ let input = serde_json:: to_vec ( & expected_input_value) . unwrap ( ) ;
482+ let input_bytes = BytesContainer :: new ( BytesContainerType :: Input , Codec :: Json , input) ;
483+ let function_run_result = run ( FunctionRunParams {
484+ function_path : Path :: new ( "tests/fixtures/build/echo.trampolined.wasm" ) . to_path_buf ( ) ,
485+ input : input_bytes. unwrap ( ) ,
486+ export : DEFAULT_EXPORT ,
487+ module,
488+ engine,
489+ scale_factor : 1.0 ,
490+ profile_opts : None ,
491+ } ) ;
492+
493+ assert ! ( function_run_result. is_ok( ) ) ;
494+ let result = function_run_result. unwrap ( ) ;
495+ assert_eq ! (
496+ serde_json:: from_slice:: <serde_json:: Value >( & result. input. raw) . unwrap( ) ,
497+ expected_input_value
498+ ) ;
499+ Ok ( ( ) )
500+ }
391501}
0 commit comments