inkpad_executor/
memory.rs1#[cfg(not(feature = "std"))]
3use crate::wasmi as e;
4#[cfg(feature = "std")]
5use crate::wasmtime as e;
6use crate::{derive, Result};
7use core::ops;
8use parity_wasm::elements::{External, Module};
9
10const IMPORT_MODULE_MEMORY: &str = "env";
11
12#[derive(Clone)]
14pub struct Memory(pub e::Memory);
15
16impl ops::Deref for Memory {
17 type Target = e::Memory;
18
19 fn deref(&self) -> &e::Memory {
20 &self.0
21 }
22}
23
24impl Memory {
25 pub fn new(initial: u32, maximum: Option<u32>) -> Result<Self> {
27 Ok(Self(<e::Memory as derive::Memory>::new(initial, maximum)?))
28 }
29
30 pub fn get(&self, ptr: u32, buf: &mut [u8]) -> Result<()> {
32 derive::Memory::get(&self.0, ptr, buf)
33 }
34
35 pub fn set(&self, ptr: u32, value: &[u8]) -> Result<()> {
37 derive::Memory::set(&self.0, ptr, value)
38 }
39}
40
41pub fn scan_imports(module: &Module) -> core::result::Result<(u32, Option<u32>), &'static str> {
50 let import_entries = module
51 .import_section()
52 .map(|is| is.entries())
53 .unwrap_or(&[]);
54
55 let mut range = None;
56 for import in import_entries {
57 match import.external() {
58 External::Table(_) => return Err("Cannot import tables"),
59 External::Global(_) => return Err("Cannot import globals"),
60 External::Function(ref type_idx) => type_idx,
61 External::Memory(ref memory_type) => {
62 if import.module() != IMPORT_MODULE_MEMORY {
63 return Err("Invalid module for imported memory");
64 }
65 if import.field() != "memory" {
66 return Err("Memory import must have the field name 'memory'");
67 }
68 if range.is_some() {
69 return Err("Multiple memory imports defined");
70 }
71
72 let limits = memory_type.limits();
73 range = Some((limits.initial() as u32, limits.maximum().map(|v| v as u32)));
74 continue;
75 }
76 };
77 }
78
79 if let Some(limit) = range {
80 Ok(limit)
81 } else {
82 Ok((0, None))
83 }
84}