Skip to main content

tinywasm_cli/cmd/
run.rs

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, &params)?;
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}