| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- use wasmer::{Array, Memory, WasmPtr};
- use crate::{Error, Result};
- pub trait MemoryManipulation {
- fn write(&self, mem_offset: u32, value_slice: &[u8]) -> Result<()>;
- fn read(&self, mem_offset: u32, value_len: usize) -> Option<&[u8]>;
- }
- impl MemoryManipulation for Memory {
- fn write(&self, mem_offset: u32, value_slice: &[u8]) -> Result<()> {
- // Prepare WasmPtr
- let target_ptr: WasmPtr<u8, Array> = WasmPtr::new(mem_offset);
- // Allocate necessary memory space on guest
- let guest_value_slice = match target_ptr.deref(self, 0, value_slice.len() as u32) {
- Some(slice) => slice,
- None => [].to_vec(),
- };
- if guest_value_slice.is_empty() {
- return Err(Error::WasmerOomError)
- }
- // Copy bytes to guest
- for i in 0..value_slice.len() {
- guest_value_slice[i].set(value_slice[i]);
- }
- Ok(())
- }
- fn read(&self, mem_offset: u32, value_len: usize) -> Option<&[u8]> {
- let memory_size = self.size().bytes().0;
- if mem_offset as usize + value_len > memory_size || mem_offset as usize >= memory_size {
- return None
- }
- let ptr = unsafe { self.view::<u8>().as_ptr().add(mem_offset as usize) as *const u8 };
- unsafe { Some(std::slice::from_raw_parts(ptr, value_len)) }
- }
- }
- #[cfg(test)]
- mod tests {
- use super::*;
- use wasmer::{imports, wat2wasm, Instance, Module, Store};
- fn wasmer_instance() -> Instance {
- let wasm_bytes = wat2wasm(
- br#"
- (module
- (type $add_one_t (func (param i32) (result i32)))
- (func $add_one_f (type $add_one_t) (param $value i32) (result i32)
- local.get $value
- i32.const 1
- i32.add)
- (export "add_one" (func $add_one_f))
- (memory $memory (export "memory") 17))
- "#,
- )
- .unwrap();
- let store = Store::default();
- let module = Module::new(&store, wasm_bytes).unwrap();
- let import_object = imports! {};
- Instance::new(&module, &import_object).unwrap()
- }
- #[test]
- fn can_write_on_memory() {
- let wasmer_instance = wasmer_instance();
- let memory = wasmer_instance.exports.get_memory("memory").unwrap();
- let data = String::from("data_test");
- let mem_addr = 0x2220;
- memory.write(mem_addr as u32, data.as_bytes()).unwrap();
- let ptr = unsafe { memory.view::<u8>().as_ptr().add(mem_addr as usize) as *const u8 };
- let slice_raw = unsafe { std::slice::from_raw_parts(ptr, data.len()) };
- assert_eq!(data.as_bytes(), slice_raw);
- }
- #[test]
- fn can_read_from_memory() {
- let wasmer_instance = wasmer_instance();
- let memory = wasmer_instance.exports.get_memory("memory").unwrap();
- let data = String::from("data_test");
- let mem_addr = 0x2220;
- memory.write(mem_addr as u32, data.as_bytes()).unwrap();
- let slice_raw = memory.read(mem_addr as u32, data.as_bytes().len()).unwrap();
- assert_eq!(data.as_bytes(), slice_raw);
- }
- }
|