1#[macro_use]
2mod macros;
3
4#[cfg(test)]
5mod tests;
6
7mod inline;
8pub use self::inline::Inline;
9
10#[cfg(feature = "serde")]
11mod serde;
12
13mod rtti;
14pub(crate) use self::rtti::RttiKind;
15pub use self::rtti::{Accessor, Rtti};
16
17mod data;
18pub use self::data::{EmptyStruct, Struct, TupleStruct};
19
20mod any_sequence;
21pub use self::any_sequence::AnySequence;
22pub(crate) use self::any_sequence::AnySequenceTakeError;
23
24use core::any;
25use core::cmp::Ordering;
26use core::fmt;
27use core::mem::replace;
28use core::ptr::NonNull;
29
30use crate::alloc::fmt::TryWrite;
31use crate::alloc::prelude::*;
32use crate::alloc::{self, String};
33use crate::compile::meta;
34use crate::sync::Arc;
35use crate::{Any, Hash, TypeHash};
36
37use super::{
38 AccessError, AnyObj, AnyObjDrop, BorrowMut, BorrowRef, CallResultOnly, ConstValue,
39 ConstValueKind, DynGuardedArgs, EnvProtocolCaller, Formatter, FromValue, Future, Hasher,
40 Iterator, MaybeTypeOf, Mut, Object, OwnedTuple, Protocol, ProtocolCaller, RawAnyObjGuard, Ref,
41 RuntimeError, Shared, Snapshot, Tuple, Type, TypeInfo, Vec, VmError, VmErrorKind,
42 VmIntegerRepr,
43};
44
45pub struct ValueRefGuard {
49 #[allow(unused)]
50 guard: AnyObjDrop,
51}
52
53pub struct ValueMutGuard {
57 #[allow(unused)]
58 guard: AnyObjDrop,
59}
60
61pub struct RawValueGuard {
63 #[allow(unused)]
64 guard: RawAnyObjGuard,
65}
66
67#[derive(Clone)]
68pub(crate) enum Repr {
69 Inline(Inline),
70 Dynamic(AnySequence<Arc<Rtti>, Value>),
71 Any(AnyObj),
72}
73
74impl Repr {
75 #[inline]
76 pub(crate) fn type_info(&self) -> TypeInfo {
77 match self {
78 Repr::Inline(value) => value.type_info(),
79 Repr::Dynamic(value) => value.type_info(),
80 Repr::Any(value) => value.type_info(),
81 }
82 }
83}
84
85pub struct Value {
87 repr: Repr,
88}
89
90impl Value {
91 #[inline]
93 pub fn take(value: &mut Self) -> Self {
94 replace(value, Self::empty())
95 }
96
97 pub fn new<T>(data: T) -> alloc::Result<Self>
100 where
101 T: Any,
102 {
103 Ok(Self {
104 repr: Repr::Any(AnyObj::new(data)?),
105 })
106 }
107
108 pub unsafe fn from_ref<T>(data: &T) -> alloc::Result<(Self, ValueRefGuard)>
153 where
154 T: Any,
155 {
156 let value = AnyObj::from_ref(data)?;
157 let (value, guard) = AnyObj::into_drop_guard(value);
158
159 let guard = ValueRefGuard { guard };
160
161 Ok((
162 Self {
163 repr: Repr::Any(value),
164 },
165 guard,
166 ))
167 }
168
169 pub unsafe fn from_mut<T>(data: &mut T) -> alloc::Result<(Self, ValueMutGuard)>
221 where
222 T: Any,
223 {
224 let value = AnyObj::from_mut(data)?;
225 let (value, guard) = AnyObj::into_drop_guard(value);
226
227 let guard = ValueMutGuard { guard };
228
229 Ok((
230 Self {
231 repr: Repr::Any(value),
232 },
233 guard,
234 ))
235 }
236
237 pub(crate) fn snapshot(&self) -> Option<Snapshot> {
239 match &self.repr {
240 Repr::Dynamic(value) => Some(value.snapshot()),
241 Repr::Any(value) => Some(value.snapshot()),
242 _ => None,
243 }
244 }
245
246 pub fn is_writable(&self) -> bool {
285 match self.repr {
286 Repr::Inline(Inline::Empty) => false,
287 Repr::Inline(..) => true,
288 Repr::Dynamic(ref value) => value.is_writable(),
289 Repr::Any(ref any) => any.is_writable(),
290 }
291 }
292
293 pub fn is_readable(&self) -> bool {
332 match &self.repr {
333 Repr::Inline(Inline::Empty) => false,
334 Repr::Inline(..) => true,
335 Repr::Dynamic(ref value) => value.is_readable(),
336 Repr::Any(ref any) => any.is_readable(),
337 }
338 }
339
340 pub(crate) const fn unit() -> Self {
342 Self {
343 repr: Repr::Inline(Inline::Unit),
344 }
345 }
346
347 pub const fn empty() -> Self {
349 Self {
350 repr: Repr::Inline(Inline::Empty),
351 }
352 }
353
354 pub fn display_fmt(&self, f: &mut Formatter) -> Result<(), VmError> {
367 self.display_fmt_with(f, &mut EnvProtocolCaller)
368 }
369
370 #[cfg_attr(feature = "bench", inline(never))]
372 pub(crate) fn display_fmt_with(
373 &self,
374 f: &mut Formatter,
375 caller: &mut dyn ProtocolCaller,
376 ) -> Result<(), VmError> {
377 'fallback: {
378 match self.as_ref() {
379 Repr::Inline(value) => match value {
380 Inline::Char(c) => {
381 f.try_write_char(*c)?;
382 }
383 Inline::Unsigned(byte) => {
384 let mut buffer = itoa::Buffer::new();
385 f.try_write_str(buffer.format(*byte))?;
386 }
387 Inline::Signed(integer) => {
388 let mut buffer = itoa::Buffer::new();
389 f.try_write_str(buffer.format(*integer))?;
390 }
391 Inline::Float(float) => {
392 let mut buffer = ryu::Buffer::new();
393 f.try_write_str(buffer.format(*float))?;
394 }
395 Inline::Bool(bool) => {
396 write!(f, "{bool}")?;
397 }
398 _ => {
399 break 'fallback;
400 }
401 },
402 _ => {
403 break 'fallback;
404 }
405 }
406
407 return Ok(());
408 };
409
410 let mut args = DynGuardedArgs::new((f,));
411
412 let result = caller.call_protocol_fn(&Protocol::DISPLAY_FMT, self.clone(), &mut args)?;
413
414 <()>::from_value(result)?;
415 Ok(())
416 }
417
418 pub fn clone_(&self) -> Result<Self, VmError> {
431 self.clone_with(&mut EnvProtocolCaller)
432 }
433
434 pub(crate) fn clone_with(&self, caller: &mut dyn ProtocolCaller) -> Result<Value, VmError> {
435 match self.as_ref() {
436 Repr::Inline(value) => {
437 return Ok(Self {
438 repr: Repr::Inline(*value),
439 });
440 }
441 Repr::Dynamic(value) => {
442 return Ok(Self {
444 repr: Repr::Dynamic(value.clone()),
445 });
446 }
447 Repr::Any(..) => {}
448 }
449
450 caller.call_protocol_fn(&Protocol::CLONE, self.clone(), &mut ())
451 }
452
453 pub fn debug_fmt(&self, f: &mut Formatter) -> Result<(), VmError> {
466 self.debug_fmt_with(f, &mut EnvProtocolCaller)
467 }
468
469 pub(crate) fn debug_fmt_with(
471 &self,
472 f: &mut Formatter,
473 caller: &mut dyn ProtocolCaller,
474 ) -> Result<(), VmError> {
475 match &self.repr {
476 Repr::Inline(value) => {
477 write!(f, "{value:?}")?;
478 }
479 Repr::Dynamic(ref value) => {
480 value.debug_fmt_with(f, caller)?;
481 }
482 Repr::Any(..) => {
483 let mut args = DynGuardedArgs::new((&mut *f,));
485
486 match caller.try_call_protocol_fn(&Protocol::DEBUG_FMT, self.clone(), &mut args)? {
487 CallResultOnly::Ok(value) => {
488 <()>::from_value(value)?;
489 }
490 CallResultOnly::Unsupported(value) => match &value.repr {
491 Repr::Inline(value) => {
492 write!(f, "{value:?}")?;
493 }
494 Repr::Dynamic(value) => {
495 let ty = value.type_info();
496 write!(f, "<{ty} object at {value:p}>")?;
497 }
498 Repr::Any(value) => {
499 let ty = value.type_info();
500 write!(f, "<{ty} object at {value:p}>")?;
501 }
502 },
503 }
504 }
505 }
506
507 Ok(())
508 }
509
510 pub fn into_iter(self) -> Result<Iterator, VmError> {
522 self.into_iter_with(&mut EnvProtocolCaller)
523 }
524
525 pub(crate) fn into_iter_with(
526 self,
527 caller: &mut dyn ProtocolCaller,
528 ) -> Result<Iterator, VmError> {
529 let value = caller.call_protocol_fn(&Protocol::INTO_ITER, self, &mut ())?;
530 Ok(Iterator::new(value))
531 }
532
533 pub fn into_type_name(self) -> Result<String, VmError> {
548 let hash = Hash::associated_function(self.type_hash(), &Protocol::INTO_TYPE_NAME);
549
550 crate::runtime::env::shared(|context, unit| {
551 if let Some(name) = context.constant(&hash) {
552 match name.as_kind() {
553 ConstValueKind::String(s) => return Ok(String::try_from(s.as_ref())?),
554 _ => {
555 return Err(VmError::new(VmErrorKind::expected::<String>(
556 name.type_info(),
557 )))
558 }
559 }
560 }
561
562 if let Some(name) = unit.constant(&hash) {
563 match name.as_kind() {
564 ConstValueKind::String(s) => return Ok(String::try_from(s.as_ref())?),
565 _ => {
566 return Err(VmError::new(VmErrorKind::expected::<String>(
567 name.type_info(),
568 )))
569 }
570 }
571 }
572
573 Ok(self.type_info().try_to_string()?)
574 })
575 }
576
577 pub fn vec(vec: alloc::Vec<Value>) -> alloc::Result<Self> {
579 let data = Vec::from(vec);
580 Value::try_from(data)
581 }
582
583 pub fn tuple(vec: alloc::Vec<Value>) -> alloc::Result<Self> {
585 Value::try_from(OwnedTuple::try_from(vec)?)
586 }
587
588 pub fn empty_struct(rtti: Arc<Rtti>) -> alloc::Result<Self> {
590 Ok(Value::from(AnySequence::new(rtti, [])?))
591 }
592
593 pub fn tuple_struct(
595 rtti: Arc<Rtti>,
596 data: impl IntoIterator<IntoIter: ExactSizeIterator, Item = Value>,
597 ) -> alloc::Result<Self> {
598 Ok(Value::from(AnySequence::new(rtti, data)?))
599 }
600
601 pub(crate) fn drop(self) -> Result<(), VmError> {
606 match self.repr {
607 Repr::Dynamic(value) => {
608 value.drop()?;
609 }
610 Repr::Any(value) => {
611 value.drop()?;
612 }
613 _ => {}
614 }
615
616 Ok(())
617 }
618
619 pub(crate) fn move_(self) -> Result<Self, VmError> {
621 match self.repr {
622 Repr::Dynamic(value) => Ok(Value {
623 repr: Repr::Dynamic(value.take()?),
624 }),
625 Repr::Any(value) => Ok(Value {
626 repr: Repr::Any(value.take()?),
627 }),
628 repr => Ok(Value { repr }),
629 }
630 }
631
632 #[inline]
634 pub fn as_usize(&self) -> Result<usize, RuntimeError> {
635 self.as_integer()
636 }
637
638 #[deprecated(
640 note = "For consistency with other methods, this has been renamed Value::borrow_string_ref"
641 )]
642 #[inline]
643 pub fn as_string(&self) -> Result<BorrowRef<'_, str>, RuntimeError> {
644 self.borrow_string_ref()
645 }
646
647 pub fn borrow_string_ref(&self) -> Result<BorrowRef<'_, str>, RuntimeError> {
649 let string = self.borrow_ref::<String>()?;
650 Ok(BorrowRef::map(string, String::as_str))
651 }
652
653 #[inline]
655 pub fn into_string(self) -> Result<String, RuntimeError> {
656 match self.take_repr() {
657 Repr::Any(value) => Ok(value.downcast()?),
658 actual => Err(RuntimeError::expected::<String>(actual.type_info())),
659 }
660 }
661
662 #[doc(hidden)]
664 #[inline]
665 pub fn as_type_value(&self) -> Result<TypeValue<'_>, RuntimeError> {
666 match self.as_ref() {
667 Repr::Inline(value) => match value {
668 Inline::Unit => Ok(TypeValue::Unit),
669 value => Ok(TypeValue::NotTypedInline(NotTypedInline(*value))),
670 },
671 Repr::Dynamic(value) => match value.rtti().kind {
672 RttiKind::Empty => Ok(TypeValue::EmptyStruct(EmptyStruct { rtti: value.rtti() })),
673 RttiKind::Tuple => Ok(TypeValue::TupleStruct(TupleStruct {
674 rtti: value.rtti(),
675 data: value.borrow_ref()?,
676 })),
677 RttiKind::Struct => Ok(TypeValue::Struct(Struct {
678 rtti: value.rtti(),
679 data: value.borrow_ref()?,
680 })),
681 },
682 Repr::Any(value) => match value.type_hash() {
683 OwnedTuple::HASH => Ok(TypeValue::Tuple(value.borrow_ref()?)),
684 Object::HASH => Ok(TypeValue::Object(value.borrow_ref()?)),
685 _ => Ok(TypeValue::NotTypedAnyObj(NotTypedAnyObj(value))),
686 },
687 }
688 }
689
690 #[inline]
692 pub fn into_unit(&self) -> Result<(), RuntimeError> {
693 match self.as_ref() {
694 Repr::Inline(Inline::Unit) => Ok(()),
695 value => Err(RuntimeError::expected::<()>(value.type_info())),
696 }
697 }
698
699 inline_into! {
700 Ordering(Ordering),
702 as_ordering,
703 as_ordering_mut,
704 }
705
706 inline_into! {
707 Hash(Hash),
709 as_hash,
710 as_hash_mut,
711 }
712
713 inline_into! {
714 Bool(bool),
716 as_bool,
717 as_bool_mut,
718 }
719
720 inline_into! {
721 Char(char),
723 as_char,
724 as_char_mut,
725 }
726
727 inline_into! {
728 Signed(i64),
730 as_signed,
731 as_signed_mut,
732 }
733
734 inline_into! {
735 Unsigned(u64),
737 as_unsigned,
738 as_unsigned_mut,
739 }
740
741 inline_into! {
742 Float(f64),
744 as_float,
745 as_float_mut,
746 }
747
748 inline_into! {
749 Type(Type),
751 as_type,
752 as_type_mut,
753 }
754
755 #[inline]
760 pub fn borrow_tuple_ref(&self) -> Result<BorrowRef<'_, Tuple>, RuntimeError> {
761 match self.as_ref() {
762 Repr::Inline(Inline::Unit) => Ok(BorrowRef::from_static(Tuple::new(&[]))),
763 Repr::Inline(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
764 Repr::Dynamic(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
765 Repr::Any(value) => {
766 let value = value.borrow_ref::<OwnedTuple>()?;
767 let value = BorrowRef::map(value, OwnedTuple::as_ref);
768 Ok(value)
769 }
770 }
771 }
772
773 #[inline]
778 pub fn borrow_tuple_mut(&self) -> Result<BorrowMut<'_, Tuple>, RuntimeError> {
779 match self.as_ref() {
780 Repr::Inline(Inline::Unit) => Ok(BorrowMut::from_ref(Tuple::new_mut(&mut []))),
781 Repr::Inline(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
782 Repr::Dynamic(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
783 Repr::Any(value) => {
784 let value = value.borrow_mut::<OwnedTuple>()?;
785 let value = BorrowMut::map(value, OwnedTuple::as_mut);
786 Ok(value)
787 }
788 }
789 }
790
791 #[inline]
796 pub fn into_tuple(&self) -> Result<Box<Tuple>, RuntimeError> {
797 match self.as_ref() {
798 Repr::Inline(Inline::Unit) => Ok(Tuple::from_boxed(Box::default())),
799 Repr::Inline(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
800 Repr::Dynamic(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
801 Repr::Any(value) => Ok(value.clone().downcast::<OwnedTuple>()?.into_boxed_tuple()),
802 }
803 }
804
805 #[inline]
810 pub fn into_tuple_ref(&self) -> Result<Ref<Tuple>, RuntimeError> {
811 match self.as_ref() {
812 Repr::Inline(Inline::Unit) => Ok(Ref::from_static(Tuple::new(&[]))),
813 Repr::Inline(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
814 Repr::Dynamic(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
815 Repr::Any(value) => {
816 let value = value.clone().into_ref::<OwnedTuple>()?;
817 let value = Ref::map(value, OwnedTuple::as_ref);
818 Ok(value)
819 }
820 }
821 }
822
823 #[inline]
828 pub fn into_tuple_mut(&self) -> Result<Mut<Tuple>, RuntimeError> {
829 match self.as_ref() {
830 Repr::Inline(Inline::Unit) => Ok(Mut::from_static(Tuple::new_mut(&mut []))),
831 Repr::Inline(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
832 Repr::Dynamic(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
833 Repr::Any(value) => {
834 let value = value.clone().into_mut::<OwnedTuple>()?;
835 let value = Mut::map(value, OwnedTuple::as_mut);
836 Ok(value)
837 }
838 }
839 }
840
841 #[inline]
843 pub fn into_any_obj(self) -> Result<AnyObj, RuntimeError> {
844 match self.repr {
845 Repr::Inline(value) => Err(RuntimeError::expected_any_obj(value.type_info())),
846 Repr::Dynamic(value) => Err(RuntimeError::expected_any_obj(value.type_info())),
847 Repr::Any(value) => Ok(value),
848 }
849 }
850
851 #[inline]
856 pub fn into_shared<T>(self) -> Result<Shared<T>, RuntimeError>
857 where
858 T: Any,
859 {
860 match self.repr {
861 Repr::Inline(value) => Err(RuntimeError::expected_any_obj(value.type_info())),
862 Repr::Dynamic(value) => Err(RuntimeError::expected_any_obj(value.type_info())),
863 Repr::Any(value) => Ok(value.into_shared()?),
864 }
865 }
866
867 #[inline]
883 pub fn into_future(self) -> Result<Future, RuntimeError> {
884 let target = match self.repr {
885 Repr::Any(value) => match value.type_hash() {
886 Future::HASH => {
887 return Ok(value.downcast::<Future>()?);
888 }
889 _ => Value::from(value),
890 },
891 repr => Value::from(repr),
892 };
893
894 let value = EnvProtocolCaller.call_protocol_fn(&Protocol::INTO_FUTURE, target, &mut ())?;
895
896 Future::from_value(value)
897 }
898
899 #[inline]
906 pub fn into_any_ref_ptr<T>(self) -> Result<(NonNull<T>, RawValueGuard), RuntimeError>
907 where
908 T: Any,
909 {
910 match self.repr {
911 Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
912 Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
913 Repr::Any(value) => {
914 let (ptr, guard) = value.borrow_ref_ptr::<T>()?;
915 let guard = RawValueGuard { guard };
916 Ok((ptr, guard))
917 }
918 }
919 }
920
921 #[inline]
928 #[doc(hidden)]
929 pub fn into_any_mut_ptr<T>(self) -> Result<(NonNull<T>, RawValueGuard), RuntimeError>
930 where
931 T: Any,
932 {
933 match self.repr {
934 Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
935 Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
936 Repr::Any(value) => {
937 let (ptr, guard) = value.borrow_mut_ptr::<T>()?;
938 let guard = RawValueGuard { guard };
939 Ok((ptr, guard))
940 }
941 }
942 }
943
944 #[inline]
974 pub fn downcast<T>(self) -> Result<T, RuntimeError>
975 where
976 T: Any,
977 {
978 match self.repr {
979 Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
980 Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
981 Repr::Any(value) => Ok(value.downcast::<T>()?),
982 }
983 }
984
985 #[inline]
1007 pub fn borrow_ref<T>(&self) -> Result<BorrowRef<'_, T>, RuntimeError>
1008 where
1009 T: Any,
1010 {
1011 match &self.repr {
1012 Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1013 Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1014 Repr::Any(value) => Ok(value.borrow_ref()?),
1015 }
1016 }
1017
1018 #[inline]
1039 pub fn into_ref<T>(self) -> Result<Ref<T>, RuntimeError>
1040 where
1041 T: Any,
1042 {
1043 match self.repr {
1044 Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1045 Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1046 Repr::Any(value) => Ok(value.into_ref()?),
1047 }
1048 }
1049
1050 #[inline]
1052 pub fn borrow_mut<T>(&self) -> Result<BorrowMut<'_, T>, RuntimeError>
1053 where
1054 T: Any,
1055 {
1056 match &self.repr {
1057 Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1058 Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1059 Repr::Any(value) => Ok(value.borrow_mut()?),
1060 }
1061 }
1062
1063 #[inline]
1092 pub fn into_mut<T>(self) -> Result<Mut<T>, RuntimeError>
1093 where
1094 T: Any,
1095 {
1096 match self.repr {
1097 Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1098 Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1099 Repr::Any(value) => Ok(value.into_mut()?),
1100 }
1101 }
1102
1103 #[inline(always)]
1108 pub fn type_hash(&self) -> Hash {
1109 match &self.repr {
1110 Repr::Inline(value) => value.type_hash(),
1111 Repr::Dynamic(value) => value.type_hash(),
1112 Repr::Any(value) => value.type_hash(),
1113 }
1114 }
1115
1116 #[inline(always)]
1118 pub fn type_info(&self) -> TypeInfo {
1119 match &self.repr {
1120 Repr::Inline(value) => value.type_info(),
1121 Repr::Dynamic(value) => value.type_info(),
1122 Repr::Any(value) => value.type_info(),
1123 }
1124 }
1125
1126 pub fn partial_eq(a: &Value, b: &Value) -> Result<bool, VmError> {
1137 Self::partial_eq_with(a, b, &mut EnvProtocolCaller)
1138 }
1139
1140 #[cfg_attr(feature = "bench", inline(never))]
1144 pub(crate) fn partial_eq_with(
1145 &self,
1146 b: &Value,
1147 caller: &mut dyn ProtocolCaller,
1148 ) -> Result<bool, VmError> {
1149 self.bin_op_with(
1150 b,
1151 caller,
1152 &Protocol::PARTIAL_EQ,
1153 Inline::partial_eq,
1154 |lhs, rhs, caller| {
1155 if lhs.0.variant_hash != rhs.0.variant_hash {
1156 return Ok(false);
1157 }
1158
1159 Vec::eq_with(lhs.1, rhs.1, Value::partial_eq_with, caller)
1160 },
1161 )
1162 }
1163
1164 pub fn eq(&self, b: &Value) -> Result<bool, VmError> {
1175 self.eq_with(b, &mut EnvProtocolCaller)
1176 }
1177
1178 #[cfg_attr(feature = "bench", inline(never))]
1182 pub(crate) fn eq_with(
1183 &self,
1184 b: &Value,
1185 caller: &mut dyn ProtocolCaller,
1186 ) -> Result<bool, VmError> {
1187 self.bin_op_with(b, caller, &Protocol::EQ, Inline::eq, |lhs, rhs, caller| {
1188 if lhs.0.variant_hash != rhs.0.variant_hash {
1189 return Ok(false);
1190 }
1191
1192 Vec::eq_with(lhs.1, rhs.1, Value::eq_with, caller)
1193 })
1194 }
1195
1196 pub fn partial_cmp(a: &Value, b: &Value) -> Result<Option<Ordering>, VmError> {
1207 Value::partial_cmp_with(a, b, &mut EnvProtocolCaller)
1208 }
1209
1210 #[cfg_attr(feature = "bench", inline(never))]
1214 pub(crate) fn partial_cmp_with(
1215 &self,
1216 b: &Value,
1217 caller: &mut dyn ProtocolCaller,
1218 ) -> Result<Option<Ordering>, VmError> {
1219 self.bin_op_with(
1220 b,
1221 caller,
1222 &Protocol::PARTIAL_CMP,
1223 Inline::partial_cmp,
1224 |lhs, rhs, caller| {
1225 let ord = lhs.0.variant_hash.cmp(&rhs.0.variant_hash);
1226
1227 if ord != Ordering::Equal {
1228 return Ok(Some(ord));
1229 }
1230
1231 Vec::partial_cmp_with(lhs.1, rhs.1, caller)
1232 },
1233 )
1234 }
1235
1236 pub fn cmp(a: &Value, b: &Value) -> Result<Ordering, VmError> {
1247 Value::cmp_with(a, b, &mut EnvProtocolCaller)
1248 }
1249
1250 #[cfg_attr(feature = "bench", inline(never))]
1254 pub(crate) fn cmp_with(
1255 &self,
1256 b: &Value,
1257 caller: &mut dyn ProtocolCaller,
1258 ) -> Result<Ordering, VmError> {
1259 self.bin_op_with(
1260 b,
1261 caller,
1262 &Protocol::CMP,
1263 Inline::cmp,
1264 |lhs, rhs, caller| {
1265 let ord = lhs.0.variant_hash.cmp(&rhs.0.variant_hash);
1266
1267 if ord != Ordering::Equal {
1268 return Ok(ord);
1269 }
1270
1271 Vec::cmp_with(lhs.1, rhs.1, caller)
1272 },
1273 )
1274 }
1275
1276 pub fn hash(&self, hasher: &mut Hasher) -> Result<(), VmError> {
1278 self.hash_with(hasher, &mut EnvProtocolCaller)
1279 }
1280
1281 #[cfg_attr(feature = "bench", inline(never))]
1283 pub(crate) fn hash_with(
1284 &self,
1285 hasher: &mut Hasher,
1286 caller: &mut dyn ProtocolCaller,
1287 ) -> Result<(), VmError> {
1288 match self.as_ref() {
1289 Repr::Inline(value) => {
1290 value.hash(hasher)?;
1291 return Ok(());
1292 }
1293 Repr::Any(value) => match value.type_hash() {
1294 Vec::HASH => {
1295 let vec = value.borrow_ref::<Vec>()?;
1296 return Vec::hash_with(&vec, hasher, caller);
1297 }
1298 OwnedTuple::HASH => {
1299 let tuple = value.borrow_ref::<OwnedTuple>()?;
1300 return Tuple::hash_with(&tuple, hasher, caller);
1301 }
1302 _ => {}
1303 },
1304 _ => {}
1305 }
1306
1307 let mut args = DynGuardedArgs::new((hasher,));
1308
1309 if let CallResultOnly::Ok(value) =
1310 caller.try_call_protocol_fn(&Protocol::HASH, self.clone(), &mut args)?
1311 {
1312 <()>::from_value(value)?;
1313 return Ok(());
1314 }
1315
1316 Err(VmError::new(VmErrorKind::UnsupportedUnaryOperation {
1317 op: Protocol::HASH.name,
1318 operand: self.type_info(),
1319 }))
1320 }
1321
1322 fn bin_op_with<T>(
1323 &self,
1324 b: &Value,
1325 caller: &mut dyn ProtocolCaller,
1326 protocol: &'static Protocol,
1327 inline: fn(&Inline, &Inline) -> Result<T, RuntimeError>,
1328 dynamic: fn(
1329 (&Arc<Rtti>, &[Value]),
1330 (&Arc<Rtti>, &[Value]),
1331 &mut dyn ProtocolCaller,
1332 ) -> Result<T, VmError>,
1333 ) -> Result<T, VmError>
1334 where
1335 T: FromValue,
1336 {
1337 match (self.as_ref(), b.as_ref()) {
1338 (Repr::Inline(lhs), Repr::Inline(rhs)) => return Ok(inline(lhs, rhs)?),
1339 (Repr::Inline(lhs), rhs) => {
1340 return Err(VmError::new(VmErrorKind::UnsupportedBinaryOperation {
1341 op: protocol.name,
1342 lhs: lhs.type_info(),
1343 rhs: rhs.type_info(),
1344 }));
1345 }
1346 (Repr::Dynamic(lhs), Repr::Dynamic(rhs)) => {
1347 let lhs_rtti = lhs.rtti();
1348 let rhs_rtti = rhs.rtti();
1349
1350 let lhs = lhs.borrow_ref()?;
1351 let rhs = rhs.borrow_ref()?;
1352
1353 if lhs_rtti.hash == rhs_rtti.hash {
1354 return dynamic((lhs_rtti, &lhs), (rhs_rtti, &rhs), caller);
1355 }
1356
1357 return Err(VmError::new(VmErrorKind::UnsupportedBinaryOperation {
1358 op: protocol.name,
1359 lhs: Rtti::type_info(lhs_rtti.clone()),
1360 rhs: Rtti::type_info(rhs_rtti.clone()),
1361 }));
1362 }
1363 _ => {}
1364 }
1365
1366 if let CallResultOnly::Ok(value) =
1367 caller.try_call_protocol_fn(protocol, self.clone(), &mut Some((b.clone(),)))?
1368 {
1369 return Ok(T::from_value(value)?);
1370 }
1371
1372 Err(VmError::new(VmErrorKind::UnsupportedBinaryOperation {
1373 op: protocol.name,
1374 lhs: self.type_info(),
1375 rhs: b.type_info(),
1376 }))
1377 }
1378
1379 pub fn as_integer<T>(&self) -> Result<T, RuntimeError>
1392 where
1393 T: TryFrom<u64> + TryFrom<i64>,
1394 {
1395 match self.repr {
1396 Repr::Inline(value) => value.as_integer(),
1397 Repr::Dynamic(ref value) => Err(RuntimeError::new(VmErrorKind::ExpectedNumber {
1398 actual: value.type_info(),
1399 })),
1400 Repr::Any(ref value) => Err(RuntimeError::new(VmErrorKind::ExpectedNumber {
1401 actual: value.type_info(),
1402 })),
1403 }
1404 }
1405
1406 pub(crate) fn as_inline_unchecked(&self) -> Option<&Inline> {
1407 match &self.repr {
1408 Repr::Inline(value) => Some(value),
1409 _ => None,
1410 }
1411 }
1412
1413 pub(crate) fn is_inline(&self) -> bool {
1415 matches!(self.repr, Repr::Inline(..))
1416 }
1417
1418 #[inline]
1422 pub(crate) fn as_inline(&self) -> Option<&Inline> {
1423 match &self.repr {
1424 Repr::Inline(value) => Some(value),
1425 Repr::Dynamic(..) => None,
1426 Repr::Any(..) => None,
1427 }
1428 }
1429
1430 #[inline]
1431 pub(crate) fn as_inline_mut(&mut self) -> Option<&mut Inline> {
1432 match &mut self.repr {
1433 Repr::Inline(value) => Some(value),
1434 Repr::Dynamic(..) => None,
1435 Repr::Any(..) => None,
1436 }
1437 }
1438
1439 #[inline]
1443 pub fn as_any(&self) -> Option<&AnyObj> {
1444 match &self.repr {
1445 Repr::Inline(..) => None,
1446 Repr::Dynamic(..) => None,
1447 Repr::Any(value) => Some(value),
1448 }
1449 }
1450
1451 #[inline(always)]
1452 pub(crate) fn take_repr(self) -> Repr {
1453 self.repr
1454 }
1455
1456 #[inline(always)]
1457 pub(crate) fn as_ref(&self) -> &Repr {
1458 &self.repr
1459 }
1460
1461 #[inline(always)]
1462 pub(crate) fn as_mut(&mut self) -> &mut Repr {
1463 &mut self.repr
1464 }
1465
1466 #[inline]
1467 pub(crate) fn try_borrow_ref<T>(&self) -> Result<Option<BorrowRef<'_, T>>, AccessError>
1468 where
1469 T: Any,
1470 {
1471 match &self.repr {
1472 Repr::Inline(..) => Ok(None),
1473 Repr::Dynamic(..) => Ok(None),
1474 Repr::Any(value) => value.try_borrow_ref(),
1475 }
1476 }
1477
1478 #[inline]
1479 pub(crate) fn try_borrow_mut<T>(&self) -> Result<Option<BorrowMut<'_, T>>, AccessError>
1480 where
1481 T: Any,
1482 {
1483 match &self.repr {
1484 Repr::Inline(..) => Ok(None),
1485 Repr::Dynamic(..) => Ok(None),
1486 Repr::Any(value) => value.try_borrow_mut(),
1487 }
1488 }
1489
1490 pub(crate) fn protocol_into_iter(&self) -> Result<Value, VmError> {
1491 EnvProtocolCaller.call_protocol_fn(&Protocol::INTO_ITER, self.clone(), &mut ())
1492 }
1493
1494 pub(crate) fn protocol_next(&self) -> Result<Option<Value>, VmError> {
1495 let value = EnvProtocolCaller.call_protocol_fn(&Protocol::NEXT, self.clone(), &mut ())?;
1496
1497 Ok(FromValue::from_value(value)?)
1498 }
1499
1500 pub(crate) fn protocol_next_back(&self) -> Result<Option<Value>, VmError> {
1501 let value =
1502 EnvProtocolCaller.call_protocol_fn(&Protocol::NEXT_BACK, self.clone(), &mut ())?;
1503
1504 Ok(FromValue::from_value(value)?)
1505 }
1506
1507 pub(crate) fn protocol_nth_back(&self, n: usize) -> Result<Option<Value>, VmError> {
1508 let value = EnvProtocolCaller.call_protocol_fn(
1509 &Protocol::NTH_BACK,
1510 self.clone(),
1511 &mut Some((n,)),
1512 )?;
1513
1514 Ok(FromValue::from_value(value)?)
1515 }
1516
1517 pub(crate) fn protocol_len(&self) -> Result<usize, VmError> {
1518 let value = EnvProtocolCaller.call_protocol_fn(&Protocol::LEN, self.clone(), &mut ())?;
1519
1520 Ok(FromValue::from_value(value)?)
1521 }
1522
1523 pub(crate) fn protocol_size_hint(&self) -> Result<(usize, Option<usize>), VmError> {
1524 let value =
1525 EnvProtocolCaller.call_protocol_fn(&Protocol::SIZE_HINT, self.clone(), &mut ())?;
1526
1527 Ok(FromValue::from_value(value)?)
1528 }
1529}
1530
1531impl fmt::Debug for Value {
1532 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1533 match &self.repr {
1534 Repr::Inline(value) => {
1535 write!(f, "{value:?}")?;
1536 }
1537 _ => {
1538 let mut s = String::new();
1539 let result = Formatter::format_with(&mut s, |f| self.debug_fmt(f));
1540
1541 if let Err(e) = result {
1542 match &self.repr {
1543 Repr::Inline(value) => {
1544 write!(f, "<{value:?}: {e}>")?;
1545 }
1546 Repr::Dynamic(value) => {
1547 let ty = value.type_info();
1548 write!(f, "<{ty} object at {value:p}: {e}>")?;
1549 }
1550 Repr::Any(value) => {
1551 let ty = value.type_info();
1552 write!(f, "<{ty} object at {value:p}: {e}>")?;
1553 }
1554 }
1555
1556 return Ok(());
1557 }
1558
1559 f.write_str(s.as_str())?;
1560 }
1561 }
1562
1563 Ok(())
1564 }
1565}
1566
1567impl From<Repr> for Value {
1568 #[inline]
1569 fn from(repr: Repr) -> Self {
1570 Self { repr }
1571 }
1572}
1573
1574impl From<()> for Value {
1575 #[inline]
1576 fn from((): ()) -> Self {
1577 Value::from(Inline::Unit)
1578 }
1579}
1580
1581impl From<Inline> for Value {
1582 #[inline]
1583 fn from(value: Inline) -> Self {
1584 Self {
1585 repr: Repr::Inline(value),
1586 }
1587 }
1588}
1589
1590impl From<AnyObj> for Value {
1608 #[inline]
1609 fn from(value: AnyObj) -> Self {
1610 Self {
1611 repr: Repr::Any(value),
1612 }
1613 }
1614}
1615
1616impl<T> From<Shared<T>> for Value
1634where
1635 T: Any,
1636{
1637 #[inline]
1638 fn from(value: Shared<T>) -> Self {
1639 Self {
1640 repr: Repr::Any(value.into_any_obj()),
1641 }
1642 }
1643}
1644
1645impl From<AnySequence<Arc<Rtti>, Value>> for Value {
1646 #[inline]
1647 fn from(value: AnySequence<Arc<Rtti>, Value>) -> Self {
1648 Self {
1649 repr: Repr::Dynamic(value),
1650 }
1651 }
1652}
1653
1654impl TryFrom<&str> for Value {
1655 type Error = alloc::Error;
1656
1657 #[inline]
1658 fn try_from(value: &str) -> Result<Self, Self::Error> {
1659 Value::new(String::try_from(value)?)
1660 }
1661}
1662
1663inline_from! {
1664 Bool => bool,
1665 Char => char,
1666 Signed => i64,
1667 Unsigned => u64,
1668 Float => f64,
1669 Type => Type,
1670 Ordering => Ordering,
1671 Hash => Hash,
1672}
1673
1674any_from! {
1675 crate::alloc::String,
1676 super::Bytes,
1677 super::Format,
1678 super::ControlFlow,
1679 super::GeneratorState,
1680 super::Vec,
1681 super::OwnedTuple,
1682 super::Generator,
1683 super::Stream,
1684 super::Function,
1685 super::Future,
1686 super::Object,
1687 Option<Value>,
1688 Result<Value, Value>,
1689}
1690
1691signed_value_from!(i8, i16, i32);
1692signed_value_try_from!(i128, isize);
1693unsigned_value_from!(u8, u16, u32);
1694unsigned_value_try_from!(u128, usize);
1695signed_value_trait!(i8, i16, i32, i128, isize);
1696unsigned_value_trait!(u8, u16, u32, u128, usize);
1697float_value_trait!(f32);
1698
1699impl MaybeTypeOf for Value {
1700 #[inline]
1701 fn maybe_type_of() -> alloc::Result<meta::DocType> {
1702 Ok(meta::DocType::empty())
1703 }
1704}
1705
1706impl Clone for Value {
1707 #[inline]
1708 fn clone(&self) -> Self {
1709 let repr = match &self.repr {
1710 Repr::Inline(inline) => Repr::Inline(*inline),
1711 Repr::Dynamic(mutable) => Repr::Dynamic(mutable.clone()),
1712 Repr::Any(any) => Repr::Any(any.clone()),
1713 };
1714
1715 Self { repr }
1716 }
1717
1718 #[inline]
1719 fn clone_from(&mut self, source: &Self) {
1720 match (&mut self.repr, &source.repr) {
1721 (Repr::Inline(lhs), Repr::Inline(rhs)) => {
1722 *lhs = *rhs;
1723 }
1724 (Repr::Dynamic(lhs), Repr::Dynamic(rhs)) => {
1725 lhs.clone_from(rhs);
1726 }
1727 (Repr::Any(lhs), Repr::Any(rhs)) => {
1728 lhs.clone_from(rhs);
1729 }
1730 (lhs, rhs) => {
1731 *lhs = rhs.clone();
1732 }
1733 }
1734 }
1735}
1736
1737impl TryClone for Value {
1738 fn try_clone(&self) -> alloc::Result<Self> {
1739 Ok(self.clone())
1741 }
1742}
1743
1744#[doc(hidden)]
1746pub struct NotTypedInline(Inline);
1747
1748#[doc(hidden)]
1750pub struct NotTypedAnyObj<'a>(&'a AnyObj);
1751
1752#[non_exhaustive]
1754#[doc(hidden)]
1755pub enum TypeValue<'a> {
1756 Unit,
1758 Tuple(BorrowRef<'a, OwnedTuple>),
1760 Object(BorrowRef<'a, Object>),
1762 EmptyStruct(EmptyStruct<'a>),
1764 TupleStruct(TupleStruct<'a>),
1766 Struct(Struct<'a>),
1768 #[doc(hidden)]
1770 NotTypedInline(NotTypedInline),
1771 #[doc(hidden)]
1773 NotTypedAnyObj(NotTypedAnyObj<'a>),
1774}
1775
1776impl TypeValue<'_> {
1777 #[doc(hidden)]
1779 pub fn type_info(&self) -> TypeInfo {
1780 match self {
1781 TypeValue::Unit => TypeInfo::any::<OwnedTuple>(),
1782 TypeValue::Tuple(..) => TypeInfo::any::<OwnedTuple>(),
1783 TypeValue::Object(..) => TypeInfo::any::<Object>(),
1784 TypeValue::EmptyStruct(empty) => empty.type_info(),
1785 TypeValue::TupleStruct(tuple) => tuple.type_info(),
1786 TypeValue::Struct(object) => object.type_info(),
1787 TypeValue::NotTypedInline(value) => value.0.type_info(),
1788 TypeValue::NotTypedAnyObj(value) => value.0.type_info(),
1789 }
1790 }
1791}
1792
1793#[test]
1796fn size_of_value() {
1797 use core::mem::size_of;
1798
1799 assert_eq!(size_of::<Repr>(), size_of::<Inline>());
1800 assert_eq!(size_of::<Repr>(), size_of::<Value>());
1801 assert_eq!(size_of::<Option<Value>>(), size_of::<Value>());
1802 assert_eq!(size_of::<Option<Repr>>(), size_of::<Repr>());
1803}