Skip to content

Commit

Permalink
feat: cli now has options to specify arguments and function to run
Browse files Browse the repository at this point in the history
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
  • Loading branch information
explodingcamera committed Dec 6, 2023
1 parent 5f928b7 commit 7d167c2
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 13 deletions.
48 changes: 48 additions & 0 deletions crates/cli/src/args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use std::str::FromStr;
use tinywasm::WasmValue;

#[derive(Debug)]
pub struct WasmArg(WasmValue);

pub fn to_wasm_args(args: Vec<WasmArg>) -> Vec<WasmValue> {
args.into_iter().map(|a| a.into()).collect()
}

impl From<WasmArg> for WasmValue {
fn from(value: WasmArg) -> Self {
value.0
}
}

impl FromStr for WasmArg {
type Err = String;
fn from_str(s: &str) -> std::prelude::v1::Result<Self, Self::Err> {
let [ty, val]: [&str; 2] = s
.split(':')
.collect::<Vec<_>>()
.try_into()
.map_err(|e| format!("invalid arguments: {:?}", e))?;

let arg: WasmValue = match ty {
"i32" => val
.parse::<i32>()
.map_err(|e| format!("invalid argument value for i32: {e:?}"))?
.into(),
"i64" => val
.parse::<i64>()
.map_err(|e| format!("invalid argument value for i64: {e:?}"))?
.into(),
"f32" => val
.parse::<f32>()
.map_err(|e| format!("invalid argument value for f32: {e:?}"))?
.into(),
"f64" => val
.parse::<f64>()
.map_err(|e| format!("invalid argument value for f64: {e:?}"))?
.into(),
t => return Err(format!("Invalid arg type: {}", t)),
};

Ok(WasmArg(arg))
}
}
42 changes: 29 additions & 13 deletions crates/cli/src/bin.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
use std::str::FromStr;

use argh::FromArgs;
use args::WasmArg;
use color_eyre::eyre::Result;
use log::info;
use tinywasm::{self, Module};
use log::{debug, info};
use tinywasm::{self, Module, WasmValue};

use crate::args::to_wasm_args;
mod args;
mod util;

#[cfg(feature = "wat")]
Expand Down Expand Up @@ -49,6 +53,14 @@ struct Run {
#[argh(positional)]
wasm_file: String,

/// function to run
#[argh(option, short = 'f')]
func: Option<String>,

/// arguments to pass to the wasm file
#[argh(option, short = 'a')]
args: Vec<WasmArg>,

/// engine to use
#[argh(option, short = 'e', default = "Engine::Main")]
engine: Engine,
Expand All @@ -72,7 +84,14 @@ fn main() -> Result<()> {
let cwd = std::env::current_dir()?;

match args.nested {
TinyWasmSubcommand::Run(Run { wasm_file, engine }) => {
TinyWasmSubcommand::Run(Run {
wasm_file,
engine,
args,
func,
}) => {
debug!("args: {:?}", args);

let path = cwd.join(wasm_file.clone());
let module = match wasm_file.ends_with(".wat") {
#[cfg(feature = "wat")]
Expand All @@ -87,24 +106,21 @@ fn main() -> Result<()> {
};

match engine {
Engine::Main => run(module),
Engine::Main => run(module, func, to_wasm_args(args)),
}
}
}
}

fn run(module: Module) -> Result<()> {
fn run(module: Module, func: Option<String>, args: Vec<WasmValue>) -> Result<()> {
let mut store = tinywasm::Store::default();
let instance = module.instantiate(&mut store)?;

let func = instance.get_typed_func::<(i32, i32), (i32,)>(&store, "add")?;
let (res,) = func.call(&mut store, (2, 2))?;
info!("{res:?}");

// let func = instance.get_func(&store, "add")?;
// let params = vec![WasmValue::I32(2), WasmValue::I32(2)];
// let res = func.call(&mut store, &params)?;
// info!("{res:?}");
if let Some(func) = func {
let func = instance.get_func(&store, &func)?;
let res = func.call(&mut store, &args)?;
info!("{res:?}");
}

Ok(())
}
20 changes: 20 additions & 0 deletions examples/wasm/loop.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
(module
(func $loopExample (export "loopExample")
(local i32) ;; Declare a local i32 variable, let's call it 'i'
(i32.const 0) ;; Initialize 'i' to 0
(local.set 0)

(loop $loopStart ;; Start of the loop
(local.get 0) ;; Get the current value of 'i'
(i32.const 1) ;; Push 1 onto the stack
(i32.add) ;; Add 'i' and 1
(local.set 0) ;; Update 'i' with the new value

(local.get 0) ;; Push the current value of 'i' to check the condition
(i32.const 10) ;; Push 10 onto the stack
(i32.lt_s) ;; Check if 'i' is less than 10
(br_if $loopStart) ;; If 'i' < 10, continue the loop
)
)
)

0 comments on commit 7d167c2

Please sign in to comment.