1use eyre::{Result, bail};
2use tinywasm::types::ExportType;
3use tinywasm::{ModuleInstance, Store};
4
5use crate::cli::RunArgs;
6use crate::load::load_module;
7use crate::output::print_results;
8use crate::value_parse::parse_invocation_args;
9
10pub fn run(args: RunArgs) -> Result<()> {
11 let module_path = args.module.as_deref().ok_or_else(|| eyre::eyre!("missing module path"))?;
12 let loaded = load_module(module_path)?;
13 let mut store = Store::new(args.engine.build_engine()?);
14 let instance = ModuleInstance::instantiate_no_start(&mut store, &loaded.module, None)?;
15
16 match args.invoke.as_deref() {
17 Some(export) => {
18 if loaded.module.start_func.is_some() {
19 let _ = instance.start(&mut store)?;
20 }
21
22 let func_ty = loaded
23 .module
24 .exports()
25 .find_map(|item| match (item.name == export, item.ty) {
26 (true, ExportType::Func(ty)) => Some(ty),
27 _ => None,
28 })
29 .ok_or_else(|| eyre::eyre!("export is not a function: {export}"))?;
30 let func = instance.func_untyped(&store, export)?;
31 let params = parse_invocation_args(func_ty, &args.args)?;
32 let results = func.call(&mut store, ¶ms)?;
33 print_results(&results);
34 Ok(())
35 }
36 None => {
37 if instance.start_func(&store)?.is_none() {
38 bail!(
39 "module has no start function or `_start` export; use `tinywasm inspect {module_path}` or `tinywasm run --invoke <export> {module_path}`"
40 )
41 }
42
43 let _ = instance.start(&mut store)?;
44 Ok(())
45 }
46 }
47}