corevm_guest/
rust.rs

1//! Rust wrappers around C API.
2
3#![allow(clippy::missing_safety_doc)]
4
5use crate::c;
6use core::mem::size_of_val;
7use corevm_types::{AudioMode, VideoMode};
8
9/// Get the current amount of gas.
10#[inline]
11pub fn gas() -> u64 {
12	unsafe { c::gas() }
13}
14
15/// Allocate memory block of the specified size.
16///
17/// - The size is rounded up to the next multiple of page size.
18/// - The returned address is aligned at a page boundary.
19///
20/// Returns the pointer to the allocated memory region or [`null_mut()`](core::ptr::null_mut) if the
21/// allocation was unsuccessful.
22#[inline]
23pub unsafe fn alloc(size: u64) -> *mut u8 {
24	c::alloc(size) as *mut u8
25}
26
27/// Deallocate the memory block of the specified size starting at `address`.
28///
29/// Deallocates *all* the pages that overlap the memory block.
30#[inline]
31pub unsafe fn free(address: *mut u8, size: u64) {
32	c::free(address as u64, size)
33}
34
35/// Console stream type.
36#[derive(Debug, Clone, Copy, PartialEq, Eq)]
37pub enum ConsoleStream {
38	/// Standard output stream.
39	Stdout = 1,
40	/// Standard error stream.
41	Stderr = 2,
42}
43
44/// Append `data` to the specified _console_ output stream.
45#[inline]
46pub fn yield_console_data<S: AsRef<[u8]>>(stream: ConsoleStream, data: S) {
47	let bytes = data.as_ref();
48	let len = bytes.len() as u64;
49	unsafe { c::yield_console_data(stream as u64, bytes.as_ptr() as u64, len) };
50}
51
52/// Append video frame to the _video_ output stream.
53///
54/// Frame format is defined by [`video_mode`](crate::video_mode).
55#[inline]
56pub fn yield_video_frame(frame: &[u8]) {
57	let address = frame.as_ptr() as u64;
58	let len = size_of_val(frame) as u64;
59	unsafe { c::yield_video_frame(address, len) };
60}
61
62/// Set video monitor output mode to `mode`.
63#[inline]
64pub fn video_mode(mode: VideoMode) {
65	unsafe {
66		c::video_mode(
67			u64::from(mode.width.get()),
68			u64::from(mode.height.get()),
69			u64::from(mode.refresh_rate.get()),
70			mode.format as u64,
71		)
72	}
73}
74
75/// Append audio samples to the _audio_ output stream.
76///
77/// Sample format is defined by [`audio_mode`](crate::audio_mode).
78#[inline]
79pub fn yield_audio_samples<T: AudioSample>(samples: &[T]) {
80	let address = samples.as_ptr() as u64;
81	let len = size_of_val(samples) as u64;
82	unsafe { c::yield_audio_samples(address, len) };
83}
84
85/// Marker trait for types that can be used as audio samples.
86pub trait AudioSample: Copy + Sized {}
87
88impl AudioSample for u8 {}
89impl AudioSample for i16 {}
90
91/// Set audio output mode to `mode`.
92#[inline]
93pub fn audio_mode(mode: AudioMode) {
94	unsafe {
95		c::audio_mode(
96			u64::from(mode.channels.get()),
97			u64::from(mode.sample_rate.get()),
98			mode.sample_format as u64,
99		)
100	}
101}