|
| 1 | +use std::collections::HashMap; |
| 2 | +use std::rc::Rc; |
| 3 | +use std::time::{Instant, SystemTime, UNIX_EPOCH}; |
| 4 | + |
| 5 | +use wagmi::{ExportValue, Imports, Instance, Module, RuntimeFunction, ValType, WasmValue}; |
| 6 | + |
| 7 | +fn vt_name(v: ValType) -> &'static str { |
| 8 | + match v { |
| 9 | + ValType::I32 => "i32", |
| 10 | + ValType::I64 => "i64", |
| 11 | + ValType::F32 => "f32", |
| 12 | + ValType::F64 => "f64", |
| 13 | + ValType::Any => "any", |
| 14 | + } |
| 15 | +} |
| 16 | + |
| 17 | +fn clock_ms_i64() -> i64 { |
| 18 | + SystemTime::now() |
| 19 | + .duration_since(UNIX_EPOCH) |
| 20 | + .expect("Clock may have gone backwards") |
| 21 | + .as_millis() as i64 |
| 22 | +} |
| 23 | + |
| 24 | +fn main() -> Result<(), Box<dyn std::error::Error>> { |
| 25 | + let coremark_bytes = include_bytes!("coremark-minimal.wasm"); |
| 26 | + |
| 27 | + let module = Module::compile(coremark_bytes.to_vec()) |
| 28 | + .map_err(|e| format!("Failed to compile coremark module: {:?}", e))?; |
| 29 | + |
| 30 | + { |
| 31 | + println!("Imports:"); |
| 32 | + for (mod_name, fields) in &module.imports { |
| 33 | + for (field, et) in fields { |
| 34 | + let kind = match et { wagmi::module::ExternType::Func => "func", wagmi::module::ExternType::Table => "table", wagmi::module::ExternType::Mem => "mem", wagmi::module::ExternType::Global => "global" }; |
| 35 | + println!(" {}::{} ({})", mod_name, field, kind); |
| 36 | + } |
| 37 | + } |
| 38 | + |
| 39 | + for (idx, func) in module.functions.iter().enumerate() { |
| 40 | + if let Some(import) = &func.import { |
| 41 | + let params: Vec<&str> = func.ty.params.iter().copied().map(vt_name).collect(); |
| 42 | + let res = func.ty.result.map(vt_name); |
| 43 | + println!( |
| 44 | + " import func #{} {}::{} (params=[{}], result={})", |
| 45 | + idx, |
| 46 | + import.module, |
| 47 | + import.field, |
| 48 | + params.join(", "), |
| 49 | + res.unwrap_or("void") |
| 50 | + ); |
| 51 | + } |
| 52 | + } |
| 53 | + if let Some(mem) = &module.memory { |
| 54 | + if let Some(import) = &mem.import { println!(" imports memory {}::{} min={} max={}", import.module, import.field, mem.min, mem.max); } |
| 55 | + } |
| 56 | + if let Some(table) = &module.table { |
| 57 | + if let Some(import) = &table.import { println!(" imports table {}::{} min={} max={}", import.module, import.field, table.min, table.max); } |
| 58 | + } |
| 59 | + } |
| 60 | + let module = Rc::new(module); |
| 61 | + |
| 62 | + let clock_fn = RuntimeFunction::new_host( |
| 63 | + vec![], |
| 64 | + Some(ValType::I64), |
| 65 | + move |_args| Some(WasmValue::from_i64(clock_ms_i64())), |
| 66 | + ); |
| 67 | + let mut imports: Imports = Imports::new(); |
| 68 | + let mut env_mod: HashMap<String, ExportValue> = HashMap::new(); |
| 69 | + env_mod.insert("clock_ms".to_string(), ExportValue::Function(clock_fn)); |
| 70 | + imports.insert("env".to_string(), env_mod); |
| 71 | + |
| 72 | + let instance = Instance::instantiate(module, &imports) |
| 73 | + .map_err(|e| format!("Failed to instantiate coremark module: {:?}", e))?; |
| 74 | + |
| 75 | + let run_fn = match instance.exports.get("run") { |
| 76 | + Some(ExportValue::Function(f)) => f, |
| 77 | + _ => return Err("Export 'run' not found or not a function".into()), |
| 78 | + }; |
| 79 | + |
| 80 | + println!("Running Coremark minimal with WAGMI... (this may take a while)"); |
| 81 | + let t0 = Instant::now(); |
| 82 | + let results = instance |
| 83 | + .invoke(run_fn, &[]) |
| 84 | + .map_err(|e| format!("Execution failed: {:?}", e))?; |
| 85 | + let elapsed = t0.elapsed(); |
| 86 | + |
| 87 | + let score = results[0].as_f32(); |
| 88 | + println!("Result: {} (elapsed {:.3}s)", score, elapsed.as_secs_f64()); |
| 89 | + |
| 90 | + Ok(()) |
| 91 | +} |
| 92 | + |
| 93 | + |
0 commit comments