Skip to main content

rune/runtime/
ref.rs

1use core::fmt;
2use core::future::Future;
3use core::mem::replace;
4use core::ops::{Deref, DerefMut};
5use core::pin::Pin;
6use core::ptr::NonNull;
7use core::task::{Context, Poll};
8
9use rust_alloc::rc::Rc;
10use rust_alloc::sync::Arc;
11
12use crate::any::AnyMarker;
13
14use super::{FromValue, RuntimeError, Value};
15
16pub(super) struct RefVtable {
17    pub(super) drop: DropFn,
18    /// Hand the value which is referred to back, if the reference is one which
19    /// keeps a value alive rather than something borrowed from elsewhere.
20    ///
21    /// The reference is released by this, so it must not be released again,
22    /// which is what [`RawAnyGuard::take_value`] makes sure of.
23    pub(super) into_value: Option<IntoValueFn>,
24}
25
26type DropFn = unsafe fn(NonNull<()>);
27type IntoValueFn = unsafe fn(NonNull<()>) -> Value;
28
29/// A strong owned reference to the given type that can be safely dereferenced.
30///
31/// # Examples
32///
33/// Constructed from a static value:
34///
35/// ```rust
36/// use rune::Ref;
37///
38/// let value: Ref<str> = Ref::from_static("hello world");
39/// ```
40pub struct Ref<T: ?Sized> {
41    value: NonNull<T>,
42    guard: RawAnyGuard,
43}
44
45impl<T> From<Rc<T>> for Ref<T> {
46    /// Construct from an atomically reference-counted value.
47    ///
48    /// # Examples
49    ///
50    /// ```
51    /// use std::rc::Rc;
52    /// use rune::Ref;
53    ///
54    /// let value: Ref<String> = Ref::from(Rc::new(String::from("hello world")));
55    /// assert_eq!(value.as_ref(), "hello world");
56    /// ```
57    #[inline]
58    fn from(value: Rc<T>) -> Ref<T> {
59        unsafe fn drop_fn<T>(data: NonNull<()>) {
60            let _ = Rc::from_raw(data.cast::<T>().as_ptr().cast_const());
61        }
62
63        let value = Rc::into_raw(value);
64        let value = unsafe { NonNull::new_unchecked(value as *mut _) };
65
66        let guard = RawAnyGuard::new(
67            value.cast(),
68            &RefVtable {
69                drop: drop_fn::<T>,
70                into_value: None,
71            },
72        );
73
74        Ref::new(value, guard)
75    }
76}
77
78impl<T> From<Arc<T>> for Ref<T> {
79    /// Construct from an atomically reference-counted value.
80    ///
81    /// # Examples
82    ///
83    /// ```
84    /// use std::sync::Arc;
85    ///
86    /// use rune::Ref;
87    ///
88    /// let value: Ref<String> = Ref::from(Arc::new(String::from("hello world")));
89    /// assert_eq!(value.as_ref(), "hello world");
90    /// ```
91    #[inline]
92    fn from(value: Arc<T>) -> Ref<T> {
93        unsafe fn drop_fn<T>(data: NonNull<()>) {
94            let _ = Arc::from_raw(data.cast::<T>().as_ptr().cast_const());
95        }
96
97        let value = Arc::into_raw(value);
98        let value = unsafe { NonNull::new_unchecked(value as *mut _) };
99
100        let guard = RawAnyGuard::new(
101            value.cast(),
102            &RefVtable {
103                drop: drop_fn::<T>,
104                into_value: None,
105            },
106        );
107
108        Ref::new(value, guard)
109    }
110}
111
112impl<T: ?Sized> Ref<T> {
113    #[inline]
114    pub(super) const fn new(value: NonNull<T>, guard: RawAnyGuard) -> Self {
115        Self { value, guard }
116    }
117
118    /// Hand the value this keeps alive back, leaving the reference released.
119    ///
120    /// What is pointed to must not be used afterwards, which is why this is
121    /// only used while the thing holding the reference is being taken apart.
122    ///
123    /// See [`RawAnyGuard::take_value`].
124    #[inline]
125    pub(crate) fn take_value(this: &mut Self) -> Option<Value> {
126        this.guard.take_value()
127    }
128
129    /// The guard which keeps what is referred to alive, so that it can be
130    /// handed over while whatever holds the reference is taken apart.
131    #[inline]
132    pub(crate) fn guard_mut(&mut self) -> &mut RawAnyGuard {
133        &mut self.guard
134    }
135
136    /// Construct an owned reference from a static value.
137    ///
138    /// # Examples
139    ///
140    /// ```rust
141    /// use rune::Ref;
142    ///
143    /// let value: Ref<str> = Ref::from_static("Hello World");
144    /// assert_eq!(value.as_ref(), "Hello World");
145    /// ```
146    #[inline]
147    pub const fn from_static(value: &'static T) -> Ref<T> {
148        let value = unsafe { NonNull::new_unchecked((value as *const T).cast_mut()) };
149        let guard = RawAnyGuard::new(NonNull::dangling(), &NOOP_VTABLE);
150        Self::new(value, guard)
151    }
152
153    /// Map the interior reference of an owned mutable value.
154    ///
155    /// # Examples
156    ///
157    /// ```
158    /// use rune::Ref;
159    /// use rune::runtime::Bytes;
160    /// use rune::alloc::try_vec;
161    ///
162    /// let bytes = rune::to_value(Bytes::from_vec(try_vec![1, 2, 3, 4]))?;
163    /// let bytes: Ref<Bytes> = rune::from_value(bytes)?;
164    /// let value: Ref<[u8]> = Ref::map(bytes, |vec| &vec[0..2]);
165    ///
166    /// assert_eq!(&*value, &[1, 2][..]);
167    /// # Ok::<_, rune::support::Error>(())
168    /// ```
169    #[inline]
170    pub fn map<U: ?Sized, F>(this: Self, f: F) -> Ref<U>
171    where
172        F: FnOnce(&T) -> &U,
173    {
174        let Self { value, guard } = this;
175
176        // Safety: this follows the same safety guarantees as when the managed
177        // ref was acquired. And since we have a managed reference to `T`, we're
178        // permitted to do any sort of projection to `U`.
179        let value = f(unsafe { value.as_ref() });
180
181        Ref::new(value.into(), guard)
182    }
183
184    /// Try to map the reference to a projection.
185    ///
186    /// # Examples
187    ///
188    /// ```
189    /// use rune::Ref;
190    /// use rune::runtime::Bytes;
191    /// use rune::alloc::try_vec;
192    ///
193    /// let bytes = rune::to_value(Bytes::from_vec(try_vec![1, 2, 3, 4]))?;
194    /// let bytes: Ref<Bytes> = rune::from_value(bytes)?;
195    ///
196    /// let Ok(value) = Ref::try_map(bytes, |bytes| bytes.get(0..2)) else {
197    ///     panic!("Conversion failed");
198    /// };
199    ///
200    /// assert_eq!(&value[..], &[1, 2][..]);
201    /// # Ok::<_, rune::support::Error>(())
202    /// ```
203    #[inline]
204    pub fn try_map<U: ?Sized, F>(this: Self, f: F) -> Result<Ref<U>, Ref<T>>
205    where
206        F: FnOnce(&T) -> Option<&U>,
207    {
208        let Self { value, guard } = this;
209
210        // Safety: this follows the same safety guarantees as when the managed
211        // ref was acquired. And since we have a managed reference to `T`, we're
212        // permitted to do any sort of projection to `U`.
213
214        unsafe {
215            let Some(value) = f(value.as_ref()) else {
216                return Err(Ref::new(value, guard));
217            };
218
219            Ok(Ref::new(value.into(), guard))
220        }
221    }
222
223    /// Convert into a raw pointer and associated raw access guard.
224    ///
225    /// # Safety
226    ///
227    /// The returned pointer must not outlive the associated guard, since this
228    /// prevents other uses of the underlying data which is incompatible with
229    /// the current.
230    #[inline]
231    pub fn into_raw(this: Self) -> (NonNull<T>, RawAnyGuard) {
232        (this.value, this.guard)
233    }
234
235    /// Convert a raw reference and guard into a regular reference.
236    ///
237    /// # Safety
238    ///
239    /// The caller is responsible for ensuring that the raw reference is
240    /// associated with the specific pointer.
241    #[inline]
242    pub unsafe fn from_raw(value: NonNull<T>, guard: RawAnyGuard) -> Self {
243        Self { value, guard }
244    }
245}
246
247impl<T: ?Sized> AsRef<T> for Ref<T> {
248    #[inline]
249    fn as_ref(&self) -> &T {
250        self
251    }
252}
253
254impl<T: ?Sized> Deref for Ref<T> {
255    type Target = T;
256
257    #[inline]
258    fn deref(&self) -> &Self::Target {
259        // Safety: An owned ref holds onto a hard pointer to the data,
260        // preventing it from being dropped for the duration of the owned ref.
261        unsafe { self.value.as_ref() }
262    }
263}
264
265impl<T: ?Sized> fmt::Debug for Ref<T>
266where
267    T: fmt::Debug,
268{
269    #[inline]
270    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
271        fmt::Debug::fmt(&**self, fmt)
272    }
273}
274
275impl<T> FromValue for Ref<T>
276where
277    T: AnyMarker,
278{
279    #[inline]
280    fn from_value(value: Value) -> Result<Self, RuntimeError> {
281        value.into_ref()
282    }
283}
284
285/// A strong owned mutable reference to the given type that can be safely
286/// dereferenced.
287///
288/// # Examples
289///
290/// Constructed from a static value:
291///
292/// ```rust
293/// use rune::Mut;
294///
295/// let value: Mut<[u8]> = Mut::from_static(&mut [][..]);
296/// assert_eq!(&value[..], b"");
297/// ```
298pub struct Mut<T: ?Sized> {
299    value: NonNull<T>,
300    guard: RawAnyGuard,
301}
302
303impl<T: ?Sized> Mut<T> {
304    #[inline]
305    pub(super) const fn new(value: NonNull<T>, guard: RawAnyGuard) -> Self {
306        Self { value, guard }
307    }
308
309    /// Construct an owned mutable reference from a static value.
310    ///
311    /// # Examples
312    ///
313    /// ```rust
314    /// use rune::Mut;
315    ///
316    /// let value: Mut<[u8]> = Mut::from_static(&mut [][..]);
317    /// assert_eq!(&value[..], b"");
318    /// ```
319    #[inline]
320    pub fn from_static(value: &'static mut T) -> Mut<T> {
321        let value = unsafe { NonNull::new_unchecked((value as *const T).cast_mut()) };
322        let guard = RawAnyGuard::new(NonNull::dangling(), &NOOP_VTABLE);
323        Self::new(value, guard)
324    }
325
326    /// Map the interior reference of an owned mutable value.
327    ///
328    /// # Examples
329    ///
330    /// ```
331    /// use rune::Mut;
332    /// use rune::runtime::Bytes;
333    /// use rune::alloc::try_vec;
334    ///
335    /// let bytes = rune::to_value(Bytes::from_vec(try_vec![1, 2, 3, 4]))?;
336    /// let bytes: Mut<Bytes> = rune::from_value(bytes)?;
337    /// let value: Mut<[u8]> = Mut::map(bytes, |bytes| &mut bytes[0..2]);
338    ///
339    /// assert_eq!(&*value, &mut [1, 2][..]);
340    /// # Ok::<_, rune::support::Error>(())
341    /// ```
342    #[inline]
343    pub fn map<U: ?Sized, F>(this: Self, f: F) -> Mut<U>
344    where
345        F: FnOnce(&mut T) -> &mut U,
346    {
347        let Self {
348            mut value, guard, ..
349        } = this;
350
351        // Safety: this follows the same safety guarantees as when the managed
352        // ref was acquired. And since we have a managed reference to `T`, we're
353        // permitted to do any sort of projection to `U`.
354        let value = f(unsafe { value.as_mut() });
355
356        Mut::new(value.into(), guard)
357    }
358
359    /// Try to map the mutable reference to a projection.
360    ///
361    /// # Examples
362    ///
363    /// ```
364    /// use rune::Mut;
365    /// use rune::runtime::Bytes;
366    /// use rune::alloc::try_vec;
367    ///
368    /// let bytes = rune::to_value(Bytes::from_vec(try_vec![1, 2, 3, 4]))?;
369    /// let bytes: Mut<Bytes> = rune::from_value(bytes)?;
370    ///
371    /// let Ok(mut value) = Mut::try_map(bytes, |bytes| bytes.get_mut(0..2)) else {
372    ///     panic!("Conversion failed");
373    /// };
374    ///
375    /// assert_eq!(&mut value[..], &mut [1, 2][..]);
376    /// # Ok::<_, rune::support::Error>(())
377    /// ```
378    #[inline]
379    pub fn try_map<U: ?Sized, F>(this: Self, f: F) -> Result<Mut<U>, Mut<T>>
380    where
381        F: FnOnce(&mut T) -> Option<&mut U>,
382    {
383        let Self {
384            mut value, guard, ..
385        } = this;
386
387        // Safety: this follows the same safety guarantees as when the managed
388        // ref was acquired. And since we have a managed reference to `T`, we're
389        // permitted to do any sort of projection to `U`.
390        unsafe {
391            let Some(value) = f(value.as_mut()) else {
392                return Err(Mut::new(value, guard));
393            };
394
395            Ok(Mut::new(value.into(), guard))
396        }
397    }
398
399    /// Convert into a raw pointer and associated raw access guard.
400    ///
401    /// # Safety
402    ///
403    /// The returned pointer must not outlive the associated guard, since this
404    /// prevents other uses of the underlying data which is incompatible with
405    /// the current.
406    #[inline]
407    pub fn into_raw(this: Self) -> (NonNull<T>, RawAnyGuard) {
408        (this.value, this.guard)
409    }
410
411    /// Convert a raw mutable reference and guard into a regular mutable
412    /// reference.
413    ///
414    /// # Safety
415    ///
416    /// The caller is responsible for ensuring that the raw mutable reference is
417    /// associated with the specific pointer.
418    #[inline]
419    pub unsafe fn from_raw(value: NonNull<T>, guard: RawAnyGuard) -> Self {
420        Self { value, guard }
421    }
422}
423
424impl<T: ?Sized> AsRef<T> for Mut<T> {
425    #[inline]
426    fn as_ref(&self) -> &T {
427        self
428    }
429}
430
431impl<T: ?Sized> AsMut<T> for Mut<T> {
432    #[inline]
433    fn as_mut(&mut self) -> &mut T {
434        self
435    }
436}
437
438impl<T: ?Sized> Deref for Mut<T> {
439    type Target = T;
440
441    #[inline]
442    fn deref(&self) -> &Self::Target {
443        // Safety: An owned mut holds onto a hard pointer to the data,
444        // preventing it from being dropped for the duration of the owned mut.
445        unsafe { self.value.as_ref() }
446    }
447}
448
449impl<T: ?Sized> DerefMut for Mut<T> {
450    #[inline]
451    fn deref_mut(&mut self) -> &mut Self::Target {
452        // Safety: An owned mut holds onto a hard pointer to the data,
453        // preventing it from being dropped for the duration of the owned mut.
454        unsafe { self.value.as_mut() }
455    }
456}
457
458impl<T: ?Sized> fmt::Debug for Mut<T>
459where
460    T: fmt::Debug,
461{
462    #[inline]
463    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
464        fmt::Debug::fmt(&**self, fmt)
465    }
466}
467
468impl<T> FromValue for Mut<T>
469where
470    T: AnyMarker,
471{
472    #[inline]
473    fn from_value(value: Value) -> Result<Self, RuntimeError> {
474        value.into_mut()
475    }
476}
477
478impl<F> Future for Mut<F>
479where
480    F: Unpin + Future,
481{
482    type Output = F::Output;
483
484    #[inline]
485    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
486        // NB: inner Future is Unpin.
487        let this = self.get_mut();
488        Pin::new(&mut **this).poll(cx)
489    }
490}
491
492/// A raw guard for a [`Ref`] or a [`Mut`] that has been converted into its raw
493/// components through [`Ref::into_raw`] or [`Mut::into_raw`].
494pub struct RawAnyGuard {
495    data: NonNull<()>,
496    vtable: &'static RefVtable,
497}
498
499impl RawAnyGuard {
500    #[inline]
501    pub(super) const fn new(data: NonNull<()>, vtable: &'static RefVtable) -> Self {
502        Self { data, vtable }
503    }
504
505    /// Hand the value this keeps alive back, leaving the guard released so that
506    /// dropping it does nothing.
507    ///
508    /// This is what a value which refers to another one rather than holding it
509    /// in a slot - an iterator over a collection - uses to hand the collection
510    /// over while it is being taken apart, so that dropping it does not descend
511    /// into the collection and recurse.
512    ///
513    /// Returns `None` for a reference which does not keep a value alive, which
514    /// leaves the guard alone.
515    pub(crate) fn take_value(&mut self) -> Option<Value> {
516        let into_value = self.vtable.into_value?;
517        let data = replace(&mut self.data, NonNull::dangling());
518        self.vtable = &NOOP_VTABLE;
519        // Safety: type and referential safety is guaranteed at construction
520        // time, and the guard is released here so it cannot be released again.
521        Some(unsafe { into_value(data) })
522    }
523}
524
525/// The guard of a reference which owns nothing, which is what a guard is
526/// replaced with once what it kept alive has been handed over.
527static NOOP_VTABLE: RefVtable = RefVtable {
528    drop: |_| {},
529    into_value: None,
530};
531
532impl Drop for RawAnyGuard {
533    #[inline]
534    fn drop(&mut self) {
535        // Safety: type and referential safety is guaranteed at construction
536        // time, since all constructors are unsafe.
537        unsafe {
538            (self.vtable.drop)(self.data);
539        }
540    }
541}