(&self, store: &mut Store<Host>, func: Func)
| 988 | } |
| 989 | |
| 990 | async fn invoke_func(&self, store: &mut Store<Host>, func: Func) -> Result<()> { |
| 991 | let ty = func.ty(&store); |
| 992 | if ty.params().len() > 0 { |
| 993 | eprintln!( |
| 994 | "warning: using `--invoke` with a function that takes arguments \ |
| 995 | is experimental and may break in the future" |
| 996 | ); |
| 997 | } |
| 998 | let mut args = self.module_and_args.iter().skip(1); |
| 999 | let mut values = Vec::new(); |
| 1000 | for ty in ty.params() { |
| 1001 | let val = match args.next() { |
| 1002 | Some(s) => s, |
| 1003 | None => { |
| 1004 | if let Some(name) = &self.invoke { |
| 1005 | bail!("not enough arguments for `{name}`") |
| 1006 | } else { |
| 1007 | bail!("not enough arguments for command default") |
| 1008 | } |
| 1009 | } |
| 1010 | }; |
| 1011 | let val = val |
| 1012 | .to_str() |
| 1013 | .ok_or_else(|| format_err!("argument is not valid utf-8: {val:?}"))?; |
| 1014 | values.push(match ty { |
| 1015 | // Supports both decimal and hexadecimal notation (with 0x prefix) |
| 1016 | ValType::I32 => Val::I32(if val.starts_with("0x") || val.starts_with("0X") { |
| 1017 | i32::from_str_radix(&val[2..], 16)? |
| 1018 | } else { |
| 1019 | val.parse::<i32>()? |
| 1020 | }), |
| 1021 | ValType::I64 => Val::I64(if val.starts_with("0x") || val.starts_with("0X") { |
| 1022 | i64::from_str_radix(&val[2..], 16)? |
| 1023 | } else { |
| 1024 | val.parse::<i64>()? |
| 1025 | }), |
| 1026 | ValType::F32 => Val::F32(val.parse::<f32>()?.to_bits()), |
| 1027 | ValType::F64 => Val::F64(val.parse::<f64>()?.to_bits()), |
| 1028 | t => bail!("unsupported argument type {t:?}"), |
| 1029 | }); |
| 1030 | } |
| 1031 | |
| 1032 | // Invoke the function and then afterwards print all the results that came |
| 1033 | // out, if there are any. |
| 1034 | let mut results = vec![Val::null_func_ref(); ty.results().len()]; |
| 1035 | let invoke_res = func |
| 1036 | .call_async(&mut *store, &values, &mut results) |
| 1037 | .await |
| 1038 | .with_context(|| { |
| 1039 | if let Some(name) = &self.invoke { |
| 1040 | format!("failed to invoke `{name}`") |
| 1041 | } else { |
| 1042 | format!("failed to invoke command default") |
| 1043 | } |
| 1044 | }); |
| 1045 | |
| 1046 | if let Err(err) = invoke_res { |
| 1047 | return Err(self.handle_core_dump(&mut *store, err)); |
no test coverage detected