diff --git a/crates/rune-alloc/Cargo.toml b/crates/rune-alloc/Cargo.toml index a73cd184b..6fb42df7b 100644 --- a/crates/rune-alloc/Cargo.toml +++ b/crates/rune-alloc/Cargo.toml @@ -21,6 +21,7 @@ alloc = [] [dependencies] serde = { version = "1.0", optional = true } ahash = { version = "0.8.3", default-features = false } +pin-project = "1.1.0" [dev-dependencies] rand = { version = "0.8.5", features = ["small_rng"] } diff --git a/crates/rune-alloc/src/alloc/allocator.rs b/crates/rune-alloc/src/alloc/allocator.rs index c215e45c8..114b9f756 100644 --- a/crates/rune-alloc/src/alloc/allocator.rs +++ b/crates/rune-alloc/src/alloc/allocator.rs @@ -3,9 +3,7 @@ use core::alloc::Layout; use core::fmt; -use crate::ptr::{self, invalid_mut, NonNull}; - -use ::rust_alloc::alloc::{alloc, alloc_zeroed, dealloc}; +use crate::ptr::{self, NonNull}; /// Error raised while allocating. #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -299,8 +297,7 @@ where #[inline] unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { - // SAFETY: the safety contract must be upheld by the caller - unsafe { (**self).deallocate(ptr, layout) } + (**self).deallocate(ptr, layout) } #[inline] @@ -310,8 +307,7 @@ where old_layout: Layout, new_layout: Layout, ) -> Result, AllocError> { - // SAFETY: the safety contract must be upheld by the caller - unsafe { (**self).grow(ptr, old_layout, new_layout) } + (**self).grow(ptr, old_layout, new_layout) } #[inline] @@ -321,63 +317,6 @@ where old_layout: Layout, new_layout: Layout, ) -> Result, AllocError> { - // SAFETY: the safety contract must be upheld by the caller - unsafe { (**self).shrink(ptr, old_layout, new_layout) } - } -} - -/// The default global allocator. -#[derive(Default, Debug, Clone)] -pub struct Global; - -impl Global { - #[inline] - fn alloc_impl(&self, layout: Layout, zeroed: bool) -> Result, AllocError> { - /// Creates a `NonNull` that is dangling, but well-aligned for this Layout. - /// - /// Note that the pointer value may potentially represent a valid pointer, which - /// means this must not be used as a "not yet initialized" sentinel value. Types - /// that lazily allocate must track initialization by some other means. - pub(crate) const fn dangling(layout: &Layout) -> NonNull { - unsafe { NonNull::new_unchecked(invalid_mut::(layout.align())) } - } - - match layout.size() { - 0 => Ok(NonNull::slice_from_raw_parts(dangling(&layout), 0)), - // SAFETY: `layout` is non-zero in size, - size => unsafe { - let raw_ptr = if zeroed { - alloc_zeroed(layout) - } else { - alloc(layout) - }; - - let Some(ptr) = NonNull::new(raw_ptr) else { - return Err(AllocError { layout }); - }; - - Ok(NonNull::slice_from_raw_parts(ptr, size)) - }, - } - } -} - -unsafe impl Allocator for Global { - #[inline] - fn allocate(&self, layout: Layout) -> Result, AllocError> { - self.alloc_impl(layout, false) - } - - #[inline] - fn allocate_zeroed(&self, layout: Layout) -> Result, AllocError> { - self.alloc_impl(layout, true) - } - - unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { - if layout.size() != 0 { - // SAFETY: `layout` is non-zero in size, - // other conditions must be upheld by the caller - unsafe { dealloc(ptr.as_ptr(), layout) } - } + (**self).shrink(ptr, old_layout, new_layout) } } diff --git a/crates/rune-alloc/src/alloc/boxed.rs b/crates/rune-alloc/src/alloc/boxed.rs index 1d1b55239..87c9a0ff7 100644 --- a/crates/rune-alloc/src/alloc/boxed.rs +++ b/crates/rune-alloc/src/alloc/boxed.rs @@ -32,10 +32,10 @@ impl Box { /// ``` /// use rune_alloc::Box; /// - /// let five = Box::new(5)?; + /// let five = Box::try_new(5)?; /// # Ok::<_, rune_alloc::AllocError>(()) /// ``` - pub fn new(value: T) -> Result { + pub fn try_new(value: T) -> Result { Self::try_new_in(value, Global) } } @@ -148,7 +148,7 @@ impl Box { /// # fn main() -> Result<(), rune_alloc::Error> { /// use rune_alloc::Box; /// - /// let x = Box::new(41)?; + /// let x = Box::try_new(41)?; /// let static_ref: &'static mut usize = Box::leak(x); /// *static_ref += 1; /// assert_eq!(*static_ref, 42); diff --git a/crates/rune-alloc/src/alloc/global.rs b/crates/rune-alloc/src/alloc/global.rs new file mode 100644 index 000000000..244ca40a1 --- /dev/null +++ b/crates/rune-alloc/src/alloc/global.rs @@ -0,0 +1,72 @@ +use core::alloc::Layout; + +use crate::alloc::{AllocError, Allocator}; +use crate::ptr::{invalid_mut, NonNull}; + +use ::rust_alloc::alloc::{alloc, alloc_zeroed, dealloc}; + +/// Creates a `NonNull` that is dangling, but well-aligned for this Layout. +/// +/// Note that the pointer value may potentially represent a valid pointer, which +/// means this must not be used as a "not yet initialized" sentinel value. Types +/// that lazily allocate must track initialization by some other means. +pub(crate) const fn dangling(layout: &Layout) -> NonNull { + unsafe { NonNull::new_unchecked(invalid_mut::(layout.align())) } +} + +/// The default global allocator for Rune. +/// +/// This supports enforcing thread-local memory limits through the [`limit`] +/// module. +/// +/// [`limit`]: crate::limit +#[derive(Default, Debug, Clone, Copy)] +pub struct Global; + +impl Global { + #[inline] + fn alloc_impl(&self, layout: Layout, zeroed: bool) -> Result, AllocError> { + if !crate::limit::take(layout.size()) { + return Err(AllocError { layout }); + } + + match layout.size() { + 0 => Ok(NonNull::slice_from_raw_parts(dangling(&layout), 0)), + // SAFETY: `layout` is non-zero in size, + size => unsafe { + let raw_ptr = if zeroed { + alloc_zeroed(layout) + } else { + alloc(layout) + }; + + let Some(ptr) = NonNull::new(raw_ptr) else { + return Err(AllocError { layout }); + }; + + Ok(NonNull::slice_from_raw_parts(ptr, size)) + }, + } + } +} + +unsafe impl Allocator for Global { + #[inline] + fn allocate(&self, layout: Layout) -> Result, AllocError> { + self.alloc_impl(layout, false) + } + + #[inline] + fn allocate_zeroed(&self, layout: Layout) -> Result, AllocError> { + self.alloc_impl(layout, true) + } + + unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { + if layout.size() != 0 { + // SAFETY: `layout` is non-zero in size, + // other conditions must be upheld by the caller + dealloc(ptr.as_ptr(), layout); + crate::limit::release(layout.size()); + } + } +} diff --git a/crates/rune-alloc/src/alloc/mod.rs b/crates/rune-alloc/src/alloc/mod.rs index c52f6e6fb..53cba273e 100644 --- a/crates/rune-alloc/src/alloc/mod.rs +++ b/crates/rune-alloc/src/alloc/mod.rs @@ -5,9 +5,12 @@ pub(crate) mod raw_vec; pub use self::borrow::TryToOwned; pub(crate) mod borrow; -pub use self::allocator::{AllocError, Allocator, Global}; +pub use self::allocator::{AllocError, Allocator}; pub(crate) mod allocator; +pub use self::global::Global; +pub(crate) mod global; + pub use self::boxed::Box; pub mod boxed; diff --git a/crates/rune-alloc/src/alloc/slice.rs b/crates/rune-alloc/src/alloc/slice.rs index ab18e8dd2..ae58e71db 100644 --- a/crates/rune-alloc/src/alloc/slice.rs +++ b/crates/rune-alloc/src/alloc/slice.rs @@ -4,17 +4,8 @@ use crate::alloc::{Allocator, Box, Error, Global, TryClone, TryToOwned, Vec}; /// /// The resulting vector can be converted back into a box via /// `Vec`'s `into_boxed_slice` method. -/// -/// # Examples -/// -/// ``` -/// let s: Box<[i32]> = Box::new([10, 40, 30]); -/// let x = s.into_vec(); -/// // `s` cannot be used anymore because it has been converted into `x`. -/// -/// assert_eq!(x, vec![10, 40, 30]); -/// ``` #[inline] +#[doc(hidden)] pub fn into_vec(this: Box<[T], A>) -> Vec { // N.B., see the `hack` module in this file for more details. hack::into_vec(this) diff --git a/crates/rune-alloc/src/alloc/string.rs b/crates/rune-alloc/src/alloc/string.rs index 536ff45b0..866babb44 100644 --- a/crates/rune-alloc/src/alloc/string.rs +++ b/crates/rune-alloc/src/alloc/string.rs @@ -1736,7 +1736,7 @@ impl FromUtf8Error { } } -impl Borrow for String { +impl Borrow for String { #[inline] fn borrow(&self) -> &str { &self[..] diff --git a/crates/rune-alloc/src/alloc/vec/mod.rs b/crates/rune-alloc/src/alloc/vec/mod.rs index d91eddfd3..0c59636f8 100644 --- a/crates/rune-alloc/src/alloc/vec/mod.rs +++ b/crates/rune-alloc/src/alloc/vec/mod.rs @@ -84,6 +84,7 @@ use self::is_zero::IsZero; #[cfg(rune_nightly)] mod is_zero; +#[doc(hidden)] pub use crate::alloc::slice::into_vec; use core::borrow::Borrow; @@ -2899,16 +2900,24 @@ impl TryFrom> for [T; N] { } impl From> for Vec { - /// Convert a boxed slice into a vector by transferring ownership of - /// the existing heap allocation. + /// Convert a boxed slice into a vector by transferring ownership of the + /// existing heap allocation. /// /// # Examples /// /// ``` - /// use rune_alloc::{Vec, Box}; + /// use rune_alloc::{Box, Vec}; + /// use rune_alloc::try_vec; + /// + /// let s: Box<[i32]> = Box::try_from([10, 40, 30])?; + /// let x: Vec = Vec::from(s); + /// + /// assert_eq!(x, [10, 40, 30]); + /// + /// let s: Box<[i32]> = try_vec![10, 40, 30].try_into_boxed_slice()?; + /// let x: Vec = Vec::from(s); /// - /// let b: Box<[i32]> = rune_alloc::try_vec![1, 2, 3].try_into_boxed_slice()?; - /// assert_eq!(Vec::from(b), rune_alloc::try_vec![1, 2, 3]); + /// assert_eq!(x, [10, 40, 30]); /// # Ok::<_, rune_alloc::Error>(()) /// ``` fn from(s: Box<[T], A>) -> Self { diff --git a/crates/rune-alloc/src/lib.rs b/crates/rune-alloc/src/lib.rs index 7eb8061bf..10849591b 100644 --- a/crates/rune-alloc/src/lib.rs +++ b/crates/rune-alloc/src/lib.rs @@ -94,6 +94,8 @@ pub mod prelude { }; } +pub mod limit; + #[cfg(test)] mod testing; diff --git a/crates/rune-alloc/src/limit.rs b/crates/rune-alloc/src/limit.rs new file mode 100644 index 000000000..ae33f26dd --- /dev/null +++ b/crates/rune-alloc/src/limit.rs @@ -0,0 +1,121 @@ +//! Memory limits for Rune. +//! +//! This module contains methods which allows for limiting the memory use of the +//! virtual machine to abide by the specified budget. +//! +//! By default memory limits are disabled, but can be enabled by wrapping your +//! function call or future in [with]. + +#[cfg_attr(feature = "std", path = "limit/std.rs")] +mod no_std; + +use core::future::Future; +use core::pin::Pin; +use core::task::{Context, Poll}; + +use pin_project::pin_project; + +/// Something being budgeted. +#[pin_project] +pub struct Memory { + /// The current budget. + budget: usize, + /// The thing being budgeted. + #[pin] + value: T, +} + +/// Wrap the given value with a memory limit. +/// +/// # Examples +/// +/// ``` +/// use rune_alloc::limit; +/// use rune_alloc::Vec; +/// +/// let f = limit::with(1024, || { +/// let mut vec = Vec::::try_with_capacity(256)?; +/// +/// for n in 0..256u32 { +/// vec.try_push(n)?; +/// } +/// +/// Ok::<_, rune_alloc::Error>(vec.into_iter().sum::()) +/// }); +/// +/// let sum = f.call()?; +/// assert_eq!(sum, 32640); +/// # Ok::<_, rune_alloc::Error>(()) +/// ``` +/// +/// Overloading the limit. Note that this happens because while the vector is +/// growing it might both over-allocate, and hold onto two allocations +/// simultaneously. +/// +/// ``` +/// use rune_alloc::limit; +/// use rune_alloc::Vec; +/// +/// let f = limit::with(1024, || { +/// let mut vec = Vec::::new(); +/// +/// for n in 0..256u32 { +/// vec.try_push(n)?; +/// } +/// +/// Ok::<_, rune_alloc::Error>(vec.into_iter().sum::()) +/// }); +/// +/// assert!(f.call().is_err()); +/// ``` +pub fn with(budget: usize, value: T) -> Memory { + Memory { budget, value } +} + +/// Take memory from the current budget. +#[inline(never)] +pub(crate) fn take(amount: usize) -> bool { + self::no_std::rune_memory_take(amount) +} + +/// Release memory from the current budget. +#[inline(never)] +pub(crate) fn release(amount: usize) { + self::no_std::rune_memory_release(amount); +} + +#[repr(transparent)] +struct MemoryGuard(usize); + +impl Drop for MemoryGuard { + fn drop(&mut self) { + let _ = self::no_std::rune_memory_replace(self.0); + } +} + +impl Memory +where + T: FnOnce() -> O, +{ + /// Call the wrapped function. + pub fn call(self) -> O { + let _guard = MemoryGuard(self::no_std::rune_memory_replace(self.budget)); + (self.value)() + } +} + +impl Future for Memory +where + T: Future, +{ + type Output = T::Output; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = self.project(); + + let _guard = MemoryGuard(self::no_std::rune_memory_replace(*this.budget)); + let poll = this.value.poll(cx); + *this.budget = self::no_std::rune_memory_get(); + poll + } +} diff --git a/crates/rune-alloc/src/limit/no_std.rs b/crates/rune-alloc/src/limit/no_std.rs new file mode 100644 index 000000000..03c2c6e7a --- /dev/null +++ b/crates/rune-alloc/src/limit/no_std.rs @@ -0,0 +1,47 @@ +// In no-std environments, the implementor must define these functions. +// +// Normally these make use of thread-local storage, but if you want them to be +// completed disabled simply return dummy values or store it in static storage +// (if single threaded). +extern "C" { + /// Take the given amount of memory from the current budget. Return `false` + /// if the budget has been breached, or `true` otherwise. + /// + /// If this is called before `rune_memory_set` then it should usually just + /// return `true`. + pub(super) fn __rune_alloc_memory_take(amount: usize) -> bool; + + /// Release the given amount of memory to the current budget. + pub(super) fn __rune_alloc_memory_release(amount: usize); + + /// Get the remaining memory budget for the current thread. + pub(super) fn __rune_alloc_memory_get() -> usize; + + /// Replace the memory budget for the current thread and return the one + /// which was previously set. + pub(super) fn __rune_alloc_memory_replace(value: usize) -> usize; +} + +pub(super) fn rune_memory_take(amount: usize) -> bool { + // SAFETY: implementor is expected to have read the documentation and + // implemented this correctly. + unsafe { __rune_alloc_memory_take(amount) } +} + +pub(super) fn rune_memory_release(amount: usize) -> bool { + // SAFETY: implementor is expected to have read the documentation and + // implemented this correctly. + unsafe { __rune_alloc_memory_release(amount) } +} + +pub(super) fn rune_memory_get() -> usize { + // SAFETY: implementor is expected to have read the documentation and + // implemented this correctly. + unsafe { __rune_alloc_memory_get() } +} + +pub(super) fn rune_memory_replace(value: usize) -> usize { + // SAFETY: implementor is expected to have read the documentation and + // implemented this correctly. + unsafe { __rune_alloc_memory_replace(value) } +} diff --git a/crates/rune-alloc/src/limit/std.rs b/crates/rune-alloc/src/limit/std.rs new file mode 100644 index 000000000..90eea7248 --- /dev/null +++ b/crates/rune-alloc/src/limit/std.rs @@ -0,0 +1,33 @@ +use core::cell::Cell; + +::rust_std::thread_local!(static MEMORY: Cell = Cell::new(usize::max_value())); + +pub(super) fn rune_memory_take(amount: usize) -> bool { + MEMORY.with(|tls| { + let v = tls.get(); + + if v == usize::max_value() { + true + } else if v >= amount { + tls.set(v - amount); + true + } else { + tls.set(0); + false + } + }) +} + +pub(super) fn rune_memory_release(amount: usize) { + MEMORY.with(|tls| { + tls.set(tls.get().saturating_add(amount)); + }) +} + +pub(super) fn rune_memory_get() -> usize { + MEMORY.with(|tls| tls.get()) +} + +pub(super) fn rune_memory_replace(value: usize) -> usize { + MEMORY.with(|tls| tls.replace(value)) +} diff --git a/crates/rune/src/hashbrown/table.rs b/crates/rune/src/hashbrown/table.rs index 744e2229f..a98c007ba 100644 --- a/crates/rune/src/hashbrown/table.rs +++ b/crates/rune/src/hashbrown/table.rs @@ -6,7 +6,7 @@ use core::marker::PhantomData; use core::mem; use core::ptr; -use crate::alloc::{Allocator, Error, Global, TryClone}; +use crate::alloc::{Error, TryClone}; #[cfg(feature = "alloc")] use crate::runtime::Hasher; @@ -15,24 +15,24 @@ use crate::runtime::{ProtocolCaller, RawRef, Ref, Value, VmError, VmResult}; use crate::alloc::hashbrown::raw::{RawIter, RawTable}; use crate::alloc::hashbrown::ErrorOrInsertSlot; -pub(crate) struct Table { - table: RawTable<(Value, V), A>, +pub(crate) struct Table { + table: RawTable<(Value, V)>, state: hash_map::RandomState, } -impl Table { +impl Table { #[inline(always)] - pub(crate) fn new_in(alloc: A) -> Self { + pub(crate) fn new() -> Self { Self { - table: RawTable::new_in(alloc), + table: RawTable::new(), state: hash_map::RandomState::new(), } } #[inline(always)] - pub(crate) fn try_with_capacity_in(capacity: usize, alloc: A) -> Result { + pub(crate) fn try_with_capacity(capacity: usize) -> Result { Ok(Self { - table: RawTable::try_with_capacity_in(capacity, alloc)?, + table: RawTable::try_with_capacity(capacity)?, state: hash_map::RandomState::new(), }) } @@ -155,7 +155,7 @@ impl Table { } } -impl TryClone for Table +impl TryClone for Table where V: TryClone, { diff --git a/crates/rune/src/modules/collections/hash_map.rs b/crates/rune/src/modules/collections/hash_map.rs index 0f800d805..4a247d745 100644 --- a/crates/rune/src/modules/collections/hash_map.rs +++ b/crates/rune/src/modules/collections/hash_map.rs @@ -1,6 +1,6 @@ use crate as rune; use crate::alloc::fmt::TryWrite; -use crate::alloc::{Global, TryClone}; +use crate::alloc::TryClone; use crate::hashbrown::Table; use crate::runtime::{ EnvProtocolCaller, Formatter, FromValue, Iterator, ProtocolCaller, Ref, Value, VmErrorKind, @@ -56,7 +56,7 @@ impl HashMap { #[rune::function(keep, path = Self::new)] fn new() -> Self { Self { - table: Table::new_in(Global), + table: Table::new(), } } @@ -75,7 +75,7 @@ impl HashMap { #[rune::function(keep, path = Self::with_capacity)] fn with_capacity(capacity: usize) -> VmResult { VmResult::Ok(Self { - table: vm_try!(Table::try_with_capacity_in(capacity, Global)), + table: vm_try!(Table::try_with_capacity(capacity)), }) } diff --git a/crates/rune/src/modules/collections/hash_set.rs b/crates/rune/src/modules/collections/hash_set.rs index eefcc871a..6359a3e4c 100644 --- a/crates/rune/src/modules/collections/hash_set.rs +++ b/crates/rune/src/modules/collections/hash_set.rs @@ -5,7 +5,7 @@ use core::ptr; use crate as rune; use crate::alloc::hashbrown::raw::RawIter; -use crate::alloc::{Global, TryClone}; +use crate::alloc::TryClone; use crate::hashbrown::{IterRef, Table}; use crate::runtime::{ EnvProtocolCaller, Formatter, Iterator, ProtocolCaller, RawRef, Ref, Value, VmResult, @@ -59,7 +59,7 @@ impl HashSet { #[rune::function(keep, path = Self::new)] fn new() -> Self { Self { - table: Table::new_in(Global), + table: Table::new(), } } @@ -80,7 +80,7 @@ impl HashSet { #[rune::function(keep, path = Self::with_capacity)] fn with_capacity(capacity: usize) -> VmResult { VmResult::Ok(Self { - table: vm_try!(Table::try_with_capacity_in(capacity, Global)), + table: vm_try!(Table::try_with_capacity(capacity)), }) } @@ -303,8 +303,8 @@ impl HashSet { // use longest as lead and then append any missing that are in second let iter = if this.as_ref().len() >= other.as_ref().len() { - let this_iter = Table::<_, Global>::iter_ref_raw(this); - let other_iter = Table::<_, Global>::iter_ref_raw(other); + let this_iter = Table::iter_ref_raw(this); + let other_iter = Table::iter_ref_raw(other); Union { this, @@ -313,8 +313,8 @@ impl HashSet { _guards: (this_guard, other_guard), } } else { - let this_iter = Table::<_, Global>::iter_ref_raw(other); - let other_iter = Table::<_, Global>::iter_ref_raw(this); + let this_iter = Table::iter_ref_raw(other); + let other_iter = Table::iter_ref_raw(this); Union { this: other, @@ -424,7 +424,7 @@ impl HashSet { where P: ?Sized + ProtocolCaller, { - let mut set = vm_try!(Table::try_with_capacity_in(it.size_hint().0, Global)); + let mut set = vm_try!(Table::try_with_capacity(it.size_hint().0)); while let Some(key) = vm_try!(it.next()) { vm_try!(set.insert_with(key, (), caller)); diff --git a/crates/rune/src/modules/collections/vec_deque.rs b/crates/rune/src/modules/collections/vec_deque.rs index 2e8f93ae0..f45e07728 100644 --- a/crates/rune/src/modules/collections/vec_deque.rs +++ b/crates/rune/src/modules/collections/vec_deque.rs @@ -3,7 +3,7 @@ use core::iter; use crate as rune; use crate::alloc::fmt::TryWrite; -use crate::alloc::{self, Error, Global, TryClone}; +use crate::alloc::{self, Error, TryClone}; use crate::runtime::{ EnvProtocolCaller, Formatter, Iterator, Protocol, ProtocolCaller, RawRef, Ref, Value, VmErrorKind, VmResult, @@ -100,7 +100,7 @@ impl VecDeque { #[rune::function(path = Self::with_capacity)] fn with_capacity(count: usize) -> VmResult { VmResult::Ok(Self { - inner: vm_try!(alloc::VecDeque::try_with_capacity_in(count, Global)), + inner: vm_try!(alloc::VecDeque::try_with_capacity(count)), }) } @@ -503,10 +503,7 @@ impl VecDeque { } pub(crate) fn from_iter(mut it: Iterator) -> VmResult { - let mut inner = vm_try!(alloc::VecDeque::try_with_capacity_in( - it.size_hint().0, - Global - )); + let mut inner = vm_try!(alloc::VecDeque::try_with_capacity(it.size_hint().0,)); while let Some(value) = vm_try!(it.next()) { vm_try!(inner.try_push_back(value)); diff --git a/crates/rune/src/runtime/fmt.rs b/crates/rune/src/runtime/fmt.rs index 37de8968d..24a570c25 100644 --- a/crates/rune/src/runtime/fmt.rs +++ b/crates/rune/src/runtime/fmt.rs @@ -1,7 +1,7 @@ use crate as rune; use crate::alloc::fmt::TryWrite; -use crate::alloc::{Error, Global, String}; +use crate::alloc::{Error, String}; use crate::Any; /// A formatter for the rune virtual machine. @@ -14,8 +14,8 @@ use crate::Any; #[derive(Any)] #[rune(item = ::std::fmt)] pub struct Formatter { - pub(crate) string: String, - pub(crate) buf: String, + pub(crate) string: String, + pub(crate) buf: String, } impl Formatter { @@ -31,26 +31,26 @@ impl Formatter { #[inline] pub fn new() -> Self { Self { - string: String::new_in(Global), - buf: String::new_in(Global), + string: String::new(), + buf: String::new(), } } #[inline] pub(crate) fn with_capacity(capacity: usize) -> Result { Ok(Self { - string: String::try_with_capacity_in(capacity, Global)?, - buf: String::new_in(Global), + string: String::try_with_capacity(capacity)?, + buf: String::new(), }) } #[inline] - pub(crate) fn parts_mut(&mut self) -> (&mut String, &str) { + pub(crate) fn parts_mut(&mut self) -> (&mut String, &str) { (&mut self.string, &self.buf) } #[inline] - pub(crate) fn buf_mut(&mut self) -> &mut String { + pub(crate) fn buf_mut(&mut self) -> &mut String { &mut self.buf } @@ -65,7 +65,7 @@ impl Formatter { } #[inline] - pub(crate) fn into_string(self) -> String { + pub(crate) fn into_string(self) -> String { self.string } diff --git a/crates/rune/src/runtime/format.rs b/crates/rune/src/runtime/format.rs index bc73ae6c3..157eb3954 100644 --- a/crates/rune/src/runtime/format.rs +++ b/crates/rune/src/runtime/format.rs @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize}; use crate as rune; use crate::alloc::fmt::TryWrite; -use crate::alloc::{Global, String}; +use crate::alloc::String; use crate::runtime::{Formatter, ProtocolCaller, Value, VmErrorKind, VmResult}; use crate::Any; @@ -119,14 +119,14 @@ impl FormatSpec { } /// Format the given number. - fn format_number(&self, buf: &mut String, n: i64) -> VmResult<()> { + fn format_number(&self, buf: &mut String, n: i64) -> VmResult<()> { let mut buffer = itoa::Buffer::new(); vm_try!(buf.try_push_str(buffer.format(n))); VmResult::Ok(()) } /// Format the given float. - fn format_float(&self, buf: &mut String, n: f64) -> VmResult<()> { + fn format_float(&self, buf: &mut String, n: f64) -> VmResult<()> { if let Some(precision) = self.precision { vm_write!(buf, "{:.*}", precision.get(), n); } else { diff --git a/crates/rune/src/runtime/iterator.rs b/crates/rune/src/runtime/iterator.rs index bb7c81f23..b726064dd 100644 --- a/crates/rune/src/runtime/iterator.rs +++ b/crates/rune/src/runtime/iterator.rs @@ -5,7 +5,7 @@ use core::iter; use crate::no_std::prelude::*; use crate as rune; -use crate::alloc::{self, Global}; +use crate::alloc; use crate::runtime::{FromValue, Function, Panic, ToValue, Value, VmErrorKind, VmResult}; use crate::Any; @@ -292,7 +292,7 @@ impl Iterator { T: FromValue, { let (cap, _) = self.iter.size_hint(); - let mut vec = vm_try!(alloc::Vec::try_with_capacity_in(cap, Global)); + let mut vec = vm_try!(alloc::Vec::try_with_capacity(cap)); while let Some(value) = vm_try!(self.next()) { vm_try!(vec.try_push(vm_try!(T::from_value(value)))); diff --git a/crates/rune/src/runtime/object.rs b/crates/rune/src/runtime/object.rs index 32949d6a7..0a2146542 100644 --- a/crates/rune/src/runtime/object.rs +++ b/crates/rune/src/runtime/object.rs @@ -6,7 +6,7 @@ use core::hash; use core::iter; use crate::alloc::{btree_map, BTreeMap}; -use crate::alloc::{Error, Global, String, TryClone}; +use crate::alloc::{Error, String, TryClone}; use crate as rune; use crate::compile::ItemBuf; @@ -81,7 +81,7 @@ pub type Values<'a> = btree_map::Values<'a, String, Value>; #[repr(transparent)] #[rune(builtin, static_type = OBJECT_TYPE)] pub struct Object { - inner: BTreeMap, + inner: BTreeMap, } impl Object { @@ -97,7 +97,7 @@ impl Object { #[rune::function(keep, path = Self::new)] pub fn new() -> Self { Self { - inner: BTreeMap::new_in(Global), + inner: BTreeMap::new(), } } @@ -120,7 +120,7 @@ impl Object { // BTreeMap doesn't support setting capacity on creation but we keep // this here in case we want to switch store later. Ok(Self { - inner: BTreeMap::new_in(Global), + inner: BTreeMap::new(), }) } diff --git a/crates/rune/src/runtime/shared.rs b/crates/rune/src/runtime/shared.rs index ea1e5e3bc..56b212be2 100644 --- a/crates/rune/src/runtime/shared.rs +++ b/crates/rune/src/runtime/shared.rs @@ -13,7 +13,7 @@ use ::rust_alloc::rc::Rc; #[cfg(feature = "alloc")] use ::rust_alloc::sync::Arc; -use crate::alloc::{Box, Error, Global}; +use crate::alloc::{Box, Error}; use crate::runtime::{ Access, AccessError, AccessKind, AnyObj, AnyObjError, BorrowMut, BorrowRef, RawAccessGuard, }; @@ -33,7 +33,7 @@ impl Shared { data: data.into(), }; - let inner = Box::leak(Box::try_new_in(shared, Global)?); + let inner = Box::leak(Box::try_new(shared)?); Ok(Self { inner: inner.into(), @@ -461,7 +461,7 @@ impl Shared { count: Cell::new(2), data: any.into(), }; - let inner = ptr::NonNull::from(Box::leak(Box::try_new_in(shared, Global)?)); + let inner = ptr::NonNull::from(Box::leak(Box::try_new(shared)?)); let guard = SharedPointerGuard { _inner: RawDrop::take_shared_box(inner), @@ -499,7 +499,12 @@ impl Shared { let expected = TypeId::of::(); let (e, any) = match any.raw_take(expected) { - Ok(value) => return Ok(Box::into_inner(Box::from_raw_in(value as *mut T, Global))), + Ok(value) => { + return Ok(Box::into_inner(Box::from_raw_in( + value as *mut T, + rune_alloc::Global, + ))) + } Err((AnyObjError::Cast, any)) => { let actual = any.type_name(); @@ -803,7 +808,7 @@ impl SharedBox { return false; } - let this = Box::from_raw_in(this, Global); + let this = Box::from_raw_in(this, rune_alloc::Global); if this.access.is_taken() { // NB: This prevents the inner `T` from being dropped in case it diff --git a/crates/rune/src/runtime/stack.rs b/crates/rune/src/runtime/stack.rs index 7b3ada569..86d7e9bf1 100644 --- a/crates/rune/src/runtime/stack.rs +++ b/crates/rune/src/runtime/stack.rs @@ -415,9 +415,12 @@ impl TryClone for Stack { } impl TryFromIteratorIn for Stack { - fn try_from_iter_in>(iter: T, _: Global) -> Result { + fn try_from_iter_in>( + iter: T, + alloc: Global, + ) -> Result { Ok(Self { - stack: iter.into_iter().try_collect()?, + stack: iter.into_iter().try_collect_in(alloc)?, stack_bottom: 0, }) } diff --git a/crates/rune/src/runtime/tuple.rs b/crates/rune/src/runtime/tuple.rs index 37ba3d00d..eb41e9be9 100644 --- a/crates/rune/src/runtime/tuple.rs +++ b/crates/rune/src/runtime/tuple.rs @@ -5,7 +5,7 @@ use core::slice; use crate::no_std::std; use crate as rune; -use crate::alloc::{Box, Error, Global, TryClone}; +use crate::alloc::{Box, Error, TryClone}; use crate::runtime::{ ConstValue, FromValue, Mut, RawMut, RawRef, Ref, ToValue, UnsafeToMut, UnsafeToRef, Value, VmErrorKind, VmResult, @@ -243,7 +243,7 @@ impl TryFrom> for OwnedTuple { return Ok(OwnedTuple::new()); } - let mut out = rune_alloc::Vec::try_with_capacity_in(inner.len(), Global)?; + let mut out = rune_alloc::Vec::try_with_capacity(inner.len())?; for value in inner.into_vec() { out.try_push(value.into_value()?)?; @@ -263,7 +263,7 @@ impl TryFrom> for OwnedTuple { return Ok(OwnedTuple::new()); } - let mut out = rune_alloc::Vec::try_with_capacity_in(inner.len(), Global)?; + let mut out = rune_alloc::Vec::try_with_capacity(inner.len())?; for value in rune_alloc::Vec::from(inner) { out.try_push(value.into_value()?)?; diff --git a/crates/rune/src/runtime/value/serde.rs b/crates/rune/src/runtime/value/serde.rs index 5841515bd..75a893e18 100644 --- a/crates/rune/src/runtime/value/serde.rs +++ b/crates/rune/src/runtime/value/serde.rs @@ -1,6 +1,6 @@ use core::fmt; -use crate::alloc::{self, Global, TryToOwned}; +use crate::alloc::{self, TryToOwned}; use crate::no_std::std; use crate::runtime::{Bytes, Object, Shared, Vec}; @@ -292,9 +292,9 @@ impl<'de> de::Visitor<'de> for VmVisitor { V: de::SeqAccess<'de>, { let mut vec = if let Some(hint) = visitor.size_hint() { - alloc::Vec::try_with_capacity_in(hint, Global).map_err(V::Error::custom)? + alloc::Vec::try_with_capacity(hint).map_err(V::Error::custom)? } else { - alloc::Vec::new_in(Global) + alloc::Vec::new() }; while let Some(elem) = visitor.next_element()? { diff --git a/crates/rune/src/runtime/vec.rs b/crates/rune/src/runtime/vec.rs index 9f4163936..9a8a5005d 100644 --- a/crates/rune/src/runtime/vec.rs +++ b/crates/rune/src/runtime/vec.rs @@ -11,7 +11,7 @@ use crate::no_std::std; use crate as rune; use crate::alloc::fmt::TryWrite; -use crate::alloc::{self, Error, Global, TryClone}; +use crate::alloc::{self, Error, TryClone}; #[cfg(feature = "alloc")] use crate::runtime::Hasher; use crate::runtime::{ @@ -43,7 +43,7 @@ use self::iter::Iter; #[repr(transparent)] #[rune(builtin, static_type = VEC_TYPE, from_value = Value::into_vec)] pub struct Vec { - inner: alloc::Vec, + inner: alloc::Vec, } impl Vec { @@ -60,7 +60,7 @@ impl Vec { /// ``` pub const fn new() -> Self { Self { - inner: alloc::Vec::new_in(Global), + inner: alloc::Vec::new(), } } @@ -76,12 +76,12 @@ impl Vec { /// capacity. pub fn with_capacity(cap: usize) -> Result { Ok(Self { - inner: alloc::Vec::try_with_capacity_in(cap, Global)?, + inner: alloc::Vec::try_with_capacity(cap)?, }) } /// Convert into inner std vector. - pub fn into_inner(self) -> alloc::Vec { + pub fn into_inner(self) -> alloc::Vec { self.inner } @@ -462,7 +462,7 @@ impl TryFrom> for Vec { #[inline] fn try_from(values: std::Vec) -> Result { - let mut inner = alloc::Vec::try_with_capacity_in(values.len(), Global)?; + let mut inner = alloc::Vec::try_with_capacity(values.len())?; for value in values { inner.try_push(value)?; @@ -481,7 +481,7 @@ impl TryFrom> for Vec { } } -impl From> for Vec { +impl From> for Vec { #[inline] fn from(inner: alloc::Vec) -> Self { Self { inner } @@ -514,7 +514,7 @@ where let vec = vm_try!(value.into_vec()); let vec = vm_try!(vec.take()); - let mut output = vm_try!(alloc::Vec::try_with_capacity_in(vec.len(), Global)); + let mut output = vm_try!(alloc::Vec::try_with_capacity(vec.len())); for value in vec { vm_try!(output.try_push(vm_try!(T::from_value(value)))); @@ -536,12 +536,12 @@ impl UnsafeToRef for [Value] { } } -impl ToValue for alloc::Vec +impl ToValue for alloc::Vec where T: ToValue, { fn to_value(self) -> VmResult { - let mut inner = vm_try!(alloc::Vec::try_with_capacity_in(self.len(), Global)); + let mut inner = vm_try!(alloc::Vec::try_with_capacity(self.len())); for value in self { vm_try!(inner.try_push(vm_try!(value.to_value()))); @@ -556,7 +556,7 @@ where T: ToValue, { fn to_value(self) -> VmResult { - let mut inner = vm_try!(alloc::Vec::try_with_capacity_in(self.len(), Global)); + let mut inner = vm_try!(alloc::Vec::try_with_capacity(self.len())); for value in self { vm_try!(inner.try_push(vm_try!(value.to_value())));