Skip to content

Commit

Permalink
feat(common): Move from RegisterSize to native ptr size type (#95)
Browse files Browse the repository at this point in the history
  • Loading branch information
clabby authored Apr 8, 2024
1 parent 8f5c7ee commit 2dba60b
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 89 deletions.
28 changes: 14 additions & 14 deletions crates/common/src/asterisc/io.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{asterisc::syscall, BasicKernelInterface, FileDescriptor, RegisterSize};
use crate::{asterisc::syscall, BasicKernelInterface, FileDescriptor};
use anyhow::Result;

/// Concrete implementation of the [`KernelIO`] trait for the `riscv64` target architecture.
Expand All @@ -13,7 +13,7 @@ pub struct AsteriscIO;
/// only the ones necessary for the [BasicKernelInterface] trait implementation. If an extension
/// trait for the [BasicKernelInterface] trait is created for the `asterisc` kernel, this list
/// should be extended accordingly.
#[repr(u32)]
#[repr(usize)]
pub(crate) enum SyscallNumber {
/// Sets the Exited and ExitCode states to true and $a0 respectively.
Exit = 93,
Expand All @@ -24,31 +24,31 @@ pub(crate) enum SyscallNumber {
}

impl BasicKernelInterface for AsteriscIO {
fn write(fd: FileDescriptor, buf: &[u8]) -> Result<RegisterSize> {
fn write(fd: FileDescriptor, buf: &[u8]) -> Result<usize> {
unsafe {
Ok(syscall::syscall3(
SyscallNumber::Write as u64,
SyscallNumber::Write as usize,
fd.into(),
buf.as_ptr() as u64,
buf.len() as u64,
) as RegisterSize)
buf.as_ptr() as usize,
buf.len(),
))
}
}

fn read(fd: FileDescriptor, buf: &mut [u8]) -> Result<RegisterSize> {
fn read(fd: FileDescriptor, buf: &mut [u8]) -> Result<usize> {
unsafe {
Ok(syscall::syscall3(
SyscallNumber::Read as u64,
SyscallNumber::Read as usize,
fd.into(),
buf.as_ptr() as u64,
buf.len() as u64,
) as RegisterSize)
buf.as_ptr() as usize,
buf.len(),
))
}
}

fn exit(code: RegisterSize) -> ! {
fn exit(code: usize) -> ! {
unsafe {
syscall::syscall1(SyscallNumber::Exit as u64, code);
syscall::syscall1(SyscallNumber::Exit as usize, code);
panic!()
}
}
Expand Down
17 changes: 8 additions & 9 deletions crates/common/src/asterisc/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@
//! | %a5 | arg6 |
//! | %a7 | syscall number |
use crate::RegisterSize;
use core::arch::asm;

/// Issues a raw system call with 1 argument. (e.g. exit)
#[inline]
pub(crate) unsafe fn syscall1(syscall_number: RegisterSize, arg1: RegisterSize) -> RegisterSize {
let mut ret: RegisterSize;
pub(crate) unsafe fn syscall1(syscall_number: usize, arg1: usize) -> usize {
let mut ret: usize;
asm!(
"ecall",
in("a7") syscall_number,
Expand All @@ -34,12 +33,12 @@ pub(crate) unsafe fn syscall1(syscall_number: RegisterSize, arg1: RegisterSize)
/// Issues a raw system call with 3 arguments. (e.g. read, write)
#[inline]
pub(crate) unsafe fn syscall3(
syscall_number: RegisterSize,
arg1: RegisterSize,
arg2: RegisterSize,
arg3: RegisterSize,
) -> RegisterSize {
let mut ret: RegisterSize;
syscall_number: usize,
arg1: usize,
arg2: usize,
arg3: usize,
) -> usize {
let mut ret: usize;
asm!(
"ecall",
in("a7") syscall_number,
Expand Down
24 changes: 12 additions & 12 deletions crates/common/src/cannon/io.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{cannon::syscall, BasicKernelInterface, FileDescriptor, RegisterSize};
use crate::{cannon::syscall, BasicKernelInterface, FileDescriptor};
use anyhow::{anyhow, Result};

/// Concrete implementation of the [BasicKernelInterface] trait for the `MIPS32rel1` target
Expand All @@ -14,7 +14,7 @@ pub struct CannonIO;
/// only the ones necessary for the [BasicKernelInterface] trait implementation. If an extension
/// trait for the [BasicKernelInterface] trait is created for the `Cannon` kernel, this list should
/// be extended accordingly.
#[repr(u32)]
#[repr(usize)]
pub(crate) enum SyscallNumber {
/// Sets the Exited and ExitCode states to true and $a0 respectively.
Exit = 4246,
Expand All @@ -25,33 +25,33 @@ pub(crate) enum SyscallNumber {
}

impl BasicKernelInterface for CannonIO {
fn write(fd: FileDescriptor, buf: &[u8]) -> Result<RegisterSize> {
fn write(fd: FileDescriptor, buf: &[u8]) -> Result<usize> {
unsafe {
syscall::syscall3(
SyscallNumber::Write as u32,
SyscallNumber::Write as usize,
fd.into(),
buf.as_ptr() as u32,
buf.len() as u32,
buf.as_ptr() as usize,
buf.len(),
)
.map_err(|e| anyhow!("Syscall Error: {e}"))
}
}

fn read(fd: FileDescriptor, buf: &mut [u8]) -> Result<RegisterSize> {
fn read(fd: FileDescriptor, buf: &mut [u8]) -> Result<usize> {
unsafe {
syscall::syscall3(
SyscallNumber::Read as u32,
SyscallNumber::Read as usize,
fd.into(),
buf.as_ptr() as u32,
buf.len() as u32,
buf.as_ptr() as usize,
buf.len(),
)
.map_err(|e| anyhow!("Syscall Error: {e}"))
}
}

fn exit(code: RegisterSize) -> ! {
fn exit(code: usize) -> ! {
unsafe {
syscall::syscall1(SyscallNumber::Exit as RegisterSize, code);
syscall::syscall1(SyscallNumber::Exit as usize, code);
panic!()
}
}
Expand Down
23 changes: 11 additions & 12 deletions crates/common/src/cannon/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,13 @@
//!
//! All temporary registers are clobbered (8-15, 24-25).
use crate::RegisterSize;
use core::arch::asm;

/// Issues a raw system call with 1 argument. (e.g. exit)
#[inline]
pub(crate) unsafe fn syscall1(n: RegisterSize, arg1: RegisterSize) -> RegisterSize {
let mut err: RegisterSize;
let mut ret: RegisterSize;
pub(crate) unsafe fn syscall1(n: usize, arg1: usize) -> usize {
let mut err: usize;
let mut ret: usize;
asm!(
"syscall",
inlateout("$2") n => ret,
Expand All @@ -67,13 +66,13 @@ pub(crate) unsafe fn syscall1(n: RegisterSize, arg1: RegisterSize) -> RegisterSi
/// Issues a raw system call with 3 arguments. (e.g. read, write)
#[inline]
pub(crate) unsafe fn syscall3(
n: RegisterSize,
arg1: RegisterSize,
arg2: RegisterSize,
arg3: RegisterSize,
) -> Result<RegisterSize, i32> {
let mut err: RegisterSize;
let mut ret: RegisterSize;
n: usize,
arg1: usize,
arg2: usize,
arg3: usize,
) -> Result<usize, i32> {
let mut err: usize;
let mut ret: usize;
asm!(
"syscall",
inlateout("$2") n => ret,
Expand All @@ -97,7 +96,7 @@ pub(crate) unsafe fn syscall3(

let value = (err == 0).then_some(ret).unwrap_or_else(|| ret.wrapping_neg());

(value <= -4096isize as RegisterSize).then_some(value).ok_or_else(|| {
(value <= -4096isize as usize).then_some(value).ok_or_else(|| {
// Truncation of the error value is guaranteed to never occur due to
// the above check. This is the same check that musl uses:
// https://git.musl-libc.org/cgit/musl/tree/src/internal/syscall_ret.c?h=v1.1.15
Expand Down
24 changes: 12 additions & 12 deletions crates/common/src/io.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! This module contains the [ClientIO] struct, which is used to perform various IO operations
//! inside of the FPVM kernel within a `client` program.
use crate::{BasicKernelInterface, FileDescriptor, RegisterSize};
use crate::{BasicKernelInterface, FileDescriptor};
use anyhow::Result;
use cfg_if::cfg_if;

Expand Down Expand Up @@ -38,27 +38,27 @@ pub fn print_err(s: &str) {

/// Write the passed buffer to the given [FileDescriptor].
#[inline]
pub fn write(fd: FileDescriptor, buf: &[u8]) -> Result<RegisterSize> {
pub fn write(fd: FileDescriptor, buf: &[u8]) -> Result<usize> {
ClientIO::write(fd, buf)
}

/// Write the passed buffer to the given [FileDescriptor].
#[inline]
pub fn read(fd: FileDescriptor, buf: &mut [u8]) -> Result<RegisterSize> {
pub fn read(fd: FileDescriptor, buf: &mut [u8]) -> Result<usize> {
ClientIO::read(fd, buf)
}

/// Exit the process with the given exit code.
#[inline]
pub fn exit(code: RegisterSize) -> ! {
pub fn exit(code: usize) -> ! {
ClientIO::exit(code)
}

#[cfg(not(any(target_arch = "mips", target_arch = "riscv64")))]
mod native_io {
extern crate std;

use crate::{io::FileDescriptor, traits::BasicKernelInterface, types::RegisterSize};
use crate::{io::FileDescriptor, traits::BasicKernelInterface};
use anyhow::{anyhow, Result};
use std::{
fs::File,
Expand All @@ -71,8 +71,8 @@ mod native_io {
pub struct NativeIO;

impl BasicKernelInterface for NativeIO {
fn write(fd: FileDescriptor, buf: &[u8]) -> Result<RegisterSize> {
let raw_fd: RegisterSize = fd.into();
fn write(fd: FileDescriptor, buf: &[u8]) -> Result<usize> {
let raw_fd: usize = fd.into();
let mut file = unsafe { File::from_raw_fd(raw_fd as i32) };
let n = file
.write(buf)
Expand All @@ -85,22 +85,22 @@ mod native_io {
// forget the file descriptor so that the `Drop` impl doesn't close it.
std::mem::forget(file);

n.try_into().map_err(|_| anyhow!("Failed to convert usize to RegisterSize"))
Ok(n)
}

fn read(fd: FileDescriptor, buf: &mut [u8]) -> Result<RegisterSize> {
let raw_fd: RegisterSize = fd.into();
fn read(fd: FileDescriptor, buf: &mut [u8]) -> Result<usize> {
let raw_fd: usize = fd.into();
let mut file = unsafe { File::from_raw_fd(raw_fd as i32) };
let n =
file.read(buf).map_err(|e| anyhow!("Error reading from file descriptor: {e}"))?;

// forget the file descriptor so that the `Drop` impl doesn't close it.
std::mem::forget(file);

n.try_into().map_err(|_| anyhow!("Failed to convert usize to RegisterSize"))
Ok(n)
}

fn exit(code: RegisterSize) -> ! {
fn exit(code: usize) -> ! {
std::process::exit(code as i32)
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ mod traits;
pub use traits::BasicKernelInterface;

mod types;
pub use types::{FileDescriptor, RegisterSize};
pub use types::FileDescriptor;

mod executor;
pub use executor::block_on;
Expand Down
8 changes: 4 additions & 4 deletions crates/common/src/traits/basic.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Defines the [BasicKernelInterface] trait, which describes the functionality of several system
//! calls inside of the FPVM kernel.
use crate::{FileDescriptor, RegisterSize};
use crate::FileDescriptor;
use anyhow::Result;

/// The [BasicKernelInterface] trait describes the functionality of several core system calls inside
Expand All @@ -13,12 +13,12 @@ use anyhow::Result;
/// trait should be created that extends this trait.
pub trait BasicKernelInterface {
/// Write the given buffer to the given file descriptor.
fn write(fd: FileDescriptor, buf: &[u8]) -> Result<RegisterSize>;
fn write(fd: FileDescriptor, buf: &[u8]) -> Result<usize>;

/// Read from the given file descriptor into the passed buffer.
fn read(fd: FileDescriptor, buf: &mut [u8]) -> Result<RegisterSize>;
fn read(fd: FileDescriptor, buf: &mut [u8]) -> Result<usize>;

/// Exit the process with the given exit code. The implementation of this function
/// should always panic after invoking the `EXIT` syscall.
fn exit(code: RegisterSize) -> !;
fn exit(code: usize) -> !;
}
19 changes: 2 additions & 17 deletions crates/common/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,5 @@
//! This module contains the local types for the `kona-common` crate.
use cfg_if::cfg_if;

cfg_if! {
if #[cfg(target_arch = "mips")] {
/// The size of the `mips32` target architecture's registers.
pub type RegisterSize = u32;
} else if #[cfg(target_arch = "riscv64")] {
/// The size of the `riscv64` target architecture's registers.
pub type RegisterSize = u64;
} else {
/// The size of the native target architecture's registers.
pub type RegisterSize = u64;
}
}

/// File descriptors available to the `client` within the FPVM kernel.
#[derive(Debug, Clone, Copy)]
pub enum FileDescriptor {
Expand All @@ -33,10 +18,10 @@ pub enum FileDescriptor {
/// Write-only. Used to request pre-images.
PreimageWrite,
/// Other file descriptor, usually used for testing purposes.
Wildcard(RegisterSize),
Wildcard(usize),
}

impl From<FileDescriptor> for RegisterSize {
impl From<FileDescriptor> for usize {
fn from(fd: FileDescriptor) -> Self {
match fd {
FileDescriptor::StdIn => 0,
Expand Down
16 changes: 8 additions & 8 deletions crates/preimage/src/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//! for reading and writing from the file descriptors.
use anyhow::{bail, Result};
use kona_common::{io, FileDescriptor, RegisterSize};
use kona_common::{io, FileDescriptor};

/// [PipeHandle] is a handle for one end of a bidirectional pipe.
#[derive(Debug, Clone, Copy)]
Expand All @@ -20,33 +20,33 @@ impl PipeHandle {
}

/// Read from the pipe into the given buffer.
pub fn read(&self, buf: &mut [u8]) -> Result<RegisterSize> {
pub fn read(&self, buf: &mut [u8]) -> Result<usize> {
io::read(self.read_handle, buf)
}

/// Reads exactly `buf.len()` bytes into `buf`, blocking until all bytes are read.
pub fn read_exact(&self, buf: &mut [u8]) -> Result<RegisterSize> {
pub fn read_exact(&self, buf: &mut [u8]) -> Result<usize> {
let mut read = 0;
while read < buf.len() {
let chunk_read = self.read(&mut buf[read..])?;
read += chunk_read as usize;
read += chunk_read;
}
Ok(read as RegisterSize)
Ok(read)
}

/// Write the given buffer to the pipe.
pub fn write(&self, buf: &[u8]) -> Result<RegisterSize> {
pub fn write(&self, buf: &[u8]) -> Result<usize> {
let mut written = 0;
loop {
match io::write(self.write_handle, &buf[written..]) {
Ok(0) => break,
Ok(n) => {
written += n as usize;
written += n;
continue;
}
Err(e) => bail!("Failed to write preimage key: {}", e),
}
}
Ok(written as RegisterSize)
Ok(written)
}
}

0 comments on commit 2dba60b

Please sign in to comment.