4949 = libwasmtime_load_symbol ((cookie), "wasm_byte_vec_delete"); \
5050 void (*wasmtime_error_message) (const wasmtime_error_t *error, wasm_name_t *message) \
5151 = libwasmtime_load_symbol ((cookie), "wasmtime_error_message"); \
52+ bool (*wasmtime_error_exit_status) (const wasmtime_error_t *error, int *status) \
53+ = libwasmtime_load_symbol ((cookie), "wasmtime_error_exit_status"); \
5254 void (*wasmtime_error_delete) (wasmtime_error_t * error) \
5355 = libwasmtime_load_symbol ((cookie), "wasmtime_error_delete");
5456
@@ -171,10 +173,10 @@ libwasmtime_free_vm (void *cookie, struct libwasmtime_vm *vm)
171173 wasm_engine_delete (vm -> engine );
172174}
173175
174- static void
176+ static int
175177libwasmtime_run_module (void * cookie , struct libwasmtime_vm * vm , wasm_byte_vec_t * wasm );
176178
177- static void
179+ static int
178180libwasmtime_run_component (void * cookie , struct libwasmtime_vm * vm , wasm_byte_vec_t * wasm );
179181
180182static int
@@ -183,6 +185,7 @@ libwasmtime_exec (void *cookie, libcrun_container_t *container arg_unused,
183185{
184186 wasm_byte_vec_t error_message ;
185187 wasm_byte_vec_t wasm_bytes ;
188+ int status ;
186189
187190 WASMTIME_COMMON_SYMBOLS (cookie )
188191 wasmtime_error_t * (* wasmtime_wat2wasm ) (const char * wat , size_t wat_len , wasm_byte_vec_t * out )
@@ -231,14 +234,14 @@ libwasmtime_exec (void *cookie, libcrun_container_t *container arg_unused,
231234 libwasmtime_setup_vm (cookie , argv , & vm );
232235
233236 if (wasm_enc == WASM_ENC_MODULE )
234- libwasmtime_run_module (cookie , & vm , & wasm );
237+ status = libwasmtime_run_module (cookie , & vm , & wasm );
235238 else if (wasm_enc == WASM_ENC_COMPONENT )
236- libwasmtime_run_component (cookie , & vm , & wasm );
239+ status = libwasmtime_run_component (cookie , & vm , & wasm );
237240 else
238241 error (EXIT_FAILURE , 0 , "unsupported wasm encoding detected" );
239242
240243 libwasmtime_free_vm (cookie , & vm );
241- exit (EXIT_SUCCESS );
244+ exit (status );
242245}
243246
244247static void *
@@ -251,7 +254,7 @@ libwasmtime_load_symbol (void *cookie, char *const symbol)
251254 return sym ;
252255}
253256
254- static void
257+ static int
255258libwasmtime_run_module (void * cookie , struct libwasmtime_vm * vm , wasm_byte_vec_t * wasm )
256259{
257260 wasmtime_error_t * err ;
@@ -292,6 +295,10 @@ libwasmtime_run_module (void *cookie, struct libwasmtime_vm *vm, wasm_byte_vec_t
292295 size_t nresults ,
293296 wasm_trap_t * * trap )
294297 = libwasmtime_load_symbol (cookie , "wasmtime_func_call" );
298+ void (* wasm_trap_message ) (const wasm_trap_t * trap , wasm_message_t * message )
299+ = libwasmtime_load_symbol (cookie , "wasm_trap_message" );
300+ void (* wasm_trap_delete ) (wasm_trap_t * )
301+ = libwasmtime_load_symbol (cookie , "wasm_trap_delete" );
295302 void (* wasmtime_module_delete ) (wasmtime_module_t * m )
296303 = libwasmtime_load_symbol (cookie , "wasmtime_module_delete" );
297304
@@ -348,20 +355,31 @@ libwasmtime_run_module (void *cookie, struct libwasmtime_vm *vm, wasm_byte_vec_t
348355 error (EXIT_FAILURE , 0 , "failed to locate default export for module %.*s" , (int ) error_message .size , error_message .data );
349356 }
350357
358+ int status = EXIT_SUCCESS ;
351359 wasm_trap_t * trap = NULL ;
352360 err = wasmtime_func_call (vm -> context , & func , NULL , 0 , NULL , 0 , & trap );
353- if (err != NULL || trap != NULL )
361+ if (err != NULL && ! wasmtime_error_exit_status ( err , & status ) )
354362 {
363+ // The error does not describe an exit code thus we error out.
355364 wasmtime_error_message (err , & error_message );
356365 wasmtime_error_delete (err );
357366 error (EXIT_FAILURE , 0 , "error calling default export: %.*s" , (int ) error_message .size , error_message .data );
358367 }
368+ if (trap != NULL )
369+ {
370+ wasm_trap_message (trap , & error_message );
371+ wasm_trap_delete (trap );
372+ fprintf (stderr , "trap tiggered in module: %.*s" , (int ) error_message .size , error_message .data );
373+ status = EXIT_FAILURE ;
374+ }
359375
360376 // Clean everything
361377 wasmtime_module_delete (module );
378+
379+ return status ;
362380}
363381
364- static void
382+ static int
365383libwasmtime_run_component (void * cookie , struct libwasmtime_vm * vm , wasm_byte_vec_t * wasm )
366384{
367385 const char * const wasi_cli_run_interface = "wasi:cli/run@0.2.0" ;
@@ -408,6 +426,8 @@ libwasmtime_run_component (void *cookie, struct libwasmtime_vm *vm, wasm_byte_ve
408426 wasmtime_component_val_t * results ,
409427 size_t results_size )
410428 = libwasmtime_load_symbol (cookie , "wasmtime_component_func_call" );
429+ wasmtime_error_t * (* wasmtime_component_func_post_return ) (const wasmtime_component_func_t * func , wasmtime_context_t * context )
430+ = libwasmtime_load_symbol (cookie , "wasmtime_component_func_post_return" );
411431 void (* wasmtime_component_export_index_delete ) (wasmtime_component_export_index_t * export_index )
412432 = libwasmtime_load_symbol (cookie , "wasmtime_component_export_index_delete" );
413433 void (* wasmtime_component_delete ) (wasmtime_component_t * c )
@@ -479,20 +499,46 @@ libwasmtime_run_component (void *cookie, struct libwasmtime_vm *vm, wasm_byte_ve
479499 error (EXIT_FAILURE , 0 , "failed to retrieve run function" );
480500
481501 // Call the func
502+ int status = EXIT_SUCCESS ;
503+ bool func_call_caused_error = false;
482504 wasmtime_component_val_t result = {};
483505 err = wasmtime_component_func_call (& run_func , vm -> context , NULL , 0 , & result , 1 );
484506 if (err != NULL )
485507 {
486- wasmtime_error_message (err , & error_message );
487- wasmtime_error_delete (err );
488- error (EXIT_FAILURE , 0 , "error calling run function: %.*s" , (int ) error_message .size , error_message .data );
508+ if (wasmtime_error_exit_status (err , & status ))
509+ {
510+ wasmtime_error_delete (err );
511+ func_call_caused_error = true;
512+ }
513+ else
514+ {
515+ // The error does not describe an exit code thus we error out.
516+ wasmtime_error_message (err , & error_message );
517+ wasmtime_error_delete (err );
518+ error (EXIT_FAILURE , 0 , "error calling run function: %.*s" , (int ) error_message .size , error_message .data );
519+ }
520+ }
521+
522+ // Call its post-return __only__ if `wasmtime_component_func_call` was successful.
523+ // Even an error describing an exit code which may be 0 counts as not successful.
524+ if (! func_call_caused_error )
525+ {
526+ err = wasmtime_component_func_post_return (& run_func , vm -> context );
527+ if (err != NULL )
528+ {
529+ wasmtime_error_message (err , & error_message );
530+ wasmtime_error_delete (err );
531+ error (EXIT_FAILURE , 0 , "error calling run function post-return: %.*s" , (int ) error_message .size , error_message .data );
532+ }
489533 }
490534
491535 // Clean everything
492536 wasmtime_component_export_index_delete (run_func_idx );
493537 wasmtime_component_export_index_delete (run_interface_idx );
494538 wasmtime_component_linker_delete (linker );
495539 wasmtime_component_delete (component );
540+
541+ return status ;
496542}
497543
498544static int
0 commit comments