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 #[inline]
347 pub(crate) fn is_empty(&self) -> bool {
348 matches!(self.repr, Repr::Inline(Inline::Empty))
349 }
350
351 pub(crate) const fn unit() -> Self {
353 Self {
354 repr: Repr::Inline(Inline::Unit),
355 }
356 }
357
358 pub const fn empty() -> Self {
360 Self {
361 repr: Repr::Inline(Inline::Empty),
362 }
363 }
364
365 pub fn display_fmt(&self, f: &mut Formatter) -> Result<(), VmError> {
378 self.display_fmt_with(f, &mut EnvProtocolCaller)
379 }
380
381 #[cfg_attr(feature = "bench", inline(never))]
383 pub(crate) fn display_fmt_with(
384 &self,
385 f: &mut Formatter,
386 caller: &mut dyn ProtocolCaller,
387 ) -> Result<(), VmError> {
388 'fallback: {
389 match self.as_ref() {
390 Repr::Inline(value) => match value {
391 Inline::Char(c) => {
392 f.try_write_char(*c)?;
393 }
394 Inline::Unsigned(byte) => {
395 let mut buffer = itoa::Buffer::new();
396 f.try_write_str(buffer.format(*byte))?;
397 }
398 Inline::Signed(integer) => {
399 let mut buffer = itoa::Buffer::new();
400 f.try_write_str(buffer.format(*integer))?;
401 }
402 Inline::Float(float) => {
403 let mut buffer = ryu::Buffer::new();
404 f.try_write_str(buffer.format(*float))?;
405 }
406 Inline::Bool(bool) => {
407 write!(f, "{bool}")?;
408 }
409 _ => {
410 break 'fallback;
411 }
412 },
413 _ => {
414 break 'fallback;
415 }
416 }
417
418 return Ok(());
419 };
420
421 let mut args = DynGuardedArgs::new((f,));
422
423 let result = caller.call_protocol_fn(&Protocol::DISPLAY_FMT, self.clone(), &mut args)?;
424
425 <()>::from_value(result)?;
426 Ok(())
427 }
428
429 pub fn clone_(&self) -> Result<Self, VmError> {
442 self.clone_with(&mut EnvProtocolCaller)
443 }
444
445 pub(crate) fn clone_with(&self, caller: &mut dyn ProtocolCaller) -> Result<Value, VmError> {
446 match self.as_ref() {
447 Repr::Inline(value) => {
448 return Ok(Self {
449 repr: Repr::Inline(*value),
450 });
451 }
452 Repr::Dynamic(value) => {
453 return Ok(Self {
455 repr: Repr::Dynamic(value.clone()),
456 });
457 }
458 Repr::Any(..) => {}
459 }
460
461 caller.call_protocol_fn(&Protocol::CLONE, self.clone(), &mut ())
462 }
463
464 pub fn debug_fmt(&self, f: &mut Formatter) -> Result<(), VmError> {
477 self.debug_fmt_with(f, &mut EnvProtocolCaller)
478 }
479
480 pub(crate) fn debug_fmt_with(
482 &self,
483 f: &mut Formatter,
484 caller: &mut dyn ProtocolCaller,
485 ) -> Result<(), VmError> {
486 match &self.repr {
487 Repr::Inline(value) => {
488 write!(f, "{value:?}")?;
489 }
490 Repr::Dynamic(ref value) => {
491 value.debug_fmt_with(f, caller)?;
492 }
493 Repr::Any(..) => {
494 let mut args = DynGuardedArgs::new((&mut *f,));
496
497 match caller.try_call_protocol_fn(&Protocol::DEBUG_FMT, self.clone(), &mut args)? {
498 CallResultOnly::Ok(value) => {
499 <()>::from_value(value)?;
500 }
501 CallResultOnly::Unsupported(value) => match &value.repr {
502 Repr::Inline(value) => {
503 write!(f, "{value:?}")?;
504 }
505 Repr::Dynamic(value) => {
506 let ty = value.type_info();
507 write!(f, "<{ty} object at {value:p}>")?;
508 }
509 Repr::Any(value) => {
510 let ty = value.type_info();
511 write!(f, "<{ty} object at {value:p}>")?;
512 }
513 },
514 }
515 }
516 }
517
518 Ok(())
519 }
520
521 pub fn into_iter(self) -> Result<Iterator, VmError> {
533 self.into_iter_with(&mut EnvProtocolCaller)
534 }
535
536 pub(crate) fn into_iter_with(
537 self,
538 caller: &mut dyn ProtocolCaller,
539 ) -> Result<Iterator, VmError> {
540 let value = caller.call_protocol_fn(&Protocol::INTO_ITER, self, &mut ())?;
541 Ok(Iterator::new(value))
542 }
543
544 pub fn into_type_name(self) -> Result<String, VmError> {
559 let hash = Hash::associated_function(self.type_hash(), &Protocol::INTO_TYPE_NAME);
560
561 crate::runtime::env::shared(|context, unit, _| {
562 if let Some(name) = context.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 if let Some(name) = unit.constant(&hash) {
574 match name.as_kind() {
575 ConstValueKind::String(s) => return Ok(String::try_from(s.as_ref())?),
576 _ => {
577 return Err(VmError::new(VmErrorKind::expected::<String>(
578 name.type_info(),
579 )))
580 }
581 }
582 }
583
584 Ok(self.type_info().try_to_string()?)
585 })
586 }
587
588 pub fn vec(vec: alloc::Vec<Value>) -> alloc::Result<Self> {
590 let data = Vec::from(vec);
591 Value::try_from(data)
592 }
593
594 pub fn tuple(vec: alloc::Vec<Value>) -> alloc::Result<Self> {
596 Value::try_from(OwnedTuple::try_from(vec)?)
597 }
598
599 pub fn empty_struct(rtti: Arc<Rtti>) -> alloc::Result<Self> {
601 Ok(Value::from(AnySequence::new(rtti, [])?))
602 }
603
604 pub fn tuple_struct(
606 rtti: Arc<Rtti>,
607 data: impl IntoIterator<IntoIter: ExactSizeIterator, Item = Value>,
608 ) -> alloc::Result<Self> {
609 Ok(Value::from(AnySequence::new(rtti, data)?))
610 }
611
612 pub(crate) fn drop(self) -> Result<(), VmError> {
617 match self.repr {
618 Repr::Dynamic(value) => {
619 value.drop()?;
620 }
621 Repr::Any(value) => {
622 value.drop()?;
623 }
624 _ => {}
625 }
626
627 Ok(())
628 }
629
630 pub(crate) fn move_(self) -> Result<Self, VmError> {
632 match self.repr {
633 Repr::Dynamic(value) => Ok(Value {
634 repr: Repr::Dynamic(value.take()?),
635 }),
636 Repr::Any(value) => Ok(Value {
637 repr: Repr::Any(value.take()?),
638 }),
639 repr => Ok(Value { repr }),
640 }
641 }
642
643 #[inline]
645 pub fn as_usize(&self) -> Result<usize, RuntimeError> {
646 self.as_integer()
647 }
648
649 #[deprecated(
651 note = "For consistency with other methods, this has been renamed Value::borrow_string_ref"
652 )]
653 #[inline]
654 pub fn as_string(&self) -> Result<BorrowRef<'_, str>, RuntimeError> {
655 self.borrow_string_ref()
656 }
657
658 pub fn borrow_string_ref(&self) -> Result<BorrowRef<'_, str>, RuntimeError> {
660 let string = self.borrow_ref::<String>()?;
661 Ok(BorrowRef::map(string, String::as_str))
662 }
663
664 #[inline]
666 pub fn into_string(self) -> Result<String, RuntimeError> {
667 match self.take_repr() {
668 Repr::Any(value) => Ok(value.downcast()?),
669 actual => Err(RuntimeError::expected::<String>(actual.type_info())),
670 }
671 }
672
673 #[doc(hidden)]
675 #[inline]
676 pub fn as_type_value(&self) -> Result<TypeValue<'_>, RuntimeError> {
677 match self.as_ref() {
678 Repr::Inline(value) => match value {
679 Inline::Unit => Ok(TypeValue::Unit),
680 value => Ok(TypeValue::NotTypedInline(NotTypedInline(*value))),
681 },
682 Repr::Dynamic(value) => match value.rtti().kind {
683 RttiKind::Empty => Ok(TypeValue::EmptyStruct(EmptyStruct { rtti: value.rtti() })),
684 RttiKind::Tuple => Ok(TypeValue::TupleStruct(TupleStruct {
685 rtti: value.rtti(),
686 data: value.borrow_ref()?,
687 })),
688 RttiKind::Struct => Ok(TypeValue::Struct(Struct {
689 rtti: value.rtti(),
690 data: value.borrow_ref()?,
691 })),
692 },
693 Repr::Any(value) => match value.type_hash() {
694 OwnedTuple::HASH => Ok(TypeValue::Tuple(value.borrow_ref()?)),
695 Object::HASH => Ok(TypeValue::Object(value.borrow_ref()?)),
696 _ => Ok(TypeValue::NotTypedAnyObj(NotTypedAnyObj(value))),
697 },
698 }
699 }
700
701 #[inline]
703 pub fn into_unit(&self) -> Result<(), RuntimeError> {
704 match self.as_ref() {
705 Repr::Inline(Inline::Unit) => Ok(()),
706 value => Err(RuntimeError::expected::<()>(value.type_info())),
707 }
708 }
709
710 inline_into! {
711 Ordering(Ordering),
713 as_ordering,
714 as_ordering_mut,
715 }
716
717 inline_into! {
718 Hash(Hash),
720 as_hash,
721 as_hash_mut,
722 }
723
724 inline_into! {
725 Bool(bool),
727 as_bool,
728 as_bool_mut,
729 }
730
731 inline_into! {
732 Char(char),
734 as_char,
735 as_char_mut,
736 }
737
738 inline_into! {
739 Signed(i64),
741 as_signed,
742 as_signed_mut,
743 }
744
745 inline_into! {
746 Unsigned(u64),
748 as_unsigned,
749 as_unsigned_mut,
750 }
751
752 inline_into! {
753 Float(f64),
755 as_float,
756 as_float_mut,
757 }
758
759 inline_into! {
760 Type(Type),
762 as_type,
763 as_type_mut,
764 }
765
766 #[inline]
771 pub fn borrow_tuple_ref(&self) -> Result<BorrowRef<'_, Tuple>, RuntimeError> {
772 match self.as_ref() {
773 Repr::Inline(Inline::Unit) => Ok(BorrowRef::from_static(Tuple::new(&[]))),
774 Repr::Inline(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
775 Repr::Dynamic(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
776 Repr::Any(value) => {
777 let value = value.borrow_ref::<OwnedTuple>()?;
778 let value = BorrowRef::map(value, OwnedTuple::as_ref);
779 Ok(value)
780 }
781 }
782 }
783
784 #[inline]
789 pub fn borrow_tuple_mut(&self) -> Result<BorrowMut<'_, Tuple>, RuntimeError> {
790 match self.as_ref() {
791 Repr::Inline(Inline::Unit) => Ok(BorrowMut::from_ref(Tuple::new_mut(&mut []))),
792 Repr::Inline(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
793 Repr::Dynamic(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
794 Repr::Any(value) => {
795 let value = value.borrow_mut::<OwnedTuple>()?;
796 let value = BorrowMut::map(value, OwnedTuple::as_mut);
797 Ok(value)
798 }
799 }
800 }
801
802 #[inline]
807 pub fn into_tuple(&self) -> Result<Box<Tuple>, RuntimeError> {
808 match self.as_ref() {
809 Repr::Inline(Inline::Unit) => Ok(Tuple::from_boxed(Box::default())),
810 Repr::Inline(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
811 Repr::Dynamic(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
812 Repr::Any(value) => Ok(value.clone().downcast::<OwnedTuple>()?.into_boxed_tuple()),
813 }
814 }
815
816 #[inline]
821 pub fn into_tuple_ref(&self) -> Result<Ref<Tuple>, RuntimeError> {
822 match self.as_ref() {
823 Repr::Inline(Inline::Unit) => Ok(Ref::from_static(Tuple::new(&[]))),
824 Repr::Inline(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
825 Repr::Dynamic(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
826 Repr::Any(value) => {
827 let value = value.clone().into_ref::<OwnedTuple>()?;
828 let value = Ref::map(value, OwnedTuple::as_ref);
829 Ok(value)
830 }
831 }
832 }
833
834 #[inline]
839 pub fn into_tuple_mut(&self) -> Result<Mut<Tuple>, RuntimeError> {
840 match self.as_ref() {
841 Repr::Inline(Inline::Unit) => Ok(Mut::from_static(Tuple::new_mut(&mut []))),
842 Repr::Inline(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
843 Repr::Dynamic(value) => Err(RuntimeError::expected::<Tuple>(value.type_info())),
844 Repr::Any(value) => {
845 let value = value.clone().into_mut::<OwnedTuple>()?;
846 let value = Mut::map(value, OwnedTuple::as_mut);
847 Ok(value)
848 }
849 }
850 }
851
852 #[inline]
854 pub fn into_any_obj(self) -> Result<AnyObj, RuntimeError> {
855 match self.repr {
856 Repr::Inline(value) => Err(RuntimeError::expected_any_obj(value.type_info())),
857 Repr::Dynamic(value) => Err(RuntimeError::expected_any_obj(value.type_info())),
858 Repr::Any(value) => Ok(value),
859 }
860 }
861
862 #[inline]
867 pub fn into_shared<T>(self) -> Result<Shared<T>, RuntimeError>
868 where
869 T: Any,
870 {
871 match self.repr {
872 Repr::Inline(value) => Err(RuntimeError::expected_any_obj(value.type_info())),
873 Repr::Dynamic(value) => Err(RuntimeError::expected_any_obj(value.type_info())),
874 Repr::Any(value) => Ok(value.into_shared()?),
875 }
876 }
877
878 #[inline]
894 pub fn into_future(self) -> Result<Future, RuntimeError> {
895 let target = match self.repr {
896 Repr::Any(value) => match value.type_hash() {
897 Future::HASH => {
898 return Ok(value.downcast::<Future>()?);
899 }
900 _ => Value::from(value),
901 },
902 repr => Value::from(repr),
903 };
904
905 let value = EnvProtocolCaller.call_protocol_fn(&Protocol::INTO_FUTURE, target, &mut ())?;
906
907 Future::from_value(value)
908 }
909
910 #[inline]
917 pub fn into_any_ref_ptr<T>(self) -> Result<(NonNull<T>, RawValueGuard), RuntimeError>
918 where
919 T: Any,
920 {
921 match self.repr {
922 Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
923 Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
924 Repr::Any(value) => {
925 let (ptr, guard) = value.borrow_ref_ptr::<T>()?;
926 let guard = RawValueGuard { guard };
927 Ok((ptr, guard))
928 }
929 }
930 }
931
932 #[inline]
939 #[doc(hidden)]
940 pub fn into_any_mut_ptr<T>(self) -> Result<(NonNull<T>, RawValueGuard), RuntimeError>
941 where
942 T: Any,
943 {
944 match self.repr {
945 Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
946 Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
947 Repr::Any(value) => {
948 let (ptr, guard) = value.borrow_mut_ptr::<T>()?;
949 let guard = RawValueGuard { guard };
950 Ok((ptr, guard))
951 }
952 }
953 }
954
955 #[inline]
985 pub fn downcast<T>(self) -> Result<T, RuntimeError>
986 where
987 T: Any,
988 {
989 match self.repr {
990 Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
991 Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
992 Repr::Any(value) => Ok(value.downcast::<T>()?),
993 }
994 }
995
996 #[inline]
1018 pub fn borrow_ref<T>(&self) -> Result<BorrowRef<'_, T>, RuntimeError>
1019 where
1020 T: Any,
1021 {
1022 match &self.repr {
1023 Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1024 Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1025 Repr::Any(value) => Ok(value.borrow_ref()?),
1026 }
1027 }
1028
1029 #[inline]
1050 pub fn into_ref<T>(self) -> Result<Ref<T>, RuntimeError>
1051 where
1052 T: Any,
1053 {
1054 match self.repr {
1055 Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1056 Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1057 Repr::Any(value) => Ok(value.into_ref()?),
1058 }
1059 }
1060
1061 #[inline]
1063 pub fn borrow_mut<T>(&self) -> Result<BorrowMut<'_, T>, RuntimeError>
1064 where
1065 T: Any,
1066 {
1067 match &self.repr {
1068 Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1069 Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1070 Repr::Any(value) => Ok(value.borrow_mut()?),
1071 }
1072 }
1073
1074 #[inline]
1103 pub fn into_mut<T>(self) -> Result<Mut<T>, RuntimeError>
1104 where
1105 T: Any,
1106 {
1107 match self.repr {
1108 Repr::Inline(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1109 Repr::Dynamic(value) => Err(RuntimeError::expected_any::<T>(value.type_info())),
1110 Repr::Any(value) => Ok(value.into_mut()?),
1111 }
1112 }
1113
1114 #[inline(always)]
1119 pub fn type_hash(&self) -> Hash {
1120 match &self.repr {
1121 Repr::Inline(value) => value.type_hash(),
1122 Repr::Dynamic(value) => value.type_hash(),
1123 Repr::Any(value) => value.type_hash(),
1124 }
1125 }
1126
1127 #[inline(always)]
1129 pub fn type_info(&self) -> TypeInfo {
1130 match &self.repr {
1131 Repr::Inline(value) => value.type_info(),
1132 Repr::Dynamic(value) => value.type_info(),
1133 Repr::Any(value) => value.type_info(),
1134 }
1135 }
1136
1137 pub fn partial_eq(a: &Value, b: &Value) -> Result<bool, VmError> {
1148 Self::partial_eq_with(a, b, &mut EnvProtocolCaller)
1149 }
1150
1151 #[cfg_attr(feature = "bench", inline(never))]
1155 pub(crate) fn partial_eq_with(
1156 &self,
1157 b: &Value,
1158 caller: &mut dyn ProtocolCaller,
1159 ) -> Result<bool, VmError> {
1160 self.bin_op_with(
1161 b,
1162 caller,
1163 &Protocol::PARTIAL_EQ,
1164 Inline::partial_eq,
1165 |lhs, rhs, caller| {
1166 if lhs.0.variant_hash != rhs.0.variant_hash {
1167 return Ok(false);
1168 }
1169
1170 Vec::eq_with(lhs.1, rhs.1, Value::partial_eq_with, caller)
1171 },
1172 )
1173 }
1174
1175 pub fn eq(&self, b: &Value) -> Result<bool, VmError> {
1186 self.eq_with(b, &mut EnvProtocolCaller)
1187 }
1188
1189 #[cfg_attr(feature = "bench", inline(never))]
1193 pub(crate) fn eq_with(
1194 &self,
1195 b: &Value,
1196 caller: &mut dyn ProtocolCaller,
1197 ) -> Result<bool, VmError> {
1198 self.bin_op_with(b, caller, &Protocol::EQ, Inline::eq, |lhs, rhs, caller| {
1199 if lhs.0.variant_hash != rhs.0.variant_hash {
1200 return Ok(false);
1201 }
1202
1203 Vec::eq_with(lhs.1, rhs.1, Value::eq_with, caller)
1204 })
1205 }
1206
1207 pub fn partial_cmp(a: &Value, b: &Value) -> Result<Option<Ordering>, VmError> {
1218 Value::partial_cmp_with(a, b, &mut EnvProtocolCaller)
1219 }
1220
1221 #[cfg_attr(feature = "bench", inline(never))]
1225 pub(crate) fn partial_cmp_with(
1226 &self,
1227 b: &Value,
1228 caller: &mut dyn ProtocolCaller,
1229 ) -> Result<Option<Ordering>, VmError> {
1230 self.bin_op_with(
1231 b,
1232 caller,
1233 &Protocol::PARTIAL_CMP,
1234 Inline::partial_cmp,
1235 |lhs, rhs, caller| {
1236 let ord = lhs.0.variant_hash.cmp(&rhs.0.variant_hash);
1237
1238 if ord != Ordering::Equal {
1239 return Ok(Some(ord));
1240 }
1241
1242 Vec::partial_cmp_with(lhs.1, rhs.1, caller)
1243 },
1244 )
1245 }
1246
1247 pub fn cmp(a: &Value, b: &Value) -> Result<Ordering, VmError> {
1258 Value::cmp_with(a, b, &mut EnvProtocolCaller)
1259 }
1260
1261 #[cfg_attr(feature = "bench", inline(never))]
1265 pub(crate) fn cmp_with(
1266 &self,
1267 b: &Value,
1268 caller: &mut dyn ProtocolCaller,
1269 ) -> Result<Ordering, VmError> {
1270 self.bin_op_with(
1271 b,
1272 caller,
1273 &Protocol::CMP,
1274 Inline::cmp,
1275 |lhs, rhs, caller| {
1276 let ord = lhs.0.variant_hash.cmp(&rhs.0.variant_hash);
1277
1278 if ord != Ordering::Equal {
1279 return Ok(ord);
1280 }
1281
1282 Vec::cmp_with(lhs.1, rhs.1, caller)
1283 },
1284 )
1285 }
1286
1287 pub fn hash(&self, hasher: &mut Hasher) -> Result<(), VmError> {
1289 self.hash_with(hasher, &mut EnvProtocolCaller)
1290 }
1291
1292 #[cfg_attr(feature = "bench", inline(never))]
1294 pub(crate) fn hash_with(
1295 &self,
1296 hasher: &mut Hasher,
1297 caller: &mut dyn ProtocolCaller,
1298 ) -> Result<(), VmError> {
1299 match self.as_ref() {
1300 Repr::Inline(value) => {
1301 value.hash(hasher)?;
1302 return Ok(());
1303 }
1304 Repr::Any(value) => match value.type_hash() {
1305 Vec::HASH => {
1306 let vec = value.borrow_ref::<Vec>()?;
1307 return Vec::hash_with(&vec, hasher, caller);
1308 }
1309 OwnedTuple::HASH => {
1310 let tuple = value.borrow_ref::<OwnedTuple>()?;
1311 return Tuple::hash_with(&tuple, hasher, caller);
1312 }
1313 _ => {}
1314 },
1315 _ => {}
1316 }
1317
1318 let mut args = DynGuardedArgs::new((hasher,));
1319
1320 if let CallResultOnly::Ok(value) =
1321 caller.try_call_protocol_fn(&Protocol::HASH, self.clone(), &mut args)?
1322 {
1323 <()>::from_value(value)?;
1324 return Ok(());
1325 }
1326
1327 Err(VmError::new(VmErrorKind::UnsupportedUnaryOperation {
1328 op: Protocol::HASH.name,
1329 operand: self.type_info(),
1330 }))
1331 }
1332
1333 fn bin_op_with<T>(
1334 &self,
1335 b: &Value,
1336 caller: &mut dyn ProtocolCaller,
1337 protocol: &'static Protocol,
1338 inline: fn(&Inline, &Inline) -> Result<T, RuntimeError>,
1339 dynamic: fn(
1340 (&Arc<Rtti>, &[Value]),
1341 (&Arc<Rtti>, &[Value]),
1342 &mut dyn ProtocolCaller,
1343 ) -> Result<T, VmError>,
1344 ) -> Result<T, VmError>
1345 where
1346 T: FromValue,
1347 {
1348 match (self.as_ref(), b.as_ref()) {
1349 (Repr::Inline(lhs), Repr::Inline(rhs)) => return Ok(inline(lhs, rhs)?),
1350 (Repr::Inline(lhs), rhs) => {
1351 return Err(VmError::new(VmErrorKind::UnsupportedBinaryOperation {
1352 op: protocol.name,
1353 lhs: lhs.type_info(),
1354 rhs: rhs.type_info(),
1355 }));
1356 }
1357 (Repr::Dynamic(lhs), Repr::Dynamic(rhs)) => {
1358 let lhs_rtti = lhs.rtti();
1359 let rhs_rtti = rhs.rtti();
1360
1361 let lhs = lhs.borrow_ref()?;
1362 let rhs = rhs.borrow_ref()?;
1363
1364 if lhs_rtti.hash == rhs_rtti.hash {
1365 return dynamic((lhs_rtti, &lhs), (rhs_rtti, &rhs), caller);
1366 }
1367
1368 return Err(VmError::new(VmErrorKind::UnsupportedBinaryOperation {
1369 op: protocol.name,
1370 lhs: Rtti::type_info(lhs_rtti.clone()),
1371 rhs: Rtti::type_info(rhs_rtti.clone()),
1372 }));
1373 }
1374 _ => {}
1375 }
1376
1377 if let CallResultOnly::Ok(value) =
1378 caller.try_call_protocol_fn(protocol, self.clone(), &mut Some((b.clone(),)))?
1379 {
1380 return Ok(T::from_value(value)?);
1381 }
1382
1383 Err(VmError::new(VmErrorKind::UnsupportedBinaryOperation {
1384 op: protocol.name,
1385 lhs: self.type_info(),
1386 rhs: b.type_info(),
1387 }))
1388 }
1389
1390 pub fn as_integer<T>(&self) -> Result<T, RuntimeError>
1403 where
1404 T: TryFrom<u64> + TryFrom<i64>,
1405 {
1406 match self.repr {
1407 Repr::Inline(value) => value.as_integer(),
1408 Repr::Dynamic(ref value) => Err(RuntimeError::new(VmErrorKind::ExpectedNumber {
1409 actual: value.type_info(),
1410 })),
1411 Repr::Any(ref value) => Err(RuntimeError::new(VmErrorKind::ExpectedNumber {
1412 actual: value.type_info(),
1413 })),
1414 }
1415 }
1416
1417 pub(crate) fn as_inline_unchecked(&self) -> Option<&Inline> {
1418 match &self.repr {
1419 Repr::Inline(value) => Some(value),
1420 _ => None,
1421 }
1422 }
1423
1424 pub(crate) fn is_inline(&self) -> bool {
1426 matches!(self.repr, Repr::Inline(..))
1427 }
1428
1429 #[inline]
1433 pub(crate) fn as_inline(&self) -> Option<&Inline> {
1434 match &self.repr {
1435 Repr::Inline(value) => Some(value),
1436 Repr::Dynamic(..) => None,
1437 Repr::Any(..) => None,
1438 }
1439 }
1440
1441 #[inline]
1442 pub(crate) fn as_inline_mut(&mut self) -> Option<&mut Inline> {
1443 match &mut self.repr {
1444 Repr::Inline(value) => Some(value),
1445 Repr::Dynamic(..) => None,
1446 Repr::Any(..) => None,
1447 }
1448 }
1449
1450 #[inline]
1454 pub fn as_any(&self) -> Option<&AnyObj> {
1455 match &self.repr {
1456 Repr::Inline(..) => None,
1457 Repr::Dynamic(..) => None,
1458 Repr::Any(value) => Some(value),
1459 }
1460 }
1461
1462 #[inline(always)]
1463 pub(crate) fn take_repr(self) -> Repr {
1464 self.repr
1465 }
1466
1467 #[inline(always)]
1468 pub(crate) fn as_ref(&self) -> &Repr {
1469 &self.repr
1470 }
1471
1472 #[inline(always)]
1473 pub(crate) fn as_mut(&mut self) -> &mut Repr {
1474 &mut self.repr
1475 }
1476
1477 #[inline]
1478 pub(crate) fn try_borrow_ref<T>(&self) -> Result<Option<BorrowRef<'_, T>>, AccessError>
1479 where
1480 T: Any,
1481 {
1482 match &self.repr {
1483 Repr::Inline(..) => Ok(None),
1484 Repr::Dynamic(..) => Ok(None),
1485 Repr::Any(value) => value.try_borrow_ref(),
1486 }
1487 }
1488
1489 #[inline]
1490 pub(crate) fn try_borrow_mut<T>(&self) -> Result<Option<BorrowMut<'_, T>>, AccessError>
1491 where
1492 T: Any,
1493 {
1494 match &self.repr {
1495 Repr::Inline(..) => Ok(None),
1496 Repr::Dynamic(..) => Ok(None),
1497 Repr::Any(value) => value.try_borrow_mut(),
1498 }
1499 }
1500
1501 pub(crate) fn protocol_into_iter(&self) -> Result<Value, VmError> {
1502 EnvProtocolCaller.call_protocol_fn(&Protocol::INTO_ITER, self.clone(), &mut ())
1503 }
1504
1505 pub(crate) fn protocol_next(&self) -> Result<Option<Value>, VmError> {
1506 let value = EnvProtocolCaller.call_protocol_fn(&Protocol::NEXT, self.clone(), &mut ())?;
1507
1508 Ok(FromValue::from_value(value)?)
1509 }
1510
1511 pub(crate) fn protocol_next_back(&self) -> Result<Option<Value>, VmError> {
1512 let value =
1513 EnvProtocolCaller.call_protocol_fn(&Protocol::NEXT_BACK, self.clone(), &mut ())?;
1514
1515 Ok(FromValue::from_value(value)?)
1516 }
1517
1518 pub(crate) fn protocol_nth_back(&self, n: usize) -> Result<Option<Value>, VmError> {
1519 let value = EnvProtocolCaller.call_protocol_fn(
1520 &Protocol::NTH_BACK,
1521 self.clone(),
1522 &mut Some((n,)),
1523 )?;
1524
1525 Ok(FromValue::from_value(value)?)
1526 }
1527
1528 pub(crate) fn protocol_len(&self) -> Result<usize, VmError> {
1529 let value = EnvProtocolCaller.call_protocol_fn(&Protocol::LEN, self.clone(), &mut ())?;
1530
1531 Ok(FromValue::from_value(value)?)
1532 }
1533
1534 pub(crate) fn protocol_size_hint(&self) -> Result<(usize, Option<usize>), VmError> {
1535 let value =
1536 EnvProtocolCaller.call_protocol_fn(&Protocol::SIZE_HINT, self.clone(), &mut ())?;
1537
1538 Ok(FromValue::from_value(value)?)
1539 }
1540}
1541
1542impl fmt::Debug for Value {
1543 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1544 match &self.repr {
1545 Repr::Inline(value) => {
1546 write!(f, "{value:?}")?;
1547 }
1548 _ => {
1549 let mut s = String::new();
1550 let result = Formatter::format_with(&mut s, |f| self.debug_fmt(f));
1551
1552 if let Err(e) = result {
1553 match &self.repr {
1554 Repr::Inline(value) => {
1555 write!(f, "<{value:?}: {e}>")?;
1556 }
1557 Repr::Dynamic(value) => {
1558 let ty = value.type_info();
1559 write!(f, "<{ty} object at {value:p}: {e}>")?;
1560 }
1561 Repr::Any(value) => {
1562 let ty = value.type_info();
1563 write!(f, "<{ty} object at {value:p}: {e}>")?;
1564 }
1565 }
1566
1567 return Ok(());
1568 }
1569
1570 f.write_str(s.as_str())?;
1571 }
1572 }
1573
1574 Ok(())
1575 }
1576}
1577
1578impl From<Repr> for Value {
1579 #[inline]
1580 fn from(repr: Repr) -> Self {
1581 Self { repr }
1582 }
1583}
1584
1585impl From<()> for Value {
1586 #[inline]
1587 fn from((): ()) -> Self {
1588 Value::from(Inline::Unit)
1589 }
1590}
1591
1592impl From<Inline> for Value {
1593 #[inline]
1594 fn from(value: Inline) -> Self {
1595 Self {
1596 repr: Repr::Inline(value),
1597 }
1598 }
1599}
1600
1601impl From<AnyObj> for Value {
1619 #[inline]
1620 fn from(value: AnyObj) -> Self {
1621 Self {
1622 repr: Repr::Any(value),
1623 }
1624 }
1625}
1626
1627impl<T> From<Shared<T>> for Value
1645where
1646 T: Any,
1647{
1648 #[inline]
1649 fn from(value: Shared<T>) -> Self {
1650 Self {
1651 repr: Repr::Any(value.into_any_obj()),
1652 }
1653 }
1654}
1655
1656impl From<AnySequence<Arc<Rtti>, Value>> for Value {
1657 #[inline]
1658 fn from(value: AnySequence<Arc<Rtti>, Value>) -> Self {
1659 Self {
1660 repr: Repr::Dynamic(value),
1661 }
1662 }
1663}
1664
1665impl TryFrom<&str> for Value {
1666 type Error = alloc::Error;
1667
1668 #[inline]
1669 fn try_from(value: &str) -> Result<Self, Self::Error> {
1670 Value::new(String::try_from(value)?)
1671 }
1672}
1673
1674inline_from! {
1675 Bool => bool,
1676 Char => char,
1677 Signed => i64,
1678 Unsigned => u64,
1679 Float => f64,
1680 Type => Type,
1681 Ordering => Ordering,
1682 Hash => Hash,
1683}
1684
1685any_from! {
1686 crate::alloc::String,
1687 super::Bytes,
1688 super::Format,
1689 super::ControlFlow,
1690 super::GeneratorState,
1691 super::Vec,
1692 super::OwnedTuple,
1693 super::Generator,
1694 super::Stream,
1695 super::Function,
1696 super::Future,
1697 super::Object,
1698 Option<Value>,
1699 Result<Value, Value>,
1700}
1701
1702signed_value_from!(i8, i16, i32);
1703signed_value_try_from!(i128, isize);
1704unsigned_value_from!(u8, u16, u32);
1705unsigned_value_try_from!(u128, usize);
1706signed_value_trait!(i8, i16, i32, i128, isize);
1707unsigned_value_trait!(u8, u16, u32, u128, usize);
1708float_value_trait!(f32);
1709
1710impl MaybeTypeOf for Value {
1711 #[inline]
1712 fn maybe_type_of() -> alloc::Result<meta::DocType> {
1713 Ok(meta::DocType::empty())
1714 }
1715}
1716
1717impl Clone for Value {
1718 #[inline]
1719 fn clone(&self) -> Self {
1720 let repr = match &self.repr {
1721 Repr::Inline(inline) => Repr::Inline(*inline),
1722 Repr::Dynamic(mutable) => Repr::Dynamic(mutable.clone()),
1723 Repr::Any(any) => Repr::Any(any.clone()),
1724 };
1725
1726 Self { repr }
1727 }
1728
1729 #[inline]
1730 fn clone_from(&mut self, source: &Self) {
1731 match (&mut self.repr, &source.repr) {
1732 (Repr::Inline(lhs), Repr::Inline(rhs)) => {
1733 *lhs = *rhs;
1734 }
1735 (Repr::Dynamic(lhs), Repr::Dynamic(rhs)) => {
1736 lhs.clone_from(rhs);
1737 }
1738 (Repr::Any(lhs), Repr::Any(rhs)) => {
1739 lhs.clone_from(rhs);
1740 }
1741 (lhs, rhs) => {
1742 *lhs = rhs.clone();
1743 }
1744 }
1745 }
1746}
1747
1748impl TryClone for Value {
1749 fn try_clone(&self) -> alloc::Result<Self> {
1750 Ok(self.clone())
1752 }
1753}
1754
1755#[doc(hidden)]
1757pub struct NotTypedInline(Inline);
1758
1759#[doc(hidden)]
1761pub struct NotTypedAnyObj<'a>(&'a AnyObj);
1762
1763#[non_exhaustive]
1765#[doc(hidden)]
1766pub enum TypeValue<'a> {
1767 Unit,
1769 Tuple(BorrowRef<'a, OwnedTuple>),
1771 Object(BorrowRef<'a, Object>),
1773 EmptyStruct(EmptyStruct<'a>),
1775 TupleStruct(TupleStruct<'a>),
1777 Struct(Struct<'a>),
1779 #[doc(hidden)]
1781 NotTypedInline(NotTypedInline),
1782 #[doc(hidden)]
1784 NotTypedAnyObj(NotTypedAnyObj<'a>),
1785}
1786
1787impl TypeValue<'_> {
1788 #[doc(hidden)]
1790 pub fn type_info(&self) -> TypeInfo {
1791 match self {
1792 TypeValue::Unit => TypeInfo::any::<OwnedTuple>(),
1793 TypeValue::Tuple(..) => TypeInfo::any::<OwnedTuple>(),
1794 TypeValue::Object(..) => TypeInfo::any::<Object>(),
1795 TypeValue::EmptyStruct(empty) => empty.type_info(),
1796 TypeValue::TupleStruct(tuple) => tuple.type_info(),
1797 TypeValue::Struct(object) => object.type_info(),
1798 TypeValue::NotTypedInline(value) => value.0.type_info(),
1799 TypeValue::NotTypedAnyObj(value) => value.0.type_info(),
1800 }
1801 }
1802}
1803
1804#[test]
1807fn size_of_value() {
1808 use core::mem::size_of;
1809
1810 assert_eq!(size_of::<Repr>(), size_of::<Inline>());
1811 assert_eq!(size_of::<Repr>(), size_of::<Value>());
1812 assert_eq!(size_of::<Option<Value>>(), size_of::<Value>());
1813 assert_eq!(size_of::<Option<Repr>>(), size_of::<Repr>());
1814}