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}