Last active
January 31, 2023 18:22
-
-
Save Hrushi20/b1b5834592159ee5d69d309e2cb05434 to your computer and use it in GitHub Desktop.
Writing data to webassembly memory
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
WasmEdge | |
=============================================================================================================================== | |
use wasmedge_sdk::*; | |
use anyhow::{Result, Error, anyhow}; | |
use wasmedge_sdk::WasmValue; | |
use crate::SmartEngine; | |
const ALLOC_FN: &str = "alloc"; | |
const MEMORY: &str = "memory"; | |
// const ARRAY_SUM_FN: &str = "array_sum"; | |
// const UPPER_FN: &str = "upper"; | |
// const DEALLOC_FN: &str = "dealloc"; | |
/// Copy a byte array into an instance's linear memory | |
/// and return the offset relative to the module's memory. | |
pub(crate) fn copy_memory_to_instance( | |
store: &mut Store, | |
instance: &Instance, | |
bytes: &[u8], | |
engine: &mut SmartEngine | |
) -> Result<isize, Error> { | |
// Get the "memory" export of the module. | |
// If the module does not export it, just panic, | |
// since we are not going to be able to copy the data. | |
let mut memory = instance | |
.memory(MEMORY) | |
.ok_or_else(|| anyhow!("Missing memory"))?; | |
// The module is not using any bindgen libraries, | |
// so it should export its own alloc function. | |
// | |
// Get the guest's exported alloc function, and call it with the | |
// length of the byte array we are trying to copy. | |
// The result is an offset relative to the module's linear memory, | |
// which is used to copy the bytes into the module's memory. | |
// Then, return the offset. | |
let alloc = instance.func(ALLOC_FN).ok_or_else(|| anyhow!("Missing alloc"))?; | |
let alloc_result = alloc.call(&mut engine.executor,vec![WasmValue::from_i32(bytes.len() as i32)])?; | |
println!("Alloc Result: {:?}", alloc_result[0].to_i32()); | |
// Check the size of the guest_ptr_offset (Could be i32 or i64) | |
let guest_ptr_offset = alloc_result[0].to_i32(); | |
// Writing data in guest_ptr_offset. Need to move it from host_address_space. | |
memory.write(bytes, guest_ptr_offset as u32).expect("Coudlnt' write data to memory"); | |
println!("Data written at: {}",guest_ptr_offset); | |
Ok(guest_ptr_offset as isize) | |
} | |
Wasmtime | |
=============================================================================================================================== | |
use wasmtime::*; | |
use anyhow::{Result, Error, anyhow}; | |
const ALLOC_FN: &str = "alloc"; | |
const MEMORY: &str = "memory"; | |
// const ARRAY_SUM_FN: &str = "array_sum"; | |
// const UPPER_FN: &str = "upper"; | |
// const DEALLOC_FN: &str = "dealloc"; | |
/// Copy a byte array into an instance's linear memory | |
/// and return the offset relative to the module's memory. | |
pub(crate) fn copy_memory_to_instance( | |
store: &mut impl AsContextMut, | |
instance: &Instance, | |
bytes: &[u8], | |
) -> Result<isize, Error> { | |
// Get the "memory" export of the module. | |
// If the module does not export it, just panic, | |
// since we are not going to be able to copy the data. | |
let memory = instance | |
.get_memory(&mut *store, MEMORY) | |
.ok_or_else(|| anyhow!("Missing memory"))?; | |
// The module is not using any bindgen libraries, | |
// so it should export its own alloc function. | |
// | |
// Get the guest's exported alloc function, and call it with the | |
// length of the byte array we are trying to copy. | |
// The result is an offset relative to the module's linear memory, | |
// which is used to copy the bytes into the module's memory. | |
// Then, return the offset. | |
let alloc = instance | |
.get_func(&mut *store, ALLOC_FN) | |
.ok_or_else(|| anyhow!("missing alloc"))?; | |
let mut alloc_result = [Val::I32(0)]; | |
alloc.call( | |
&mut *store, | |
&[Val::from(bytes.len() as i32)], | |
&mut alloc_result, | |
)?; | |
println!("Alloc Result: {:?}",alloc_result); | |
let guest_ptr_offset = match alloc_result | |
.get(0) | |
.ok_or_else(|| anyhow!("missing alloc"))? | |
{ | |
Val::I32(val) => *val as isize, | |
_ => return Err(Error::msg("guest pointer must be Val::I32")), | |
}; | |
println!("Data pointer is: {:?}", memory.data_ptr(&store)); | |
unsafe { | |
let raw = memory.data_ptr(store).offset(guest_ptr_offset); | |
println!("Data written at : {:?}", raw); | |
raw.copy_from(bytes.as_ptr(), bytes.len()); | |
} | |
Ok(guest_ptr_offset) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment