corevm-memory-test 0.1.22

A simple memory test program for CoreVM.
Documentation
#![cfg_attr(any(target_arch = "riscv32", target_arch = "riscv64"), no_std)]

extern crate alloc;

use alloc::alloc::{GlobalAlloc, Layout};
use corevm_guest::{free, println};
use corevm_memory_test_common::{generate_pages, page_checksum, NUM_PAGES};
use rand::{rngs::SmallRng, Rng, SeedableRng};

// This program pre-allocates more memory pages than can be exported from a work package, and then
// touches random pages until either the gas runs out or the max. no. of exported segments is
// reached.
// The purpose is to test how CoreVM handles programs that use more than `MAX_PAGES` memory pages.
#[polkavm_derive::polkavm_export]
pub extern "C" fn main() -> u64 {
	let mut rng = SmallRng::seed_from_u64(0);
	let pages = generate_pages(&mut rng);
	// Touch random pages until we ran out of exported pages.
	// Compute checksums and append them to the program output.
	for _ in 0..NUM_PAGES {
		let j = rng.random_range(0..NUM_PAGES);
		let (data, expected_checksum) = &pages[j];
		let actual_checksum = page_checksum(data);
		println!("{} {} {} {}", j, data.as_ptr() as u64, expected_checksum, actual_checksum);
	}
	0
}

#[cfg_attr(any(target_arch = "riscv32", target_arch = "riscv64"), global_allocator)]
#[cfg_attr(not(any(target_arch = "riscv32", target_arch = "riscv64")), allow(unused))]
static ALLOCATOR: NaiveAlloc = NaiveAlloc;

/// The allocator that allocates and frees memory using CoreVM-specific `alloc` and `free`
/// host-calls.
///
/// Each allocation is rounded up to the multiple of the page size.
pub struct NaiveAlloc;

unsafe impl GlobalAlloc for NaiveAlloc {
	#[inline]
	unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
		let size = layout.size() as u64;
		corevm_guest::alloc(size)
	}

	#[inline]
	unsafe fn dealloc(&self, address: *mut u8, layout: Layout) {
		let size = layout.size() as u64;
		free(address, size)
	}
}

#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
	corevm_guest::panic(info)
}