15
15
* You should have received a copy of the GNU Lesser General Public License
16
16
* along with crun. If not, see <http://www.gnu.org/licenses/>.
17
17
*/
18
+ #include <wasmtime/store.h>
18
19
#define _GNU_SOURCE
19
20
20
21
#include <config.h>
@@ -151,7 +152,6 @@ libwasmtime_run_module (void *cookie, char *const argv[], wasm_engine_t *engine,
151
152
// Load needed functions
152
153
void (* wasm_engine_delete ) (wasm_engine_t * );
153
154
void (* wasm_byte_vec_delete ) (wasm_byte_vec_t * );
154
- void (* wasm_byte_vec_new_uninitialized ) (wasm_byte_vec_t * , size_t );
155
155
wasi_config_t * (* wasi_config_new ) (const char * );
156
156
wasmtime_store_t * (* wasmtime_store_new ) (wasm_engine_t * engine , void * data , void (* finalizer ) (void * ));
157
157
wasmtime_context_t * (* wasmtime_store_context ) (wasmtime_store_t * store );
@@ -197,7 +197,6 @@ libwasmtime_run_module (void *cookie, char *const argv[], wasm_engine_t *engine,
197
197
198
198
wasm_engine_delete = dlsym (cookie , "wasm_engine_delete" );
199
199
wasm_byte_vec_delete = dlsym (cookie , "wasm_byte_vec_delete" );
200
- wasm_byte_vec_new_uninitialized = dlsym (cookie , "wasm_byte_vec_new_uninitialized" );
201
200
wasi_config_new = dlsym (cookie , "wasi_config_new" );
202
201
wasi_config_set_argv = dlsym (cookie , "wasi_config_set_argv" );
203
202
wasmtime_store_new = dlsym (cookie , "wasmtime_store_new" );
@@ -221,7 +220,7 @@ libwasmtime_run_module (void *cookie, char *const argv[], wasm_engine_t *engine,
221
220
wasi_config_preopen_dir = dlsym (cookie , "wasi_config_preopen_dir" );
222
221
223
222
if (wasm_engine_delete == NULL || wasm_byte_vec_delete == NULL
224
- || wasm_byte_vec_new_uninitialized == NULL || wasi_config_new == NULL || wasmtime_store_new == NULL
223
+ || wasi_config_new == NULL || wasmtime_store_new == NULL
225
224
|| wasmtime_store_context == NULL || wasmtime_linker_new == NULL || wasmtime_linker_define_wasi == NULL
226
225
|| wasmtime_module_new == NULL || wasi_config_inherit_argv == NULL || wasi_config_inherit_stdout == NULL
227
226
|| wasi_config_inherit_stdin == NULL || wasi_config_inherit_stderr == NULL
@@ -316,7 +315,173 @@ libwasmtime_run_module (void *cookie, char *const argv[], wasm_engine_t *engine,
316
315
static void
317
316
libwasmtime_run_component (void * cookie , char * const argv [], wasm_engine_t * engine , wasm_byte_vec_t * wasm )
318
317
{
319
- error (EXIT_FAILURE , 0 , "running components is not yet implemented!" );
318
+ const char * wasi_cli_run_interface = "wasi:cli/[email protected] " ;
319
+ const char * wasi_cli_run_interface_run = "run" ;
320
+ wasm_byte_vec_t error_message ;
321
+
322
+ // Load needed functions
323
+ void (* wasm_engine_delete ) (wasm_engine_t * );
324
+ void (* wasm_byte_vec_delete ) (wasm_byte_vec_t * );
325
+ wasmtime_store_t * (* wasmtime_store_new ) (wasm_engine_t * engine , void * data , void (* finalizer ) (void * ));
326
+ void (* wasmtime_store_delete ) (wasmtime_store_t * store );
327
+ wasmtime_context_t * (* wasmtime_store_context ) (wasmtime_store_t * store );
328
+ wasmtime_error_t * (* wasmtime_component_new ) (
329
+ const wasm_engine_t * engine ,
330
+ const uint8_t * buf ,
331
+ size_t len ,
332
+ wasmtime_component_t * * component_out );
333
+ wasmtime_wasip2_config_t * (* wasmtime_wasip2_config_new ) (void );
334
+ void (* wasmtime_wasip2_config_inherit_stdin ) (wasmtime_wasip2_config_t * config );
335
+ void (* wasmtime_wasip2_config_inherit_stdout ) (wasmtime_wasip2_config_t * config );
336
+ void (* wasmtime_wasip2_config_inherit_stderr ) (wasmtime_wasip2_config_t * config );
337
+ void (* wasmtime_context_set_wasip2 ) (wasmtime_context_t * context , wasmtime_wasip2_config_t * config );
338
+ wasmtime_component_linker_t * (* wasmtime_component_linker_new ) (wasm_engine_t * engine );
339
+ wasmtime_error_t * (* wasmtime_component_linker_add_wasip2 ) (wasmtime_component_linker_t * linker );
340
+ wasmtime_error_t * (* wasmtime_component_linker_instantiate ) (
341
+ const wasmtime_component_linker_t * linker ,
342
+ wasmtime_context_t * context ,
343
+ const wasmtime_component_t * component ,
344
+ wasmtime_component_instance_t * instance_out );
345
+ wasmtime_component_export_index_t * (* wasmtime_component_get_export_index ) (
346
+ wasmtime_component_t * component ,
347
+ wasmtime_component_export_index_t * index ,
348
+ const char * name ,
349
+ size_t name_len );
350
+ wasmtime_component_export_index_t * (* wasmtime_component_instance_get_export_index ) (
351
+ const wasmtime_component_instance_t * instance ,
352
+ wasmtime_context_t * context ,
353
+ const wasmtime_component_export_index_t * instance_export_index ,
354
+ const char * name ,
355
+ size_t name_len );
356
+ bool (* wasmtime_component_instance_get_func ) (
357
+ const wasmtime_component_instance_t * instance ,
358
+ wasmtime_context_t * context ,
359
+ const wasmtime_component_export_index_t * export_index ,
360
+ wasmtime_component_func_t * func_out );
361
+ wasmtime_error_t * (* wasmtime_component_func_call ) (
362
+ const wasmtime_component_func_t * func ,
363
+ wasmtime_context_t * context ,
364
+ const wasmtime_component_val_t * args ,
365
+ size_t args_size ,
366
+ wasmtime_component_val_t * results ,
367
+ size_t results_size );
368
+ void (* wasmtime_component_export_index_delete ) (wasmtime_component_export_index_t * export_index );
369
+ void (* wasmtime_component_delete ) (wasmtime_component_t * c );
370
+ void (* wasmtime_component_linker_delete ) (wasmtime_component_linker_t * linker );
371
+ void (* wasmtime_error_message ) (const wasmtime_error_t * error , wasm_name_t * message );
372
+ void (* wasmtime_error_delete ) (wasmtime_error_t * error );
373
+
374
+ wasm_engine_delete = dlsym (cookie , "wasm_engine_delete" );
375
+ wasm_byte_vec_delete = dlsym (cookie , "wasm_byte_vec_delete" );
376
+ wasmtime_store_new = dlsym (cookie , "wasmtime_store_new" );
377
+ wasmtime_store_delete = dlsym (cookie , "wasmtime_store_delete" );
378
+ wasmtime_store_context = dlsym (cookie , "wasmtime_store_context" );
379
+ wasmtime_component_new = dlsym (cookie , "wasmtime_component_new" );
380
+ wasmtime_wasip2_config_new = dlsym (cookie , "wasmtime_wasip2_config_new" );
381
+ wasmtime_wasip2_config_inherit_stdin = dlsym (cookie , "wasmtime_wasip2_config_inherit_stdin" );
382
+ wasmtime_wasip2_config_inherit_stdout = dlsym (cookie , "wasmtime_wasip2_config_inherit_stdout" );
383
+ wasmtime_wasip2_config_inherit_stderr = dlsym (cookie , "wasmtime_wasip2_config_inherit_stderr" );
384
+ wasmtime_context_set_wasip2 = dlsym (cookie , "wasmtime_context_set_wasip2" );
385
+ wasmtime_component_linker_new = dlsym (cookie , "wasmtime_component_linker_new" );
386
+ wasmtime_component_linker_add_wasip2 = dlsym (cookie , "wasmtime_component_linker_add_wasip2" );
387
+ wasmtime_component_linker_instantiate = dlsym (cookie , "wasmtime_component_linker_instantiate" );
388
+ wasmtime_component_get_export_index = dlsym (cookie , "wasmtime_component_get_export_index" );
389
+ wasmtime_component_instance_get_export_index = dlsym (cookie , "wasmtime_component_instance_get_export_index" );
390
+ wasmtime_component_instance_get_func = dlsym (cookie , "wasmtime_component_instance_get_func" );
391
+ wasmtime_component_func_call = dlsym (cookie , "wasmtime_component_func_call" );
392
+ wasmtime_component_export_index_delete = dlsym (cookie , "wasmtime_component_export_index_delete" );
393
+ wasmtime_component_delete = dlsym (cookie , "wasmtime_component_delete" );
394
+ wasmtime_component_linker_delete = dlsym (cookie , "wasmtime_component_linker_delete" );
395
+ wasmtime_error_message = dlsym (cookie , "wasmtime_error_message" );
396
+ wasmtime_error_delete = dlsym (cookie , "wasmtime_error_delete" );
397
+
398
+ // Set up wasmtime context
399
+ wasmtime_store_t * store = wasmtime_store_new (engine , NULL , NULL );
400
+ assert (store != NULL );
401
+ wasmtime_context_t * context = wasmtime_store_context (store );
402
+
403
+ // Compile wasm component
404
+ wasmtime_component_t * component = NULL ;
405
+ wasmtime_error_t * err = wasmtime_component_new (engine , (uint8_t * ) wasm -> data , wasm -> size , & component );
406
+ if (! component || err != NULL )
407
+ {
408
+ wasmtime_error_message (err , & error_message );
409
+ wasmtime_error_delete (err );
410
+ error (EXIT_FAILURE , 0 , "failed to compile component: %.*s" , (int ) error_message .size , error_message .data );
411
+ }
412
+ wasm_byte_vec_delete (wasm );
413
+
414
+ // Set up WASIp2 config
415
+ wasmtime_wasip2_config_t * wasi_config = wasmtime_wasip2_config_new ();
416
+ assert (wasi_config != NULL );
417
+
418
+ wasmtime_wasip2_config_inherit_stdin (wasi_config );
419
+ wasmtime_wasip2_config_inherit_stdout (wasi_config );
420
+ wasmtime_wasip2_config_inherit_stderr (wasi_config );
421
+ // TODO: argv
422
+ wasmtime_context_set_wasip2 (context , wasi_config );
423
+
424
+ // Get wasi exposing linker
425
+ wasmtime_component_linker_t * linker = wasmtime_component_linker_new (engine );
426
+ err = wasmtime_component_linker_add_wasip2 (linker );
427
+ if (err != NULL )
428
+ {
429
+ wasmtime_error_message (err , & error_message );
430
+ wasmtime_error_delete (err );
431
+ error (EXIT_FAILURE , 0 , "failed to add WASIp2 to linker: %.*s" , (int ) error_message .size , error_message .data );
432
+ }
433
+
434
+ // Instantiate the component
435
+ wasmtime_component_instance_t component_inst = {};
436
+ err = wasmtime_component_linker_instantiate (linker , context , component , & component_inst );
437
+ if (err != NULL )
438
+ {
439
+ wasmtime_error_message (err , & error_message );
440
+ wasmtime_error_delete (err );
441
+ error (EXIT_FAILURE , 0 , "failed to instantiate component: %.*s" , (int ) error_message .size , error_message .data );
442
+ }
443
+
444
+ // Get index of the run interface in wasi/cli world
445
+ wasmtime_component_export_index_t * run_interface_idx = wasmtime_component_instance_get_export_index (
446
+ & component_inst ,
447
+ context ,
448
+ NULL ,
449
+ wasi_cli_run_interface ,
450
+ strlen (wasi_cli_run_interface ));
451
+ assert (run_interface_idx != NULL );
452
+ // Get index of the run function
453
+ wasmtime_component_export_index_t * run_func_idx = wasmtime_component_instance_get_export_index (
454
+ & component_inst ,
455
+ context ,
456
+ run_interface_idx ,
457
+ wasi_cli_run_interface_run ,
458
+ strlen (wasi_cli_run_interface_run ));
459
+ assert (run_func_idx != NULL );
460
+
461
+ // Actually retrieve the func
462
+ wasmtime_component_func_t run_func = {};
463
+ if (! wasmtime_component_instance_get_func (& component_inst , context , run_func_idx , & run_func ))
464
+ {
465
+ error (EXIT_FAILURE , 0 , "failed to retrieve run function" );
466
+ }
467
+
468
+ // Call the func
469
+ wasmtime_component_val_t result = {};
470
+ err = wasmtime_component_func_call (& run_func , context , NULL , 0 , & result , 1 );
471
+ if (err != NULL )
472
+ {
473
+ wasmtime_error_message (err , & error_message );
474
+ wasmtime_error_delete (err );
475
+ error (EXIT_FAILURE , 0 , "error calling run function: %.*s" , (int ) error_message .size , error_message .data );
476
+ }
477
+
478
+ // Clean everything
479
+ wasmtime_component_export_index_delete (run_func_idx );
480
+ wasmtime_component_export_index_delete (run_interface_idx );
481
+ wasmtime_component_linker_delete (linker );
482
+ wasmtime_component_delete (component );
483
+ wasmtime_store_delete (store );
484
+ wasm_engine_delete (engine );
320
485
}
321
486
322
487
static int
0 commit comments