Skip to content

Commit

Permalink
rune: More perf work
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Nov 3, 2024
1 parent 147741a commit 0a39551
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 111 deletions.
8 changes: 3 additions & 5 deletions crates/rune/src/runtime/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -452,10 +452,8 @@ impl TryFrom<&[u8]> for Value {
}

impl IntoOutput for &[u8] {
type Output = Bytes;

#[inline]
fn into_output(self) -> VmResult<Self::Output> {
VmResult::Ok(vm_try!(Bytes::try_from(self)))
fn into_output(self) -> Result<Value, RuntimeError> {
Ok(Value::try_from(self)?)
}
}
101 changes: 32 additions & 69 deletions crates/rune/src/runtime/inst.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use core::cmp::Ordering;
use core::fmt;
use core::num::NonZeroUsize;

use musli::{Decode, Encode};
use rune_macros::InstDisplay;
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
Expand Down Expand Up @@ -1123,56 +1123,37 @@ 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)]
#[non_exhaustive]
#[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<InstAddress> {
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))
}
}

Expand Down Expand Up @@ -1200,25 +1181,26 @@ impl Output {
/// out.store(stack, number);
/// VmResult::Ok(())
/// }
#[inline]
pub fn store<O>(self, stack: &mut dyn Memory, o: O) -> VmResult<()>
#[inline(always)]
pub fn store<M, O>(self, stack: &mut M, o: O) -> Result<(), RuntimeError>
where
O: IntoOutput<Output: TryInto<Value, Error: Into<VmError>>>,
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)
}
}
}
Expand All @@ -1232,53 +1214,36 @@ 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<Self::Output>;
fn into_output(self) -> Result<Value, RuntimeError>;
}

impl<F, O> IntoOutput for F
where
F: FnOnce() -> O,
O: IntoOutput,
{
type Output = O::Output;

#[inline]
fn into_output(self) -> VmResult<Self::Output> {
fn into_output(self) -> Result<Value, RuntimeError> {
self().into_output()
}
}

impl<T, E> IntoOutput for Result<T, E>
where
VmError: From<E>,
T: IntoOutput,
RuntimeError: From<E>,
{
type Output = T;

#[inline]
fn into_output(self) -> VmResult<Self::Output> {
VmResult::Ok(vm_try!(self))
}
}

impl<T> IntoOutput for VmResult<T> {
type Output = T;

#[inline]
fn into_output(self) -> VmResult<Self::Output> {
self
fn into_output(self) -> Result<Value, RuntimeError> {
self?.into_output()
}
}

impl IntoOutput for Value {
type Output = Value;

#[inline]
fn into_output(self) -> VmResult<Self::Output> {
VmResult::Ok(self)
fn into_output(self) -> Result<Value, RuntimeError> {
Ok(self)
}
}

Expand Down Expand Up @@ -1840,10 +1805,8 @@ where
}

impl IntoOutput for &str {
type Output = String;

#[inline]
fn into_output(self) -> VmResult<Self::Output> {
VmResult::Ok(vm_try!(String::try_from(self)))
fn into_output(self) -> Result<Value, RuntimeError> {
Ok(Value::try_from(self)?)
}
}
8 changes: 8 additions & 0 deletions crates/rune/src/runtime/stack.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use core::array;
use core::convert::Infallible;
use core::fmt;
use core::mem::replace;
use core::slice;
Expand All @@ -16,6 +17,13 @@ pub struct StackError {
addr: InstAddress,
}

impl From<Infallible> 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 {
Expand Down
20 changes: 8 additions & 12 deletions crates/rune/src/runtime/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,16 +561,16 @@ impl Value {
}

/// Construct an empty.
pub fn empty_struct(rtti: Arc<Rtti>) -> VmResult<Self> {
VmResult::Ok(Value::from(vm_try!(Dynamic::new(rtti, []))))
pub fn empty_struct(rtti: Arc<Rtti>) -> alloc::Result<Self> {
Ok(Value::from(Dynamic::new(rtti, [])?))
}

/// Construct a typed tuple.
pub fn tuple_struct(
rtti: Arc<Rtti>,
data: impl IntoIterator<IntoIter: ExactSizeIterator, Item = Value>,
) -> VmResult<Self> {
VmResult::Ok(Value::from(vm_try!(Dynamic::new(rtti, data))))
) -> alloc::Result<Self> {
Ok(Value::from(Dynamic::new(rtti, data)?))
}

/// Drop the interior value.
Expand Down Expand Up @@ -1559,11 +1559,9 @@ impl From<()> for Value {
}

impl IntoOutput for () {
type Output = ();

#[inline]
fn into_output(self) -> VmResult<Self::Output> {
VmResult::Ok(())
fn into_output(self) -> Result<Value, RuntimeError> {
Ok(Value::from(()))
}
}

Expand All @@ -1586,11 +1584,9 @@ impl From<AnyObj> for Value {
}

impl IntoOutput for Inline {
type Output = Inline;

#[inline]
fn into_output(self) -> VmResult<Self::Output> {
VmResult::Ok(self)
fn into_output(self) -> Result<Value, RuntimeError> {
Ok(Value::from(self))
}
}

Expand Down
8 changes: 3 additions & 5 deletions crates/rune/src/runtime/value/dynamic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -471,10 +471,8 @@ fn debug_struct(
}

impl IntoOutput for Dynamic<Arc<Rtti>, Value> {
type Output = Dynamic<Arc<Rtti>, Value>;

#[inline]
fn into_output(self) -> VmResult<Self::Output> {
VmResult::Ok(self)
fn into_output(self) -> Result<Value, RuntimeError> {
Ok(Value::from(self))
}
}
12 changes: 4 additions & 8 deletions crates/rune/src/runtime/value/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,9 @@ macro_rules! any_from {
}

impl IntoOutput for $ty {
type Output = $ty;

#[inline]
fn into_output(self) -> VmResult<Self::Output> {
VmResult::Ok(self)
fn into_output(self) -> Result<$crate::runtime::Value, $crate::runtime::RuntimeError> {
Ok(Value::new(self)?)
}
}
)*
Expand All @@ -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<Self::Output> {
$crate::runtime::VmResult::Ok(self)
fn into_output(self) -> Result<$crate::runtime::Value, $crate::runtime::RuntimeError> {
Ok($crate::runtime::Value::from(self))
}
}

Expand Down
16 changes: 4 additions & 12 deletions crates/rune/src/runtime/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2056,10 +2056,7 @@ impl Vm {
.map(take)
.try_collect::<alloc::Vec<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(())
}

Expand All @@ -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(())
}

Expand Down Expand Up @@ -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(())
}

Expand Down
9 changes: 9 additions & 0 deletions crates/rune/src/runtime/vm_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,15 @@ impl From<AccessError> for RuntimeError {
}
}

impl From<StackError> for RuntimeError {
#[inline]
fn from(error: StackError) -> Self {
Self {
error: VmErrorKind::from(error),
}
}
}

impl From<AccessErrorKind> for RuntimeError {
#[inline]
fn from(error: AccessErrorKind) -> Self {
Expand Down

0 comments on commit 0a39551

Please sign in to comment.