1use crate::{Error, Result};
3use inkpad_std::Vec;
4use inkpad_support::convert::step_hex;
5use parity_wasm::elements::{External, Module};
6
7const IMPORT_MODULE_MEMORY: &str = "env";
8
9pub fn parse_args(selector: &str, args: Vec<Vec<u8>>, tys: Vec<u32>) -> Result<Vec<u8>> {
11 if args.len() != tys.len() {
12 return Err(Error::InvalidArgumentLength {
13 expect: tys.len(),
14 input: args.len(),
15 });
16 }
17
18 let mut res = step_hex(selector)
19 .ok_or(Error::DecodeSelectorFailed)?
20 .to_vec();
21 for mut arg in args {
22 log::debug!("-----> {:?}", arg);
23 res.append(&mut arg);
24 }
25
26 Ok(res)
27}
28
29pub fn scan_imports(module: &Module) -> core::result::Result<(u32, Option<u32>), &'static str> {
38 let import_entries = module
39 .import_section()
40 .map(|is| is.entries())
41 .unwrap_or(&[]);
42
43 let mut range = None;
44 for import in import_entries {
45 match import.external() {
46 External::Table(_) => return Err("Cannot import tables"),
47 External::Global(_) => return Err("Cannot import globals"),
48 External::Function(ref type_idx) => type_idx,
49 External::Memory(ref memory_type) => {
50 if import.module() != IMPORT_MODULE_MEMORY {
51 return Err("Invalid module for imported memory");
52 }
53 if import.field() != "memory" {
54 return Err("Memory import must have the field name 'memory'");
55 }
56 if range.is_some() {
57 return Err("Multiple memory imports defined");
58 }
59
60 let limits = memory_type.limits();
61 range = Some((limits.initial() as u32, limits.maximum().map(|v| v as u32)));
62 continue;
63 }
64 };
65 }
66
67 if let Some(limit) = range {
68 Ok(limit)
69 } else {
70 Ok((0, None))
71 }
72}