jam-pvm-common 0.1.28

Common logic for JAM PVM crates including services and authorizers
Documentation
use codec::{Decode, Encode, Output};
pub use core::alloc::Layout;

#[cfg(target_env = "polkavm")]
extern crate picoalloc; // This will pull in the global allocator.

pub fn alloc(size: u32) -> u32 {
	let ptr = unsafe { alloc::alloc::alloc(Layout::from_size_align(size as usize, 4).unwrap()) };
	ptr as u32
}

pub fn dealloc(ptr: u32, size: u32) {
	unsafe {
		alloc::alloc::dealloc(ptr as *mut u8, Layout::from_size_align(size as usize, 4).unwrap())
	};
}

pub struct BufferOutput<'a>(&'a mut [u8], usize);
impl Output for BufferOutput<'_> {
	/// Write to the output.
	fn write(&mut self, bytes: &[u8]) {
		let (_, rest) = self.0.split_at_mut(self.1);
		let len = bytes.len().min(rest.len());
		rest[..len].copy_from_slice(&bytes[..len]);
		self.1 += len;
	}
}

pub fn decode_buf<T: Decode>(ptr: u32, size: u32) -> T {
	let slice = unsafe { core::slice::from_raw_parts(ptr as *const u8, size as usize) };
	let params = T::decode(&mut &slice[..]);
	params.unwrap()
}

pub fn encode_to_buf<T: Encode>(value: T) -> (u32, u32) {
	// TODO: @gav wish avoid extra copy
	let size = value.encoded_size();
	let ptr = alloc(size as u32);
	let slice = unsafe { core::slice::from_raw_parts_mut(ptr as *mut u8, size) };
	value.encode_to(&mut BufferOutput(&mut slice[..], 0));
	(ptr, size as u32)
}