mirror of
https://github.com/pezkuwichain/wasm-instrument.git
synced 2026-06-12 14:41:05 +00:00
partly working
This commit is contained in:
+56
-29
@@ -10,11 +10,53 @@ use std::slice;
|
||||
#[link_args = "-s WASM=1 -s NO_EXIT_RUNTIME=1 -s NO_FILESYSTEM=1 -s"]
|
||||
extern {}
|
||||
|
||||
mod storage {
|
||||
pub struct Error;
|
||||
|
||||
#[link(name = "env")]
|
||||
extern {
|
||||
fn storage_read(offset: u32, len: u32, dst: *mut u8) -> i32;
|
||||
fn storage_write(offset: u32, len: u32, src: *const u8) -> i32;
|
||||
fn storage_size() -> u32;
|
||||
}
|
||||
|
||||
pub fn read(offset: u32, dst: &mut [u8]) -> Result<u32, Error> {
|
||||
match unsafe {
|
||||
storage_read(offset, dst.len() as u32, dst.as_mut_ptr())
|
||||
} {
|
||||
x if x < 0 => Err(Error),
|
||||
x => Ok(x as u32),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write(offset: u32, src: &[u8]) -> Result<u32, Error> {
|
||||
match unsafe {
|
||||
storage_write(offset, src.len() as u32, src.as_ptr())
|
||||
} {
|
||||
x if x < 0 => Err(Error),
|
||||
x => Ok(x as u32),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn size() -> u32 {
|
||||
unsafe {
|
||||
storage_size()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn append(src: &[u8]) -> Result<u32, Error> {
|
||||
let sz = size();
|
||||
match write(sz, src) {
|
||||
Ok(_) => Ok(sz),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Safe (?) wrapper around call context
|
||||
struct CallArgs {
|
||||
context: Box<[u8]>,
|
||||
result: Vec<u8>,
|
||||
storage: Vec<u8>,
|
||||
}
|
||||
|
||||
unsafe fn read_ptr_mut(slc: &[u8]) -> *mut u8 {
|
||||
@@ -40,23 +82,17 @@ fn write_ptr(dst: &mut [u8], ptr: *mut u8) {
|
||||
|
||||
impl CallArgs {
|
||||
pub fn from_raw(ptr: *mut u8) -> CallArgs {
|
||||
let desc_slice = unsafe { slice::from_raw_parts(ptr, 6 * 4) };
|
||||
let desc_slice = unsafe { slice::from_raw_parts(ptr, 4 * 4) };
|
||||
|
||||
let context_ptr = unsafe { read_ptr_mut(&desc_slice[0..4]) };
|
||||
let context_len = read_u32(&desc_slice[4..8]) as usize;
|
||||
|
||||
let storage_ptr = unsafe { read_ptr_mut(&desc_slice[8..12]) };
|
||||
let storage_len = read_u32(&desc_slice[12..16]) as usize;
|
||||
|
||||
let result_ptr = unsafe { read_ptr_mut(&desc_slice[16..20]) };
|
||||
let result_len = read_u32(&desc_slice[20..24]) as usize;
|
||||
let result_ptr = unsafe { read_ptr_mut(&desc_slice[8..12]) };
|
||||
let result_len = read_u32(&desc_slice[12..16]) as usize;
|
||||
|
||||
CallArgs {
|
||||
context: unsafe { Box::<[u8]>::from_raw(slice::from_raw_parts_mut(context_ptr, context_len)) },
|
||||
result: unsafe { Vec::from_raw_parts(result_ptr, result_len, result_len) },
|
||||
// todo: consider: storage (and result?) might also have initial allocation size passed in
|
||||
// the descriptor along with length
|
||||
storage: unsafe { Vec::from_raw_parts(storage_ptr, storage_len, storage_len) },
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,36 +104,27 @@ impl CallArgs {
|
||||
&mut self.result
|
||||
}
|
||||
|
||||
pub fn storage(&self) -> &[u8] {
|
||||
&self.storage
|
||||
}
|
||||
|
||||
pub fn storage_mut(&mut self) -> &mut Vec<u8> {
|
||||
&mut self.storage
|
||||
}
|
||||
|
||||
pub fn save(self, ptr: *mut u8) {
|
||||
let dst = unsafe { slice::from_raw_parts_mut(ptr, 6 * 4) };
|
||||
let context = self.context;
|
||||
let mut result = self.result;
|
||||
let mut storage = self.storage;
|
||||
|
||||
// context unmodified and memory is managed in calling code
|
||||
std::mem::forget(context);
|
||||
|
||||
write_ptr(dst, storage.as_mut_ptr());
|
||||
write_u32(dst, storage.len() as u32);
|
||||
// managed in calling code
|
||||
std::mem::forget(storage);
|
||||
|
||||
write_ptr(dst, result.as_mut_ptr());
|
||||
write_u32(dst, result.len() as u32);
|
||||
// managed in calling code
|
||||
std::mem::forget(result);
|
||||
if result.len() > 0 {
|
||||
// result
|
||||
write_ptr(dst, result.as_mut_ptr());
|
||||
write_u32(dst, result.len() as u32);
|
||||
// managed in calling code
|
||||
std::mem::forget(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn call(descriptor: *mut u8) {
|
||||
let context = CallArgs::from_raw(descriptor);
|
||||
let mut ctx = CallArgs::from_raw(descriptor);
|
||||
let _ = storage::append(ctx.context());
|
||||
*ctx.result_mut() = ctx.context().to_vec();
|
||||
}
|
||||
Reference in New Issue
Block a user