Skip to content

Commit

Permalink
Moves StableResult and ProgramResult from vm.rs into error.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
Lichtso committed Oct 1, 2023
1 parent cf485c6 commit 07c09fa
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 106 deletions.
4 changes: 2 additions & 2 deletions src/debugger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ use gdbstub::target::ext::section_offsets::Offsets;

use crate::{
ebpf,
error::EbpfError,
error::{EbpfError, ProgramResult},
interpreter::{DebugState, Interpreter},
memory_region::AccessType,
vm::{ContextObject, ProgramResult},
vm::ContextObject,
};

type DynResult<T> = Result<T, Box<dyn std::error::Error>>;
Expand Down
3 changes: 2 additions & 1 deletion src/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1189,10 +1189,11 @@ mod test {
consts::{ELFCLASS32, ELFDATA2MSB, ET_REL},
types::{Elf64Ehdr, Elf64Shdr},
},
error::ProgramResult,
fuzz::fuzz,
program::BuiltinFunction,
syscalls,
vm::{ProgramResult, TestContextObject},
vm::TestContextObject,
};
use rand::{distributions::Uniform, Rng};
use std::{fs::File, io::Read};
Expand Down
93 changes: 93 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,96 @@ pub enum EbpfError {
#[error("Syscall error: {0}")]
SyscallError(Box<dyn Error>),
}

/// Same as `Result` but provides a stable memory layout
#[derive(Debug)]
#[repr(C, u64)]
pub enum StableResult<T, E> {
/// Success
Ok(T),
/// Failure
Err(E),
}

impl<T: std::fmt::Debug, E: std::fmt::Debug> StableResult<T, E> {
/// `true` if `Ok`
pub fn is_ok(&self) -> bool {
match self {
Self::Ok(_) => true,
Self::Err(_) => false,
}
}

/// `true` if `Err`
pub fn is_err(&self) -> bool {
match self {
Self::Ok(_) => false,
Self::Err(_) => true,
}
}

/// Returns the inner value if `Ok`, panics otherwise
pub fn unwrap(self) -> T {
match self {
Self::Ok(value) => value,
Self::Err(error) => panic!("unwrap {:?}", error),
}
}

/// Returns the inner error if `Err`, panics otherwise
pub fn unwrap_err(self) -> E {
match self {
Self::Ok(value) => panic!("unwrap_err {:?}", value),
Self::Err(error) => error,
}
}

/// Maps ok values, leaving error values untouched
pub fn map<U, O: FnOnce(T) -> U>(self, op: O) -> StableResult<U, E> {
match self {
Self::Ok(value) => StableResult::<U, E>::Ok(op(value)),
Self::Err(error) => StableResult::<U, E>::Err(error),
}
}

/// Maps error values, leaving ok values untouched
pub fn map_err<F, O: FnOnce(E) -> F>(self, op: O) -> StableResult<T, F> {
match self {
Self::Ok(value) => StableResult::<T, F>::Ok(value),
Self::Err(error) => StableResult::<T, F>::Err(op(error)),
}
}

#[cfg_attr(
any(
not(feature = "jit"),
target_os = "windows",
not(target_arch = "x86_64")
),
allow(dead_code)
)]
pub(crate) fn discriminant(&self) -> u64 {
unsafe { *(self as *const _ as *const u64) }
}
}

impl<T, E> From<StableResult<T, E>> for Result<T, E> {
fn from(result: StableResult<T, E>) -> Self {
match result {
StableResult::Ok(value) => Ok(value),
StableResult::Err(value) => Err(value),
}
}
}

impl<T, E> From<Result<T, E>> for StableResult<T, E> {
fn from(result: Result<T, E>) -> Self {
match result {
Ok(value) => Self::Ok(value),
Err(value) => Self::Err(value),
}
}
}

/// Return value of programs and syscalls
pub type ProgramResult = StableResult<u64, EbpfError>;
4 changes: 2 additions & 2 deletions src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
use crate::{
ebpf::{self, STACK_PTR_REG},
elf::Executable,
error::EbpfError,
vm::{get_runtime_environment_key, Config, ContextObject, EbpfVm, ProgramResult},
error::{EbpfError, ProgramResult},
vm::{get_runtime_environment_key, Config, ContextObject, EbpfVm},
};

/// Virtual memory operation helper.
Expand Down
4 changes: 2 additions & 2 deletions src/jit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ use std::{fmt::Debug, mem, ptr};
use crate::{
ebpf::{self, FIRST_SCRATCH_REG, FRAME_PTR_REG, INSN_SIZE, SCRATCH_REGS, STACK_PTR_REG},
elf::Executable,
error::EbpfError,
error::{EbpfError, ProgramResult},
memory_management::{
allocate_pages, free_pages, get_system_page_size, protect_pages, round_to_page_size,
},
memory_region::{AccessType, MemoryMapping},
vm::{get_runtime_environment_key, Config, ContextObject, EbpfVm, ProgramResult},
vm::{get_runtime_environment_key, Config, ContextObject, EbpfVm},
x86::*,
};

Expand Down
4 changes: 2 additions & 2 deletions src/memory_region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
use crate::{
aligned_memory::Pod,
ebpf,
error::EbpfError,
error::{EbpfError, ProgramResult},
program::SBPFVersion,
vm::{Config, ProgramResult},
vm::Config,
};
use std::{
array,
Expand Down
2 changes: 1 addition & 1 deletion src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ macro_rules! declare_builtin_function {
if config.enable_instruction_meter {
vm.context_object_pointer.consume(vm.previous_instruction_meter - vm.due_insn_count);
}
let converted_result: $crate::vm::ProgramResult = Self::rust(
let converted_result: $crate::error::ProgramResult = Self::rust(
vm.context_object_pointer, $arg_a, $arg_b, $arg_c, $arg_d, $arg_e, &mut vm.memory_mapping,
).into();
vm.program_result = converted_result;
Expand Down
95 changes: 1 addition & 94 deletions src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use crate::{
ebpf,
elf::Executable,
error::EbpfError,
error::{EbpfError, ProgramResult},
interpreter::Interpreter,
memory_region::MemoryMapping,
program::{BuiltinProgram, FunctionRegistry, SBPFVersion},
Expand All @@ -36,99 +36,6 @@ pub fn get_runtime_environment_key() -> i32 {
.get_or_init(|| rand::thread_rng().gen::<i32>() >> PROGRAM_ENVIRONMENT_KEY_SHIFT)
}

/// Same as `Result` but provides a stable memory layout
#[derive(Debug)]
#[repr(C, u64)]
pub enum StableResult<T, E> {
/// Success
Ok(T),
/// Failure
Err(E),
}

impl<T: Debug, E: Debug> StableResult<T, E> {
/// `true` if `Ok`
pub fn is_ok(&self) -> bool {
match self {
Self::Ok(_) => true,
Self::Err(_) => false,
}
}

/// `true` if `Err`
pub fn is_err(&self) -> bool {
match self {
Self::Ok(_) => false,
Self::Err(_) => true,
}
}

/// Returns the inner value if `Ok`, panics otherwise
pub fn unwrap(self) -> T {
match self {
Self::Ok(value) => value,
Self::Err(error) => panic!("unwrap {:?}", error),
}
}

/// Returns the inner error if `Err`, panics otherwise
pub fn unwrap_err(self) -> E {
match self {
Self::Ok(value) => panic!("unwrap_err {:?}", value),
Self::Err(error) => error,
}
}

/// Maps ok values, leaving error values untouched
pub fn map<U, O: FnOnce(T) -> U>(self, op: O) -> StableResult<U, E> {
match self {
Self::Ok(value) => StableResult::<U, E>::Ok(op(value)),
Self::Err(error) => StableResult::<U, E>::Err(error),
}
}

/// Maps error values, leaving ok values untouched
pub fn map_err<F, O: FnOnce(E) -> F>(self, op: O) -> StableResult<T, F> {
match self {
Self::Ok(value) => StableResult::<T, F>::Ok(value),
Self::Err(error) => StableResult::<T, F>::Err(op(error)),
}
}

#[cfg_attr(
any(
not(feature = "jit"),
target_os = "windows",
not(target_arch = "x86_64")
),
allow(dead_code)
)]
pub(crate) fn discriminant(&self) -> u64 {
unsafe { *(self as *const _ as *const u64) }
}
}

impl<T, E> From<StableResult<T, E>> for Result<T, E> {
fn from(result: StableResult<T, E>) -> Self {
match result {
StableResult::Ok(value) => Ok(value),
StableResult::Err(value) => Err(value),
}
}
}

impl<T, E> From<Result<T, E>> for StableResult<T, E> {
fn from(result: Result<T, E>) -> Self {
match result {
Ok(value) => Self::Ok(value),
Err(value) => Self::Err(value),
}
}
}

/// Return value of programs and syscalls
pub type ProgramResult = StableResult<u64, EbpfError>;

/// VM configuration settings
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Config {
Expand Down
4 changes: 2 additions & 2 deletions tests/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ use solana_rbpf::{
assembler::assemble,
declare_builtin_function, ebpf,
elf::Executable,
error::EbpfError,
error::{EbpfError, ProgramResult},
memory_region::{AccessType, MemoryMapping, MemoryRegion},
program::{BuiltinFunction, BuiltinProgram, FunctionRegistry, SBPFVersion},
static_analysis::Analysis,
syscalls,
verifier::RequisiteVerifier,
vm::{Config, ContextObject, ProgramResult, TestContextObject},
vm::{Config, ContextObject, TestContextObject},
};
use std::{fs::File, io::Read, sync::Arc};
use test_utils::{
Expand Down

0 comments on commit 07c09fa

Please sign in to comment.