diff --git a/crates/rune/src/runtime/bytes.rs b/crates/rune/src/runtime/bytes.rs index fe21308bf..c8322d905 100644 --- a/crates/rune/src/runtime/bytes.rs +++ b/crates/rune/src/runtime/bytes.rs @@ -13,7 +13,7 @@ use crate::alloc::prelude::*; use crate::alloc::{self, Box, Vec}; use crate::Any; -use super::{IntoOutput, RawAnyGuard, Ref, UnsafeToRef, Value, VmResult}; +use super::{IntoOutput, RawAnyGuard, Ref, RuntimeError, UnsafeToRef, Value, VmResult}; /// A vector of bytes. #[derive(Any, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -452,10 +452,8 @@ impl TryFrom<&[u8]> for Value { } impl IntoOutput for &[u8] { - type Output = Bytes; - #[inline] - fn into_output(self) -> VmResult { - VmResult::Ok(vm_try!(Bytes::try_from(self))) + fn into_output(self) -> Result { + Ok(Value::try_from(self)?) } } diff --git a/crates/rune/src/runtime/inst.rs b/crates/rune/src/runtime/inst.rs index 8eda20ea2..6a75ec6b9 100644 --- a/crates/rune/src/runtime/inst.rs +++ b/crates/rune/src/runtime/inst.rs @@ -1,6 +1,5 @@ use core::cmp::Ordering; use core::fmt; -use core::num::NonZeroUsize; use musli::{Decode, Encode}; use rune_macros::InstDisplay; @@ -8,9 +7,10 @@ use serde::{Deserialize, Serialize}; use crate as rune; use crate::alloc::prelude::*; -use crate::runtime::{Call, FormatSpec, Memory, Type, Value, VmError, VmResult}; use crate::Hash; +use super::{Call, FormatSpec, Memory, RuntimeError, Type, Value}; + /// Pre-canned panic reasons. /// /// To formulate a custom reason, use @@ -1123,19 +1123,6 @@ impl Inst { } } -/// The calling convention of a function. -#[derive( - Debug, TryClone, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Encode, Decode, -)] -#[try_clone(copy)] -#[non_exhaustive] -enum OutputKind { - /// Push the produced value onto the stack. - Keep(NonZeroUsize), - /// Discard the produced value, leaving the stack unchanged. - Discard, -} - /// What to do with the output of an instruction. #[derive(TryClone, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Encode, Decode)] #[try_clone(copy)] @@ -1143,36 +1130,30 @@ enum OutputKind { #[musli(transparent)] #[serde(transparent)] pub struct Output { - kind: OutputKind, + offset: usize, } impl Output { /// Construct a keep output kind. #[inline] - pub(crate) fn keep(index: usize) -> Self { - let Some(index) = NonZeroUsize::new(index ^ usize::MAX) else { - panic!("Index {index} is out of bounds") - }; - - Self { - kind: OutputKind::Keep(index), - } + pub(crate) fn keep(offset: usize) -> Self { + assert_ne!(offset, usize::MAX, "Address is invalid"); + Self { offset } } /// Construct a discard output kind. #[inline] pub(crate) fn discard() -> Self { - Self { - kind: OutputKind::Discard, - } + Self { offset: usize::MAX } } /// Check if the output is a keep. - #[inline] + #[inline(always)] pub(crate) fn as_addr(&self) -> Option { - match self.kind { - OutputKind::Keep(index) => Some(InstAddress::new(index.get() ^ usize::MAX)), - OutputKind::Discard => None, + if self.offset == usize::MAX { + None + } else { + Some(InstAddress::new(self.offset)) } } @@ -1200,25 +1181,26 @@ impl Output { /// out.store(stack, number); /// VmResult::Ok(()) /// } - #[inline] - pub fn store(self, stack: &mut dyn Memory, o: O) -> VmResult<()> + #[inline(always)] + pub fn store(self, stack: &mut M, o: O) -> Result<(), RuntimeError> where - O: IntoOutput>>, + M: ?Sized + Memory, + O: IntoOutput, { if let Some(addr) = self.as_addr() { - let value = vm_try!(o.into_output()); - *vm_try!(stack.at_mut(addr)) = vm_try!(value.try_into().map_err(Into::into)); + *stack.at_mut(addr)? = o.into_output()?; } - VmResult::Ok(()) + Ok(()) } } impl fmt::Display for Output { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.kind { - OutputKind::Keep(index) => write!(f, "keep({})", index.get() ^ usize::MAX), - OutputKind::Discard => write!(f, "discard"), + if self.offset == usize::MAX { + write!(f, "discard") + } else { + write!(f, "keep({})", self.offset) } } } @@ -1232,11 +1214,8 @@ impl fmt::Debug for Output { /// Trait used to coerce values into outputs. pub trait IntoOutput { - #[doc(hidden)] - type Output; - /// Coerce the current value into an output. - fn into_output(self) -> VmResult; + fn into_output(self) -> Result; } impl IntoOutput for F @@ -1244,41 +1223,27 @@ where F: FnOnce() -> O, O: IntoOutput, { - type Output = O::Output; - #[inline] - fn into_output(self) -> VmResult { + fn into_output(self) -> Result { self().into_output() } } impl IntoOutput for Result where - VmError: From, + T: IntoOutput, + RuntimeError: From, { - type Output = T; - #[inline] - fn into_output(self) -> VmResult { - VmResult::Ok(vm_try!(self)) - } -} - -impl IntoOutput for VmResult { - type Output = T; - - #[inline] - fn into_output(self) -> VmResult { - self + fn into_output(self) -> Result { + self?.into_output() } } impl IntoOutput for Value { - type Output = Value; - #[inline] - fn into_output(self) -> VmResult { - VmResult::Ok(self) + fn into_output(self) -> Result { + Ok(self) } } @@ -1840,10 +1805,8 @@ where } impl IntoOutput for &str { - type Output = String; - #[inline] - fn into_output(self) -> VmResult { - VmResult::Ok(vm_try!(String::try_from(self))) + fn into_output(self) -> Result { + Ok(Value::try_from(self)?) } } diff --git a/crates/rune/src/runtime/stack.rs b/crates/rune/src/runtime/stack.rs index 3675267c0..f2d0faa34 100644 --- a/crates/rune/src/runtime/stack.rs +++ b/crates/rune/src/runtime/stack.rs @@ -1,4 +1,5 @@ use core::array; +use core::convert::Infallible; use core::fmt; use core::mem::replace; use core::slice; @@ -16,6 +17,13 @@ pub struct StackError { addr: InstAddress, } +impl From for StackError { + #[inline] + fn from(value: Infallible) -> Self { + match value {} + } +} + impl fmt::Display for StackError { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/crates/rune/src/runtime/value.rs b/crates/rune/src/runtime/value.rs index af1065457..886a6daef 100644 --- a/crates/rune/src/runtime/value.rs +++ b/crates/rune/src/runtime/value.rs @@ -561,16 +561,16 @@ impl Value { } /// Construct an empty. - pub fn empty_struct(rtti: Arc) -> VmResult { - VmResult::Ok(Value::from(vm_try!(Dynamic::new(rtti, [])))) + pub fn empty_struct(rtti: Arc) -> alloc::Result { + Ok(Value::from(Dynamic::new(rtti, [])?)) } /// Construct a typed tuple. pub fn tuple_struct( rtti: Arc, data: impl IntoIterator, - ) -> VmResult { - VmResult::Ok(Value::from(vm_try!(Dynamic::new(rtti, data)))) + ) -> alloc::Result { + Ok(Value::from(Dynamic::new(rtti, data)?)) } /// Drop the interior value. @@ -1559,11 +1559,9 @@ impl From<()> for Value { } impl IntoOutput for () { - type Output = (); - #[inline] - fn into_output(self) -> VmResult { - VmResult::Ok(()) + fn into_output(self) -> Result { + Ok(Value::from(())) } } @@ -1586,11 +1584,9 @@ impl From for Value { } impl IntoOutput for Inline { - type Output = Inline; - #[inline] - fn into_output(self) -> VmResult { - VmResult::Ok(self) + fn into_output(self) -> Result { + Ok(Value::from(self)) } } diff --git a/crates/rune/src/runtime/value/dynamic.rs b/crates/rune/src/runtime/value/dynamic.rs index 9a99dcd2d..40c7aff3f 100644 --- a/crates/rune/src/runtime/value/dynamic.rs +++ b/crates/rune/src/runtime/value/dynamic.rs @@ -12,7 +12,7 @@ use crate::alloc::fmt::TryWrite; use crate::hash::Hash; use crate::runtime::{ Access, AccessError, BorrowMut, BorrowRef, Formatter, IntoOutput, ProtocolCaller, Rtti, - RttiKind, Snapshot, TypeInfo, Value, VmResult, + RttiKind, RuntimeError, Snapshot, TypeInfo, Value, VmResult, }; #[derive(Debug)] @@ -471,10 +471,8 @@ fn debug_struct( } impl IntoOutput for Dynamic, Value> { - type Output = Dynamic, Value>; - #[inline] - fn into_output(self) -> VmResult { - VmResult::Ok(self) + fn into_output(self) -> Result { + Ok(Value::from(self)) } } diff --git a/crates/rune/src/runtime/value/macros.rs b/crates/rune/src/runtime/value/macros.rs index 34c0d245a..28e263712 100644 --- a/crates/rune/src/runtime/value/macros.rs +++ b/crates/rune/src/runtime/value/macros.rs @@ -68,11 +68,9 @@ macro_rules! any_from { } impl IntoOutput for $ty { - type Output = $ty; - #[inline] - fn into_output(self) -> VmResult { - VmResult::Ok(self) + fn into_output(self) -> Result<$crate::runtime::Value, $crate::runtime::RuntimeError> { + Ok(Value::new(self)?) } } )* @@ -97,11 +95,9 @@ macro_rules! inline_from { } impl $crate::runtime::IntoOutput for $ty { - type Output = $ty; - #[inline] - fn into_output(self) -> $crate::runtime::VmResult { - $crate::runtime::VmResult::Ok(self) + fn into_output(self) -> Result<$crate::runtime::Value, $crate::runtime::RuntimeError> { + Ok($crate::runtime::Value::from(self)) } } diff --git a/crates/rune/src/runtime/vm.rs b/crates/rune/src/runtime/vm.rs index 1cbd1e715..5ababc828 100644 --- a/crates/rune/src/runtime/vm.rs +++ b/crates/rune/src/runtime/vm.rs @@ -2056,10 +2056,7 @@ impl Vm { .map(take) .try_collect::>()); - vm_try!(out.store(&mut self.stack, || VmResult::Ok(vm_try!( - OwnedTuple::try_from(tuple) - )))); - + vm_try!(out.store(&mut self.stack, || OwnedTuple::try_from(tuple))); VmResult::Ok(()) } @@ -2073,10 +2070,7 @@ impl Vm { vm_try!(tuple.try_push(value)); } - vm_try!(out.store(&mut self.stack, || VmResult::Ok(vm_try!( - OwnedTuple::try_from(tuple) - )))); - + vm_try!(out.store(&mut self.stack, || OwnedTuple::try_from(tuple))); VmResult::Ok(()) } @@ -2867,10 +2861,8 @@ impl Vm { .lookup_rtti(hash) .ok_or(VmErrorKind::MissingRtti { hash })); - vm_try!(out.store(&mut self.stack, || Dynamic::<_, Value>::new( - rtti.clone(), - [] - ))); + let value = vm_try!(Dynamic::<_, Value>::new(rtti.clone(), [])); + vm_try!(out.store(&mut self.stack, value)); VmResult::Ok(()) } diff --git a/crates/rune/src/runtime/vm_error.rs b/crates/rune/src/runtime/vm_error.rs index b37672a01..14727e951 100644 --- a/crates/rune/src/runtime/vm_error.rs +++ b/crates/rune/src/runtime/vm_error.rs @@ -593,6 +593,15 @@ impl From for RuntimeError { } } +impl From for RuntimeError { + #[inline] + fn from(error: StackError) -> Self { + Self { + error: VmErrorKind::from(error), + } + } +} + impl From for RuntimeError { #[inline] fn from(error: AccessErrorKind) -> Self {