8000 rune: Support using Shared<T> as field · rune-rs/rune@b8f4925 · GitHub
[go: up one dir, main page]

Skip to content 8000

Commit b8f4925

Browse files
committed
rune: Support using Shared<T> as field
1 parent ad53a83 commit b8f4925

File tree

7 files changed

+287
-108
lines changed

7 files changed

+287
-108
lines changed

crates/rune/src/runtime/any_obj.rs

Lines changed: 139 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -5,112 +5,33 @@ use core::mem::{needs_drop, offset_of, replace, ManuallyDrop};
55
use core::ptr::{self, addr_of, addr_of_mut, drop_in_place, NonNull};
66

77
use crate::alloc::alloc::Global;
8+
use crate::alloc::clone::TryClone;
89
use crate::alloc::{self, Box};
910
use crate::{Any, Hash};
1011

1112
use super::{
1213
Access, AccessError, AnyTypeInfo, BorrowMut, BorrowRef, FromValue, Mut, RawAccessGuard,
13-
RawAnyGuard, Ref, RefVtable, RuntimeError, Shared, Snapshot, TypeInfo, Value, VmErrorKind,
14+
RawAnyGuard, Ref, RefVtable, RuntimeError, Shared, Snapshot, ToValue, TypeInfo, Value,
1415
};
1516

16-
#[derive(Debug)]
17-
#[cfg_attr(test, derive(PartialEq))]
18-
pub(super) enum AnyObjErrorKind {
19-
Cast(AnyTypeInfo, TypeInfo),
20-
AccessError(AccessError),
21-
}
22-
23-
/// Errors caused when accessing or coercing an [`AnyObj`].
24-
#[cfg_attr(test, derive(PartialEq))]
25-
pub struct AnyObjError {
26-
kind: AnyObjErrorKind,
27-
}
28-
29-
impl AnyObjError {
30-
#[inline]
31-
pub(super) fn new(kind: AnyObjErrorKind) -> Self {
32-
Self { kind }
33-
}
34-
35-
#[inline]
36-
pub(super) fn into_kind(self) -> AnyObjErrorKind {
37-
self.kind
38-
}
39-
}
40-
41-
impl core::error::Error for AnyObjError {}
42-
43-
impl fmt::Display for AnyObjError {
44-
#[inline]
45-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46-
match &self.kind {
47-
AnyObjErrorKind::Cast(expected, actual) => {
48-
write!(f, "Failed to cast `{actual}` to `{expected}`")
49-
}
50-
AnyObjErrorKind::AccessError(error) => error.fmt(f),
51-
}
52-
}
53-
}
54-
55-
impl fmt::Debug for AnyObjError {
56-
#[inline]
57-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58-
self.kind.fmt(f)
59-
}
60-
}
61-
62-
impl From<AccessError> for AnyObjError {
63-
#[inline]
64-
fn from(error: AccessError) -> Self {
65-
Self::new(AnyObjErrorKind::AccessError(error))
66-
}
67-
}
68-
69-
/// Guard which decrements and releases shared storage for the guarded reference.
70-
pub(super) struct AnyObjDecShared {
71-
pub(super) shared: NonNull<AnyObjData>,
72-
}
73-
74-
impl Drop for AnyObjDecShared {
75-
fn drop(&mut self) {
76-
// Safety: We know that the inner value is live in this instance.
77-
unsafe {
78-
AnyObjData::dec(self.shared);
79-
}
80-
}
81-
}
82-
83-
/// Guard which decrements and releases shared storage for the guarded reference.
84-
pub(crate) struct AnyObjDrop {
85-
#[allow(unused)]
86-
pub(super) shared: NonNull<AnyObjData>,
87-
}
88-
89-
impl Drop for AnyObjDrop {
90-
fn drop(&mut self) {
91-
// Safety: We know that the inner value is live in this instance.
92-
unsafe {
93-
self.shared.as_ref().access.take();
94-
95-
AnyObjData::dec(self.shared);
96-
}
97-
}
98-
}
99-
100-
pub(crate) struct RawAnyObjGuard {
101-
#[allow(unused)]
102-
pub(super) guard: RawAccessGuard,
103-
#[allow(unused)]
104-
pub(super) dec_shared: AnyObjDecShared,
105-
}
106-
10717
/// A type-erased wrapper for a reference.
10818
pub struct AnyObj {
10919
shared: NonNull<AnyObjData>,
11020
}
11121

11222
impl AnyObj {
23+
/// Construct a new typed object.
24+
///
25+
/// # Safety
26+
///
27+
/// Caller must ensure that the type is of the value `T`.
28+
#[inline]
29+
pub(super) unsafe fn from_raw(shared: NonNull<AnyObjData>) -> Self {
30+
Self { shared }
31+
}
32+
11333
/// Construct an Any that wraps an owned object.
34+
#[inline]
11435
pub(crate) fn new<T>(data: T) -> alloc::Result<Self>
11536
where
11637
T: Any,
@@ -149,6 +70,7 @@ impl AnyObj {
14970
///
15071
/// Caller must ensure that the returned `AnyObj` doesn't outlive the
15172
/// reference it is wrapping.
73+
#[inline]
15274
pub(crate) unsafe fn from_ref<T>(data: *const T) -> alloc::Result<Self>
15375
where
15476
T: Any,
@@ -181,6 +103,7 @@ impl AnyObj {
181103
///
182104
/// Caller must ensure that the returned `AnyObj` doesn't outlive the
183105
/// reference it is wrapping.
106+
#[inline]
184107
pub(crate) unsafe fn from_mut<T>(data: *mut T) -> alloc::Result<Self>
185108
where
186109
T: Any,
@@ -236,7 +159,7 @@ impl AnyObj {
236159
T: Any,
237160
{
238161
let this = ManuallyDrop::new(self);
239-
Shared::new(this.shared.cast())
162+
Shared::from_raw(this.shared.cast())
240163
}
241164

242165
/// Downcast into an owned value of type `T`.
@@ -288,11 +211,11 @@ impl AnyObj {
288211
}
289212

290213
/// Take the interior value and return a handle to the taken value.
291-
pub(crate) fn take(self) -> Result<Self, VmErrorKind> {
214+
pub fn take(self) -> Result<Self, AnyObjError> {
292215
let vtable = vtable(&self);
293216

294217
if !matches!(vtable.kind, Kind::Own) {
295-
return Err(VmErrorKind::from(AccessError::not_owned(
218+
return Err(AnyObjError::from(AccessError::not_owned(
296219
vtable.type_info(),
297220
)));
298221
}
@@ -654,6 +577,19 @@ impl Clone for AnyObj {
654577
}
655578
}
656579

580+
impl TryClone for AnyObj {
581+
#[inline]
582+
fn try_clone(&self) -> alloc::Result<Self> {
583+
Ok(self.clone())
584+
}
585+
586+
#[inline]
587+
fn try_clone_from(&mut self, source: &Self) -> alloc::Result<()> {
588+
self.clone_from(source);
589+
Ok(())
590+
}
591+
}
592+
657593
impl fmt::Debug for AnyObj {
658594
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
659595
self.debug(f)
@@ -676,6 +612,13 @@ impl FromValue for AnyObj {
676612
}
677613
}
678614

615+
impl ToValue for AnyObj {
616+
#[inline]
617+
fn to_value(self) -> Result<Value, RuntimeError> {
618+
Ok(Value::from(self))
619+
}
620+
}
621+
679622
/// The signature of a pointer coercion function.
680623
type TypeIdFn = fn() -> TypeId;
681624

@@ -797,6 +740,107 @@ impl AnyObjData {
797740
}
798741
}
799742

743+
#[derive(Debug)]
744+
#[cfg_attr(test, derive(PartialEq))]
745+
pub(super) enum AnyObjErrorKind {
746+
Alloc(alloc::Error),
747+
Cast(AnyTypeInfo, TypeInfo),
748+
AccessError(AccessError),
749+
}
750+
751+
/// Errors caused when accessing or coercing an [`AnyObj`].
752+
#[cfg_attr(test, derive(PartialEq))]
753+
pub struct AnyObjError {
754+
kind: AnyObjErrorKind,
755+
}
756+
757+
impl AnyObjError {
758+
#[inline]
759+
pub(super) fn new(kind: AnyObjErrorKind) -> Self {
760+
Self { kind }
761+
}
762+
763+
#[inline]
764+
pub(super) fn into_kind(self) -> AnyObjErrorKind {
765+
self.kind
766+
}
767+
}
768+
769+
impl core::error::Error for AnyObjError {}
770+
771+
impl fmt::Display for AnyObjError {
772+
#[inline]
773+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
774+
match &self.kind {
775+
AnyObjErrorKind::Alloc(error) => error.fmt(f),
776+
AnyObjErrorKind::Cast(expected, actual) => {
777+
write!(f, "Failed to cast `{actual}` to `{expected}`")
778+
}
779+
AnyObjErrorKind::AccessError(error) => error.fmt(f),
780+
}
781+
}
782+
}
783+
784+
impl fmt::Debug for AnyObjError {
785+
#[inline]
786+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
787+
self.kind.fmt(f)
788+
}
789+
}
790+
791+
impl From<alloc::Error> for AnyObjError {
792+
#[inline]
793+
fn from(error: alloc::Error) -> Self {
794+
Self::new(AnyObjErrorKind::Alloc(error))
795+
}
796+
}
797+
798+
impl From<AccessError> for AnyObjError {
799+
#[inline]
800+
fn from(error: AccessError) -> Self {
801+
Self::new(AnyObjErrorKind::AccessError(error))
802+
}
803+
}
804+
805+
/// Guard which decrements and releases shared storage for the guarded reference.
806+
pub(super) struct AnyObjDecShared {
807+
pub(super) shared: NonNull<AnyObjData>,
808+
}
809+
810+
impl Drop for AnyObjDecShared {
811+
fn drop(&mut self) {
812+
// Safety: We know that the inner value is live in this instance.
813+
unsafe {
814+
AnyObjData::dec(self.shared);
815+
}
816+
}
817+
}
818+
819+
/// Guard which decrements and releases shared storage for the guarded reference.
820+
pub(crate) struct AnyObjDrop {
821+
#[allow(unused)]
822+
pub(super) shared: NonNull<AnyObjData>,
823+
}
824+
825+
impl Drop for AnyObjDrop {
826+
#[inline]
827+
fn drop(&mut self) {
828+
// Safety: We know that the inner value is live in this instance.
829+
unsafe {
830+
self.shared.as_ref().access.take();
831+
AnyObjData::dec(self.shared);
832+
}
833+
}
834+
}
835+
836+
/// The guard returned when dealing with raw pointers.
837+
pub(crate) struct RawAnyObjGuard {
838+
#[allow(unused)]
839+
pub(super) guard: RawAccessGuard,
840+
#[allow(unused)]
841+
pub(super) dec_shared: AnyObjDecShared,
842+
}
843+
800844
fn debug_ref_impl<T>(f: &mut fmt::Formatter<'_>) -> fmt::Result
801845
where
802846
T: ?Sized + Any,

0 commit comments

Comments
 (0)
0