1use std::any::*;
2use std::marker::*;
3#[cfg(feature = "serde")]
4use std::mem::*;
5use std::ops::*;
6use std::sync::atomic::*;
7use std::sync::*;
8
9use anyhow::*;
10#[cfg(feature = "serde")]
11use bytemuck::*;
12use private::*;
13#[cfg(feature = "serde")]
14use serde::*;
15
16use crate::require_matches::require_matches;
17use crate::types::*;
18use crate::AsContext;
19use crate::AsContextMut;
20use crate::TypeIdentifier;
21
22#[derive(Clone, Debug, PartialEq)]
24#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
25pub enum Value {
26 Bool(bool),
28 S8(i8),
30 U8(u8),
32 S16(i16),
34 U16(u16),
36 S32(i32),
38 U32(u32),
40 S64(i64),
42 U64(u64),
44 F32(f32),
46 F64(f64),
48 Char(char),
50 String(Arc<str>),
52 List(List),
54 Record(Record),
56 Tuple(Tuple),
58 Variant(Variant),
60 Enum(Enum),
62 Option(OptionValue),
64 Result(ResultValue),
66 Flags(Flags),
68 Own(ResourceOwn),
70 Borrow(ResourceBorrow),
72}
73
74impl Value {
75 pub fn ty(&self) -> ValueType {
77 match self {
78 Value::Bool(_) => ValueType::Bool,
79 Value::S8(_) => ValueType::S8,
80 Value::U8(_) => ValueType::U8,
81 Value::S16(_) => ValueType::S16,
82 Value::U16(_) => ValueType::U16,
83 Value::S32(_) => ValueType::S32,
84 Value::U32(_) => ValueType::U32,
85 Value::S64(_) => ValueType::S64,
86 Value::U64(_) => ValueType::U64,
87 Value::F32(_) => ValueType::F32,
88 Value::F64(_) => ValueType::F64,
89 Value::Char(_) => ValueType::Char,
90 Value::String(_) => ValueType::String,
91 Value::List(x) => ValueType::List(x.ty()),
92 Value::Record(x) => ValueType::Record(x.ty()),
93 Value::Tuple(x) => ValueType::Tuple(x.ty()),
94 Value::Variant(x) => ValueType::Variant(x.ty()),
95 Value::Enum(x) => ValueType::Enum(x.ty()),
96 Value::Option(x) => ValueType::Option(x.ty()),
97 Value::Result(x) => ValueType::Result(x.ty()),
98 Value::Flags(x) => ValueType::Flags(x.ty()),
99 Value::Own(x) => ValueType::Own(x.ty()),
100 Value::Borrow(x) => ValueType::Borrow(x.ty()),
101 }
102 }
103}
104
105impl TryFrom<&Value> for wasm_runtime_layer::Value {
106 type Error = Error;
107
108 fn try_from(value: &Value) -> Result<Self> {
109 match value {
110 Value::S32(x) => Ok(Self::I32(*x)),
111 Value::S64(x) => Ok(Self::I64(*x)),
112 Value::F32(x) => Ok(Self::F32(*x)),
113 Value::F64(x) => Ok(Self::F64(*x)),
114 _ => bail!("Unable to convert {value:?} to core type."),
115 }
116 }
117}
118
119impl TryFrom<&wasm_runtime_layer::Value> for Value {
120 type Error = Error;
121
122 fn try_from(value: &wasm_runtime_layer::Value) -> Result<Self> {
123 match value {
124 wasm_runtime_layer::Value::I32(x) => Ok(Self::S32(*x)),
125 wasm_runtime_layer::Value::I64(x) => Ok(Self::S64(*x)),
126 wasm_runtime_layer::Value::F32(x) => Ok(Self::F32(*x)),
127 wasm_runtime_layer::Value::F64(x) => Ok(Self::F64(*x)),
128 _ => bail!("Unable to convert {value:?} to component type."),
129 }
130 }
131}
132
133macro_rules! impl_primitive_from {
135 ($(($type_name: ident, $enum_name: ident))*) => {
136 $(
137 impl From<&$type_name> for Value {
138 fn from(value: &$type_name) -> Value {
139 Value::$enum_name(*value)
140 }
141 }
142
143 impl TryFrom<$type_name> for Value {
144 type Error = Error;
145
146 fn try_from(value: $type_name) -> Result<Self> {
147 Ok(Value::$enum_name(value))
148 }
149 }
150
151 impl TryFrom<&Value> for $type_name {
152 type Error = Error;
153
154 fn try_from(value: &Value) -> Result<Self> {
155 Ok(require_matches!(value, Value::$enum_name(x), *x))
156 }
157 }
158 )*
159 };
160}
161
162impl_primitive_from!((bool, Bool)(i8, S8)(u8, U8)(i16, S16)(u16, U16)(i32, S32)(
163 u32, U32
164)(i64, S64)(u64, U64)(f32, F32)(f64, F64)(char, Char));
165
166#[derive(Clone, Debug)]
168#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
169pub struct List {
170 values: ListSpecialization,
172 ty: ListType,
174}
175
176impl List {
177 pub fn new(ty: ListType, values: impl IntoIterator<Item = Value>) -> Result<Self> {
180 let values = match ty.element_ty() {
181 ValueType::Bool => bool::from_value_iter(values)?,
182 ValueType::S8 => i8::from_value_iter(values)?,
183 ValueType::U8 => u8::from_value_iter(values)?,
184 ValueType::S16 => i16::from_value_iter(values)?,
185 ValueType::U16 => u16::from_value_iter(values)?,
186 ValueType::S32 => i32::from_value_iter(values)?,
187 ValueType::U32 => u32::from_value_iter(values)?,
188 ValueType::S64 => i64::from_value_iter(values)?,
189 ValueType::U64 => u64::from_value_iter(values)?,
190 ValueType::F32 => f32::from_value_iter(values)?,
191 ValueType::F64 => f64::from_value_iter(values)?,
192 ValueType::Char => char::from_value_iter(values)?,
193 _ => ListSpecialization::Other(
194 values
195 .into_iter()
196 .map(|x| {
197 (x.ty() == ty.element_ty()).then_some(x).ok_or_else(|| {
198 Error::msg("List elements were not all of the same type.")
199 })
200 })
201 .collect::<Result<_>>()?,
202 ),
203 };
204
205 Ok(Self { values, ty })
206 }
207
208 pub fn ty(&self) -> ListType {
210 self.ty.clone()
211 }
212
213 pub fn typed<T: ListPrimitive>(&self) -> Result<&[T]> {
217 if self.ty.element_ty() == T::ty() {
218 Ok(T::from_specialization(&self.values))
219 } else {
220 bail!(
221 "List type mismatch: expected {:?} but got {:?}",
222 T::ty(),
223 self.ty()
224 );
225 }
226 }
227
228 pub fn iter(&self) -> impl '_ + Iterator<Item = Value> {
230 self.into_iter()
231 }
232
233 pub fn is_empty(&self) -> bool {
235 self.len() == 0
236 }
237
238 pub fn len(&self) -> usize {
240 match &self.values {
241 ListSpecialization::Bool(x) => x.len(),
242 ListSpecialization::S8(x) => x.len(),
243 ListSpecialization::U8(x) => x.len(),
244 ListSpecialization::S16(x) => x.len(),
245 ListSpecialization::U16(x) => x.len(),
246 ListSpecialization::S32(x) => x.len(),
247 ListSpecialization::U32(x) => x.len(),
248 ListSpecialization::S64(x) => x.len(),
249 ListSpecialization::U64(x) => x.len(),
250 ListSpecialization::F32(x) => x.len(),
251 ListSpecialization::F64(x) => x.len(),
252 ListSpecialization::Char(x) => x.len(),
253 ListSpecialization::Other(x) => x.len(),
254 }
255 }
256}
257
258impl PartialEq for List {
259 fn eq(&self, other: &Self) -> bool {
260 self.values == other.values
261 }
262}
263
264impl<'a> IntoIterator for &'a List {
265 type IntoIter = ListSpecializationIter<'a>;
266
267 type Item = Value;
268
269 fn into_iter(self) -> Self::IntoIter {
270 self.values.into_iter()
271 }
272}
273
274impl<T: ListPrimitive> From<&[T]> for List {
275 fn from(value: &[T]) -> Self {
276 Self {
277 values: T::from_arc(value.into()),
278 ty: ListType::new(T::ty()),
279 }
280 }
281}
282
283impl<T: ListPrimitive> From<Arc<[T]>> for List {
284 fn from(value: Arc<[T]>) -> Self {
285 Self {
286 values: T::from_arc(value),
287 ty: ListType::new(T::ty()),
288 }
289 }
290}
291
292#[derive(Clone, Debug)]
294#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
295pub struct Record {
296 fields: Arc<[(Arc<str>, Value)]>,
298 ty: RecordType,
300}
301
302impl Record {
303 pub fn new<S: Into<Arc<str>>>(
306 ty: RecordType,
307 values: impl IntoIterator<Item = (S, Value)>,
308 ) -> Result<Self> {
309 let mut to_sort = values
310 .into_iter()
311 .map(|(name, val)| (Into::<Arc<str>>::into(name), val))
312 .collect::<Arc<_>>();
313 Arc::get_mut(&mut to_sort)
314 .expect("Could not get exclusive reference.")
315 .sort_by(|a, b| a.0.cmp(&b.0));
316
317 ensure!(
318 to_sort.len() == ty.fields().len(),
319 "Record fields did not match type."
320 );
321
322 for ((name, val), (ty_name, ty_val)) in to_sort.iter().zip(ty.fields()) {
323 ensure!(
324 **name == *ty_name && val.ty() == ty_val,
325 "Record fields did not match type."
326 );
327 }
328
329 Ok(Self {
330 fields: to_sort,
331 ty,
332 })
333 }
334
335 pub fn from_fields<S: Into<Arc<str>>>(
337 name: Option<TypeIdentifier>,
338 values: impl IntoIterator<Item = (S, Value)>,
339 ) -> Result<Self> {
340 let mut fields = values
341 .into_iter()
342 .map(|(name, val)| (Into::<Arc<str>>::into(name), val))
343 .collect::<Arc<_>>();
344 Arc::get_mut(&mut fields)
345 .expect("Could not get exclusive reference.")
346 .sort_by(|a, b| a.0.cmp(&b.0));
347 let ty = RecordType::new_sorted(
348 name,
349 fields.iter().map(|(name, val)| (name.clone(), val.ty())),
350 )?;
351 Ok(Self { fields, ty })
352 }
353
354 pub fn field(&self, field: impl AsRef<str>) -> Option<Value> {
356 self.fields
357 .iter()
358 .filter(|&(name, _val)| (&**name == field.as_ref()))
359 .map(|(_name, val)| val.clone())
360 .next()
361 }
362
363 pub fn fields(&self) -> impl ExactSizeIterator<Item = (&str, Value)> {
365 self.fields.iter().map(|(name, val)| (&**name, val.clone()))
366 }
367
368 pub fn ty(&self) -> RecordType {
370 self.ty.clone()
371 }
372
373 pub(crate) fn from_sorted(
375 ty: RecordType,
376 values: impl IntoIterator<Item = (Arc<str>, Value)>,
377 ) -> Self {
378 Self {
379 fields: values.into_iter().collect(),
380 ty,
381 }
382 }
383}
384
385impl PartialEq for Record {
386 fn eq(&self, other: &Self) -> bool {
387 self.fields == other.fields
388 }
389}
390
391#[derive(Clone, Debug)]
393#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
394pub struct Tuple {
395 fields: Arc<[Value]>,
397 ty: TupleType,
399}
400
401impl Tuple {
402 pub fn new(ty: TupleType, fields: impl IntoIterator<Item = Value>) -> Result<Self> {
405 Ok(Self {
406 fields: fields
407 .into_iter()
408 .enumerate()
409 .map(|(i, val)| {
410 ensure!(i < ty.fields().len(), "Field count was out-of-range.");
411 (val.ty() == ty.fields()[i])
412 .then_some(val)
413 .ok_or_else(|| Error::msg("Value was not of correct type."))
414 })
415 .collect::<Result<_>>()?,
416 ty,
417 })
418 }
419
420 pub fn from_fields(
422 name: Option<TypeIdentifier>,
423 fields: impl IntoIterator<Item = Value>,
424 ) -> Self {
425 let fields: Arc<_> = fields.into_iter().collect();
426 let ty = TupleType::new(name, fields.iter().map(|x| x.ty()));
427 Self { fields, ty }
428 }
429
430 pub fn ty(&self) -> TupleType {
432 self.ty.clone()
433 }
434
435 pub(crate) fn new_unchecked(ty: TupleType, fields: impl IntoIterator<Item = Value>) -> Self {
437 Self {
438 fields: fields.into_iter().collect(),
439 ty,
440 }
441 }
442}
443
444impl PartialEq for Tuple {
445 fn eq(&self, other: &Self) -> bool {
446 self.fields == other.fields
447 }
448}
449
450impl Deref for Tuple {
451 type Target = [Value];
452
453 fn deref(&self) -> &Self::Target {
454 &self.fields
455 }
456}
457
458impl IntoIterator for Tuple {
459 type IntoIter = std::vec::IntoIter<Value>;
460 type Item = Value;
461
462 fn into_iter(self) -> Self::IntoIter {
463 self.fields.iter().cloned().collect::<Vec<_>>().into_iter()
464 }
465}
466
467impl<'a> IntoIterator for &'a Tuple {
468 type IntoIter = std::slice::Iter<'a, Value>;
469 type Item = &'a Value;
470
471 fn into_iter(self) -> Self::IntoIter {
472 self.fields.iter()
473 }
474}
475
476#[derive(Clone, Debug, PartialEq)]
479#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
480pub struct Variant {
481 discriminant: u32,
483 value: Option<Arc<Value>>,
485 ty: VariantType,
487}
488
489impl Variant {
490 pub fn new(ty: VariantType, discriminant: usize, value: Option<Value>) -> Result<Self> {
493 ensure!(
494 discriminant < ty.cases().len(),
495 "Discriminant out-of-range."
496 );
497 ensure!(
498 ty.cases()[discriminant].ty() == value.as_ref().map(|x| x.ty()),
499 "Provided value was of incorrect type for case."
500 );
501 Ok(Self {
502 discriminant: discriminant as u32,
503 value: value.map(Arc::new),
504 ty,
505 })
506 }
507
508 pub fn discriminant(&self) -> usize {
510 self.discriminant as usize
511 }
512
513 pub fn value(&self) -> Option<Value> {
515 self.value.as_ref().map(|x| (**x).clone())
516 }
517
518 pub fn ty(&self) -> VariantType {
520 self.ty.clone()
521 }
522}
523
524#[derive(Clone, Debug, PartialEq)]
526#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
527pub struct Enum {
528 discriminant: u32,
530 ty: EnumType,
532}
533
534impl Enum {
535 pub fn new(ty: EnumType, discriminant: usize) -> Result<Self> {
538 ensure!(
539 discriminant < ty.cases().len(),
540 "Discriminant out-of-range."
541 );
542 Ok(Self {
543 discriminant: discriminant as u32,
544 ty,
545 })
546 }
547
548 pub fn discriminant(&self) -> usize {
550 self.discriminant as usize
551 }
552
553 pub fn ty(&self) -> EnumType {
555 self.ty.clone()
556 }
557}
558
559#[derive(Clone, Debug, PartialEq)]
561#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
562pub struct OptionValue {
563 ty: OptionType,
565 value: Arc<Option<Value>>,
567}
568
569impl OptionValue {
570 pub fn new(ty: OptionType, value: Option<Value>) -> Result<Self> {
572 ensure!(
573 value
574 .as_ref()
575 .map(|x| x.ty() == ty.some_ty())
576 .unwrap_or(true),
577 "Provided option value was of incorrect type."
578 );
579 Ok(Self {
580 ty,
581 value: Arc::new(value),
582 })
583 }
584
585 pub fn ty(&self) -> OptionType {
587 self.ty.clone()
588 }
589}
590
591impl Deref for OptionValue {
592 type Target = Option<Value>;
593
594 fn deref(&self) -> &Self::Target {
595 &self.value
596 }
597}
598
599#[derive(Clone, Debug, PartialEq)]
601#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
602pub struct ResultValue {
603 ty: ResultType,
605 value: Arc<Result<Option<Value>, Option<Value>>>,
607}
608
609impl ResultValue {
610 pub fn new(ty: ResultType, value: Result<Option<Value>, Option<Value>>) -> Result<Self> {
613 ensure!(
614 match &value {
615 std::result::Result::Ok(x) => x.as_ref().map(|y| y.ty()) == ty.ok_ty(),
616 std::result::Result::Err(x) => x.as_ref().map(|y| y.ty()) == ty.err_ty(),
617 },
618 "Provided result value was of incorrect type. (expected {ty:?}, had {value:?})"
619 );
620 Ok(Self {
621 ty,
622 value: Arc::new(value),
623 })
624 }
625
626 pub fn ty(&self) -> ResultType {
628 self.ty.clone()
629 }
630}
631
632impl Deref for ResultValue {
633 type Target = Result<Option<Value>, Option<Value>>;
634
635 fn deref(&self) -> &Self::Target {
636 &self.value
637 }
638}
639
640#[derive(Clone, Debug, PartialEq)]
642#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
643pub struct Flags {
644 ty: FlagsType,
646 flags: FlagsList,
648}
649
650impl Flags {
651 pub fn new(ty: FlagsType) -> Self {
653 let names = ty.names().len() as u32;
654 Self {
655 flags: if names > usize::BITS {
656 FlagsList::Multiple(Arc::new(vec![0; (((names - 1) / u32::BITS) + 1) as usize]))
657 } else {
658 FlagsList::Single(0)
659 },
660 ty,
661 }
662 }
663
664 pub fn get(&self, name: impl AsRef<str>) -> bool {
666 self.get_index(self.index_of(name))
667 }
668
669 pub fn get_index(&self, index: usize) -> bool {
671 let index = index as u32;
672 match &self.flags {
673 FlagsList::Single(x) => (*x >> index) == 1,
674 FlagsList::Multiple(x) => {
675 let arr_index = index / u32::BITS;
676 let sub_index = index % u32::BITS;
677 (x[arr_index as usize] >> sub_index) == 1
678 }
679 }
680 }
681
682 pub fn set(&mut self, name: impl AsRef<str>, value: bool) {
684 self.set_index(self.index_of(name), value)
685 }
686
687 pub fn set_index(&mut self, index: usize, value: bool) {
689 let index = index as u32;
690 match &mut self.flags {
691 FlagsList::Single(x) => {
692 if value {
693 *x |= 1 << index;
694 } else {
695 *x &= !(1 << index);
696 }
697 }
698 FlagsList::Multiple(x) => {
699 let list = Arc::make_mut(x);
700 let arr_index = index / u32::BITS;
701 let sub_index = index % u32::BITS;
702 let x = &mut list[arr_index as usize];
703 if value {
704 *x |= 1 << sub_index;
705 } else {
706 *x &= !(1 << sub_index);
707 }
708 }
709 }
710 }
711
712 pub fn ty(&self) -> FlagsType {
714 self.ty.clone()
715 }
716
717 pub(crate) fn new_unchecked(ty: FlagsType, flags: FlagsList) -> Self {
719 Self { ty, flags }
720 }
721
722 pub(crate) fn as_u32_list(&self) -> &[u32] {
724 match &self.flags {
725 FlagsList::Single(x) => std::slice::from_ref(x),
726 FlagsList::Multiple(x) => x,
727 }
728 }
729
730 fn index_of(&self, name: impl AsRef<str>) -> usize {
732 *self
733 .ty
734 .indices
735 .get(name.as_ref())
736 .expect("Unknown flag name")
737 }
738}
739
740#[derive(Clone, Debug, PartialEq)]
742#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
743pub(crate) enum FlagsList {
744 Single(u32),
746 Multiple(Arc<Vec<u32>>),
748}
749
750#[derive(Clone, Debug)]
752pub struct ResourceOwn {
753 tracker: Arc<AtomicUsize>,
755 rep: i32,
757 destructor: Option<wasm_runtime_layer::Func>,
759 store_id: u64,
761 ty: ResourceType,
763}
764
765impl ResourceOwn {
766 pub fn new<T: 'static + Send + Sync + Sized>(
768 mut ctx: impl AsContextMut,
769 value: T,
770 ty: ResourceType,
771 ) -> Result<Self> {
772 let mut store_ctx = ctx.as_context_mut();
773 let store_id = store_ctx.inner.data().id;
774 ensure!(
775 ty.valid_for::<T>(store_id),
776 "Resource value was of incorrect type."
777 );
778 let rep = store_ctx
779 .inner
780 .data_mut()
781 .host_resources
782 .insert(Box::new(value)) as i32;
783
784 Ok(Self {
785 tracker: Arc::default(),
786 rep,
787 destructor: match ty
788 .host_destructor()
789 .expect("Could not get host destructor value.")
790 {
791 Some(x) => Some(x),
792 None => store_ctx.inner.data().drop_host_resource.clone(),
793 },
794 store_id,
795 ty,
796 })
797 }
798
799 pub(crate) fn new_guest(
801 rep: i32,
802 ty: ResourceType,
803 store_id: u64,
804 destructor: Option<wasm_runtime_layer::Func>,
805 ) -> Self {
806 Self {
807 tracker: Arc::default(),
808 rep,
809 destructor,
810 ty,
811 store_id,
812 }
813 }
814
815 pub fn borrow(&self, ctx: impl crate::AsContextMut) -> Result<ResourceBorrow> {
817 ensure!(
818 self.store_id == ctx.as_context().inner.data().id,
819 "Incorrect store."
820 );
821 ensure!(
822 self.tracker.load(Ordering::Acquire) < usize::MAX,
823 "Resource was already destroyed."
824 );
825 Ok(ResourceBorrow {
826 dead: Arc::default(),
827 host_tracker: Some(self.tracker.clone()),
828 rep: self.rep,
829 store_id: self.store_id,
830 ty: self.ty.clone(),
831 })
832 }
833
834 pub fn rep<'a, T: 'static + Send + Sync, S, E: wasm_runtime_layer::backend::WasmEngine>(
836 &self,
837 ctx: &'a crate::StoreContext<S, E>,
838 ) -> Result<&'a T> {
839 ensure!(
840 self.store_id == ctx.as_context().inner.data().id,
841 "Incorrect store."
842 );
843 ensure!(
844 self.tracker.load(Ordering::Acquire) < usize::MAX,
845 "Resource was already destroyed."
846 );
847
848 if self.ty.host_destructor().is_some() {
849 ctx.inner
850 .data()
851 .host_resources
852 .get(self.rep as usize)
853 .expect("Resource was not present.")
854 .downcast_ref()
855 .context("Resource was not of requested type.")
856 } else {
857 bail!("Cannot get the representation for a guest-owned resource.");
858 }
859 }
860
861 pub fn rep_mut<'a, T: 'static + Send + Sync, S, E: wasm_runtime_layer::backend::WasmEngine>(
863 &self,
864 ctx: &'a mut crate::StoreContextMut<S, E>,
865 ) -> Result<&'a mut T> {
866 ensure!(
867 self.store_id == ctx.as_context().inner.data().id,
868 "Incorrect store."
869 );
870 ensure!(
871 self.tracker.load(Ordering::Acquire) < usize::MAX,
872 "Resource was already destroyed."
873 );
874
875 if self.ty.host_destructor().is_some() {
876 ctx.inner
877 .data_mut()
878 .host_resources
879 .get_mut(self.rep as usize)
880 .expect("Resource was not present.")
881 .downcast_mut()
882 .context("Resource was not of requested type.")
883 } else {
884 bail!("Cannot get the representation for a guest-owned resource.");
885 }
886 }
887
888 pub fn ty(&self) -> ResourceType {
890 self.ty.clone()
891 }
892
893 pub fn take<T: 'static + Send + Sync>(&self, mut ctx: impl crate::AsContextMut) -> Result<()> {
896 ensure!(
897 self.store_id == ctx.as_context().inner.data().id,
898 "Incorrect store."
899 );
900 ensure!(
901 self.tracker.load(Ordering::Acquire) == 0,
902 "Resource had remaining borrows or was already dropped."
903 );
904
905 ensure!(
906 self.ty.host_destructor().is_some(),
907 "Resource did not originate from host."
908 );
909
910 ensure!(
911 ctx.as_context_mut()
912 .inner
913 .data_mut()
914 .host_resources
915 .get(self.rep as usize)
916 .expect("Resource was not present.")
917 .is::<T>(),
918 "Resource was of incorrect type."
919 );
920
921 *ctx.as_context_mut()
922 .inner
923 .data_mut()
924 .host_resources
925 .remove(self.rep as usize)
926 .downcast()
927 .expect("Could not downcast resource.")
928 }
929
930 pub fn drop(&self, mut ctx: impl crate::AsContextMut) -> Result<()> {
933 ensure!(
934 self.store_id == ctx.as_context().inner.data().id,
935 "Incorrect store."
936 );
937 ensure!(
938 self.tracker.load(Ordering::Acquire) == 0,
939 "Resource had remaining borrows or was already dropped."
940 );
941
942 if let Some(destructor) = &self.destructor {
943 destructor.call(
944 ctx.as_context_mut().inner,
945 &[wasm_runtime_layer::Value::I32(self.rep)],
946 &mut [],
947 )?;
948 }
949
950 self.tracker.store(usize::MAX, Ordering::Release);
951 Ok(())
952 }
953
954 pub(crate) fn lower(&self, ctx: impl crate::AsContextMut) -> Result<i32> {
956 ensure!(
957 self.store_id == ctx.as_context().inner.data().id,
958 "Incorrect store."
959 );
960 ensure!(
961 self.tracker.load(Ordering::Acquire) < usize::MAX,
962 "Resource was already destroyed."
963 );
964 self.tracker.store(usize::MAX, Ordering::Release);
965 Ok(self.rep)
966 }
967}
968
969impl PartialEq for ResourceOwn {
970 fn eq(&self, other: &Self) -> bool {
971 Arc::ptr_eq(&self.tracker, &other.tracker)
972 }
973}
974
975#[cfg(feature = "serde")]
976impl Serialize for ResourceOwn {
977 fn serialize<S: Serializer>(&self, _: S) -> Result<S::Ok, S::Error> {
978 use serde::ser::*;
979 std::result::Result::Err(S::Error::custom("Cannot serialize resources."))
980 }
981}
982
983#[cfg(feature = "serde")]
984impl<'a> Deserialize<'a> for ResourceOwn {
985 fn deserialize<D: Deserializer<'a>>(_: D) -> Result<Self, D::Error> {
986 use serde::de::*;
987 std::result::Result::Err(D::Error::custom("Cannot deserialize resources."))
988 }
989}
990
991#[derive(Clone, Debug)]
995pub struct ResourceBorrow {
996 dead: Arc<AtomicBool>,
998 host_tracker: Option<Arc<AtomicUsize>>,
1000 rep: i32,
1002 store_id: u64,
1004 ty: ResourceType,
1006}
1007
1008impl ResourceBorrow {
1009 pub(crate) fn new(rep: i32, store_id: u64, ty: ResourceType) -> Self {
1011 Self {
1012 dead: Arc::default(),
1013 host_tracker: None,
1014 rep,
1015 ty,
1016 store_id,
1017 }
1018 }
1019
1020 pub fn rep<'a, T: 'static + Send + Sync, S, E: wasm_runtime_layer::backend::WasmEngine>(
1022 &self,
1023 ctx: &'a crate::StoreContext<S, E>,
1024 ) -> Result<&'a T> {
1025 ensure!(
1026 self.store_id == ctx.as_context().inner.data().id,
1027 "Incorrect store."
1028 );
1029 ensure!(
1030 !self.dead.load(Ordering::Acquire),
1031 "Borrow was already dropped."
1032 );
1033
1034 if self.ty.host_destructor().is_some() {
1035 ctx.inner
1036 .data()
1037 .host_resources
1038 .get(self.rep as usize)
1039 .expect("Resource was not present.")
1040 .downcast_ref()
1041 .context("Resource was not of requested type.")
1042 } else {
1043 bail!("Cannot get the representation for a guest-owned resource.");
1044 }
1045 }
1046
1047 pub fn rep_mut<'a, T: 'static + Send + Sync, S, E: wasm_runtime_layer::backend::WasmEngine>(
1049 &self,
1050 ctx: &'a mut crate::StoreContextMut<S, E>,
1051 ) -> Result<&'a mut T> {
1052 ensure!(
1053 self.store_id == ctx.as_context().inner.data().id,
1054 "Incorrect store."
1055 );
1056 ensure!(
1057 !self.dead.load(Ordering::Acquire),
1058 "Borrow was already dropped."
1059 );
1060
1061 if self.ty.host_destructor().is_some() {
1062 ctx.inner
1063 .data_mut()
1064 .host_resources
1065 .get_mut(self.rep as usize)
1066 .expect("Resource was not present.")
1067 .downcast_mut()
1068 .context("Resource was not of requested type.")
1069 } else {
1070 bail!("Cannot get the representation for a guest-owned resource.");
1071 }
1072 }
1073
1074 pub fn ty(&self) -> ResourceType {
1076 self.ty.clone()
1077 }
1078
1079 pub fn drop(&self, ctx: impl crate::AsContextMut) -> Result<()> {
1081 ensure!(
1082 self.store_id == ctx.as_context().inner.data().id,
1083 "Incorrect store."
1084 );
1085 ensure!(
1086 !self.dead.load(Ordering::Acquire),
1087 "Borrow was already dropped."
1088 );
1089 let tracker = self
1090 .host_tracker
1091 .as_ref()
1092 .context("Only host borrows require dropping.")?;
1093 tracker.fetch_sub(1, Ordering::AcqRel);
1094 Ok(())
1095 }
1096
1097 pub(crate) fn lower(&self, ctx: impl crate::AsContextMut) -> Result<i32> {
1099 ensure!(
1100 self.store_id == ctx.as_context().inner.data().id,
1101 "Incorrect store."
1102 );
1103 ensure!(
1104 !self.dead.load(Ordering::Acquire),
1105 "Borrow was already dropped."
1106 );
1107 Ok(self.rep)
1108 }
1109
1110 pub(crate) fn dead_ref(&self) -> Arc<AtomicBool> {
1112 self.dead.clone()
1113 }
1114}
1115
1116impl PartialEq for ResourceBorrow {
1117 fn eq(&self, other: &Self) -> bool {
1118 Arc::ptr_eq(&self.dead, &other.dead)
1119 }
1120}
1121
1122#[cfg(feature = "serde")]
1123impl Serialize for ResourceBorrow {
1124 fn serialize<S: Serializer>(&self, _: S) -> Result<S::Ok, S::Error> {
1125 use serde::ser::*;
1126 std::result::Result::Err(S::Error::custom("Cannot serialize resources."))
1127 }
1128}
1129
1130#[cfg(feature = "serde")]
1131impl<'a> Deserialize<'a> for ResourceBorrow {
1132 fn deserialize<D: Deserializer<'a>>(_: D) -> Result<Self, D::Error> {
1133 use serde::de::*;
1134 std::result::Result::Err(D::Error::custom("Cannot deserialize resources."))
1135 }
1136}
1137
1138pub trait ComponentType: 'static + Sized {
1140 fn ty() -> ValueType;
1142
1143 fn from_value(value: &Value) -> Result<Self>;
1145
1146 fn into_value(self) -> Result<Value>;
1148}
1149
1150macro_rules! impl_primitive_component_type {
1152 ($(($type_name: ident, $enum_name: ident))*) => {
1153 $(
1154 impl ComponentType for $type_name {
1155 fn ty() -> ValueType {
1156 ValueType::$enum_name
1157 }
1158
1159 fn from_value(value: &Value) -> Result<Self> {
1160 Ok(require_matches!(value, Value::$enum_name(x), *x))
1161 }
1162
1163 fn into_value(self) -> Result<Value> {
1164 Ok(Value::$enum_name(self))
1165 }
1166 }
1167 )*
1168 };
1169}
1170
1171impl_primitive_component_type!((bool, Bool)(i8, S8)(u8, U8)(i16, S16)(u16, U16)(i32, S32)(
1172 u32, U32
1173)(i64, S64)(u64, U64)(f32, F32)(f64, F64)(char, Char));
1174
1175impl ComponentType for String {
1176 fn ty() -> ValueType {
1177 ValueType::String
1178 }
1179
1180 fn from_value(value: &Value) -> Result<Self> {
1181 Ok(require_matches!(value, Value::String(x), (**x).into()))
1182 }
1183
1184 fn into_value(self) -> Result<Value> {
1185 Ok(Value::String(self.into()))
1186 }
1187}
1188
1189impl ComponentType for Box<str> {
1190 fn ty() -> ValueType {
1191 ValueType::String
1192 }
1193
1194 fn from_value(value: &Value) -> Result<Self> {
1195 Ok(require_matches!(value, Value::String(x), x)
1196 .to_string()
1197 .into())
1198 }
1199
1200 fn into_value(self) -> Result<Value> {
1201 Ok(Value::String(self.into()))
1202 }
1203}
1204
1205impl ComponentType for Arc<str> {
1206 fn ty() -> ValueType {
1207 ValueType::String
1208 }
1209
1210 fn from_value(value: &Value) -> Result<Self> {
1211 Ok(require_matches!(value, Value::String(x), x).clone())
1212 }
1213
1214 fn into_value(self) -> Result<Value> {
1215 Ok(Value::String(self))
1216 }
1217}
1218
1219impl<T: ComponentType> ComponentType for Option<T> {
1220 fn ty() -> ValueType {
1221 ValueType::Option(OptionType::new(T::ty()))
1222 }
1223
1224 fn from_value(value: &Value) -> Result<Self> {
1225 let inner = require_matches!(value, Value::Option(x), x);
1226 if let Some(val) = &**inner {
1227 Ok(Some(T::from_value(val)?))
1228 } else {
1229 Ok(None)
1230 }
1231 }
1232
1233 fn into_value(self) -> Result<Value> {
1234 if let Some(val) = self {
1235 Ok(Value::Option(OptionValue::new(
1236 OptionType::new(T::ty()),
1237 Some(T::into_value(val)?),
1238 )?))
1239 } else {
1240 Ok(Value::Option(OptionValue::new(
1241 OptionType::new(T::ty()),
1242 None,
1243 )?))
1244 }
1245 }
1246}
1247
1248impl<T: ComponentType> ComponentType for Box<T> {
1249 fn ty() -> ValueType {
1250 T::ty()
1251 }
1252
1253 fn from_value(value: &Value) -> Result<Self> {
1254 Ok(Box::new(T::from_value(value)?))
1255 }
1256
1257 fn into_value(self) -> Result<Value> {
1258 Ok(T::into_value(*self)?)
1259 }
1260}
1261
1262impl ComponentType for Result<(), ()> {
1263 fn ty() -> ValueType {
1264 ValueType::Result(ResultType::new(None, None))
1265 }
1266
1267 fn from_value(value: &Value) -> Result<Self> {
1268 match &**require_matches!(value, Value::Result(x), x) {
1269 std::result::Result::Ok(None) => Ok(std::result::Result::Ok(())),
1270 std::result::Result::Err(None) => Ok(std::result::Result::Err(())),
1271 _ => bail!("Incorrect result type."),
1272 }
1273 }
1274
1275 fn into_value(self) -> Result<Value> {
1276 match self {
1277 std::result::Result::Ok(()) => Ok(Value::Result(ResultValue::new(
1278 ResultType::new(None, None),
1279 std::result::Result::Ok(None),
1280 )?)),
1281 std::result::Result::Err(()) => Ok(Value::Result(ResultValue::new(
1282 ResultType::new(None, None),
1283 std::result::Result::Err(None),
1284 )?)),
1285 }
1286 }
1287}
1288
1289impl<T: ComponentType> ComponentType for Result<T, ()> {
1290 fn ty() -> ValueType {
1291 ValueType::Result(ResultType::new(Some(T::ty()), None))
1292 }
1293
1294 fn from_value(value: &Value) -> Result<Self> {
1295 match &**require_matches!(value, Value::Result(x), x) {
1296 std::result::Result::Ok(Some(x)) => Ok(std::result::Result::Ok(T::from_value(x)?)),
1297 std::result::Result::Err(None) => Ok(std::result::Result::Err(())),
1298 _ => bail!("Incorrect result type."),
1299 }
1300 }
1301
1302 fn into_value(self) -> Result<Value> {
1303 match self {
1304 std::result::Result::Ok(x) => Ok(Value::Result(ResultValue::new(
1305 ResultType::new(Some(T::ty()), None),
1306 std::result::Result::Ok(Some(T::into_value(x)?)),
1307 )?)),
1308 std::result::Result::Err(()) => Ok(Value::Result(ResultValue::new(
1309 ResultType::new(Some(T::ty()), None),
1310 std::result::Result::Err(None),
1311 )?)),
1312 }
1313 }
1314}
1315
1316impl<T: ComponentType> ComponentType for Result<(), T> {
1317 fn ty() -> ValueType {
1318 ValueType::Result(ResultType::new(None, Some(T::ty())))
1319 }
1320
1321 fn from_value(value: &Value) -> Result<Self> {
1322 match &**require_matches!(value, Value::Result(x), x) {
1323 std::result::Result::Ok(None) => Ok(std::result::Result::Ok(())),
1324 std::result::Result::Err(Some(v)) => Ok(std::result::Result::Err(T::from_value(v)?)),
1325 _ => bail!("Incorrect result type."),
1326 }
1327 }
1328
1329 fn into_value(self) -> Result<Value> {
1330 match self {
1331 std::result::Result::Ok(()) => Ok(Value::Result(ResultValue::new(
1332 ResultType::new(None, Some(T::ty())),
1333 std::result::Result::Ok(None),
1334 )?)),
1335 std::result::Result::Err(v) => Ok(Value::Result(ResultValue::new(
1336 ResultType::new(None, Some(T::ty())),
1337 std::result::Result::Err(Some(T::into_value(v)?)),
1338 )?)),
1339 }
1340 }
1341}
1342
1343impl<U: ComponentType, V: ComponentType> ComponentType for Result<U, V> {
1344 fn ty() -> ValueType {
1345 ValueType::Result(ResultType::new(Some(U::ty()), Some(V::ty())))
1346 }
1347
1348 fn from_value(value: &Value) -> Result<Self> {
1349 match &**require_matches!(value, Value::Result(x), x) {
1350 std::result::Result::Ok(Some(u)) => Ok(std::result::Result::Ok(U::from_value(u)?)),
1351 std::result::Result::Err(Some(v)) => Ok(std::result::Result::Err(V::from_value(v)?)),
1352 _ => bail!("Incorrect result type."),
1353 }
1354 }
1355
1356 fn into_value(self) -> Result<Value> {
1357 match self {
1358 std::result::Result::Ok(u) => Ok(Value::Result(ResultValue::new(
1359 ResultType::new(Some(U::ty()), Some(V::ty())),
1360 std::result::Result::Ok(Some(U::into_value(u)?)),
1361 )?)),
1362 std::result::Result::Err(v) => Ok(Value::Result(ResultValue::new(
1363 ResultType::new(Some(U::ty()), Some(V::ty())),
1364 std::result::Result::Err(Some(V::into_value(v)?)),
1365 )?)),
1366 }
1367 }
1368}
1369
1370impl<T: ComponentType> ComponentType for Vec<T> {
1371 fn ty() -> ValueType {
1372 ValueType::List(ListType::new(T::ty()))
1373 }
1374
1375 fn from_value(value: &Value) -> Result<Self> {
1376 let list = require_matches!(value, Value::List(x), x);
1377
1378 let id = TypeId::of::<T>();
1379 Ok(if id == TypeId::of::<bool>() {
1380 *(Box::new(require_matches!(&list.values, ListSpecialization::Bool(x), x).to_vec())
1381 as Box<dyn Any>)
1382 .downcast()
1383 .expect("Could not downcast vector.")
1384 } else if id == TypeId::of::<i8>() {
1385 *(Box::new(require_matches!(&list.values, ListSpecialization::S8(x), x).to_vec())
1386 as Box<dyn Any>)
1387 .downcast()
1388 .expect("Could not downcast vector.")
1389 } else if id == TypeId::of::<u8>() {
1390 *(Box::new(require_matches!(&list.values, ListSpecialization::U8(x), x).to_vec())
1391 as Box<dyn Any>)
1392 .downcast()
1393 .expect("Could not downcast vector.")
1394 } else if id == TypeId::of::<i16>() {
1395 *(Box::new(require_matches!(&list.values, ListSpecialization::S16(x), x).to_vec())
1396 as Box<dyn Any>)
1397 .downcast()
1398 .expect("Could not downcast vector.")
1399 } else if id == TypeId::of::<u16>() {
1400 *(Box::new(require_matches!(&list.values, ListSpecialization::U16(x), x).to_vec())
1401 as Box<dyn Any>)
1402 .downcast()
1403 .expect("Could not downcast vector.")
1404 } else if id == TypeId::of::<i32>() {
1405 *(Box::new(require_matches!(&list.values, ListSpecialization::S32(x), x).to_vec())
1406 as Box<dyn Any>)
1407 .downcast()
1408 .expect("Could not downcast vector.")
1409 } else if id == TypeId::of::<u32>() {
1410 *(Box::new(require_matches!(&list.values, ListSpecialization::U32(x), x).to_vec())
1411 as Box<dyn Any>)
1412 .downcast()
1413 .expect("Could not downcast vector.")
1414 } else if id == TypeId::of::<i64>() {
1415 *(Box::new(require_matches!(&list.values, ListSpecialization::S64(x), x).to_vec())
1416 as Box<dyn Any>)
1417 .downcast()
1418 .expect("Could not downcast vector.")
1419 } else if id == TypeId::of::<u64>() {
1420 *(Box::new(require_matches!(&list.values, ListSpecialization::U64(x), x).to_vec())
1421 as Box<dyn Any>)
1422 .downcast()
1423 .expect("Could not downcast vector.")
1424 } else if id == TypeId::of::<f32>() {
1425 *(Box::new(require_matches!(&list.values, ListSpecialization::F32(x), x).to_vec())
1426 as Box<dyn Any>)
1427 .downcast()
1428 .expect("Could not downcast vector.")
1429 } else if id == TypeId::of::<f64>() {
1430 *(Box::new(require_matches!(&list.values, ListSpecialization::F64(x), x).to_vec())
1431 as Box<dyn Any>)
1432 .downcast()
1433 .expect("Could not downcast vector.")
1434 } else if id == TypeId::of::<char>() {
1435 *(Box::new(require_matches!(&list.values, ListSpecialization::Char(x), x).to_vec())
1436 as Box<dyn Any>)
1437 .downcast()
1438 .expect("Could not downcast vector.")
1439 } else {
1440 require_matches!(&list.values, ListSpecialization::Other(x), x)
1441 .iter()
1442 .map(|x| T::from_value(x))
1443 .collect::<Result<_>>()?
1444 })
1445 }
1446
1447 fn into_value(self) -> Result<Value> {
1448 let holder = Box::new(self) as Box<dyn Any>;
1449 let id = TypeId::of::<T>();
1450 Ok(Value::List(if id == TypeId::of::<bool>() {
1451 List {
1452 ty: ListType::new(ValueType::Bool),
1453 values: ListSpecialization::Bool(Arc::from(
1454 *(holder)
1455 .downcast::<Vec<bool>>()
1456 .expect("Could not downcast vector."),
1457 )),
1458 }
1459 } else if id == TypeId::of::<i8>() {
1460 List {
1461 ty: ListType::new(ValueType::S8),
1462 values: ListSpecialization::S8(Arc::from(
1463 *(holder)
1464 .downcast::<Vec<i8>>()
1465 .expect("Could not downcast vector."),
1466 )),
1467 }
1468 } else if id == TypeId::of::<u8>() {
1469 List {
1470 ty: ListType::new(ValueType::U8),
1471 values: ListSpecialization::U8(Arc::from(
1472 *(holder)
1473 .downcast::<Vec<u8>>()
1474 .expect("Could not downcast vector."),
1475 )),
1476 }
1477 } else if id == TypeId::of::<i16>() {
1478 List {
1479 ty: ListType::new(ValueType::S16),
1480 values: ListSpecialization::S16(Arc::from(
1481 *(holder)
1482 .downcast::<Vec<i16>>()
1483 .expect("Could not downcast vector."),
1484 )),
1485 }
1486 } else if id == TypeId::of::<u16>() {
1487 List {
1488 ty: ListType::new(ValueType::U16),
1489 values: ListSpecialization::U16(Arc::from(
1490 *(holder)
1491 .downcast::<Vec<u16>>()
1492 .expect("Could not downcast vector."),
1493 )),
1494 }
1495 } else if id == TypeId::of::<i32>() {
1496 List {
1497 ty: ListType::new(ValueType::S32),
1498 values: ListSpecialization::S32(Arc::from(
1499 *(holder)
1500 .downcast::<Vec<i32>>()
1501 .expect("Could not downcast vector."),
1502 )),
1503 }
1504 } else if id == TypeId::of::<u32>() {
1505 List {
1506 ty: ListType::new(ValueType::U32),
1507 values: ListSpecialization::U32(Arc::from(
1508 *(holder)
1509 .downcast::<Vec<u32>>()
1510 .expect("Could not downcast vector."),
1511 )),
1512 }
1513 } else if id == TypeId::of::<i64>() {
1514 List {
1515 ty: ListType::new(ValueType::S64),
1516 values: ListSpecialization::S64(Arc::from(
1517 *(holder)
1518 .downcast::<Vec<i64>>()
1519 .expect("Could not downcast vector."),
1520 )),
1521 }
1522 } else if id == TypeId::of::<u64>() {
1523 List {
1524 ty: ListType::new(ValueType::U64),
1525 values: ListSpecialization::U64(Arc::from(
1526 *(holder)
1527 .downcast::<Vec<u64>>()
1528 .expect("Could not downcast vector."),
1529 )),
1530 }
1531 } else if id == TypeId::of::<f32>() {
1532 List {
1533 ty: ListType::new(ValueType::F32),
1534 values: ListSpecialization::F32(Arc::from(
1535 *(holder)
1536 .downcast::<Vec<f32>>()
1537 .expect("Could not downcast vector."),
1538 )),
1539 }
1540 } else if id == TypeId::of::<f64>() {
1541 List {
1542 ty: ListType::new(ValueType::F64),
1543 values: ListSpecialization::F64(Arc::from(
1544 *(holder)
1545 .downcast::<Vec<f64>>()
1546 .expect("Could not downcast vector."),
1547 )),
1548 }
1549 } else if id == TypeId::of::<char>() {
1550 List {
1551 ty: ListType::new(ValueType::Char),
1552 values: ListSpecialization::Char(Arc::from(
1553 *(holder)
1554 .downcast::<Vec<char>>()
1555 .expect("Could not downcast vector."),
1556 )),
1557 }
1558 } else {
1559 List {
1560 ty: ListType::new(T::ty()),
1561 values: ListSpecialization::Other(
1562 holder
1563 .downcast::<Vec<T>>()
1564 .expect("Could not downcast vector.")
1565 .into_iter()
1566 .map(|x| x.into_value())
1567 .collect::<Result<_>>()?,
1568 ),
1569 }
1570 }))
1571 }
1572}
1573
1574macro_rules! tuple_impl {
1576 ($($idx: tt $ty: ident), *) => {
1577 impl<$($ty: ComponentType),*> ComponentType for ($($ty,)*) {
1578 fn ty() -> ValueType {
1579 ValueType::Tuple(TupleType::new(None, [$(<$ty as ComponentType>::ty(),)*]))
1580 }
1581
1582 fn from_value(value: &Value) -> Result<Self> {
1583 Ok(require_matches!(
1584 value,
1585 Value::Tuple(x),
1586 ($(<$ty as ComponentType>::from_value(&x.fields[$idx])?,)*)
1587 ))
1588 }
1589
1590 fn into_value(self) -> Result<Value> {
1591 Ok(Value::Tuple(Tuple::new(
1592 TupleType::new(None, [$(<$ty as ComponentType>::ty(),)*]),
1593 [$(<$ty as ComponentType>::into_value(self.$idx)?,)*]
1594 )?))
1595 }
1596 }
1597 };
1598}
1599
1600tuple_impl! { 0 A }
1601tuple_impl! { 0 A, 1 B }
1602tuple_impl! { 0 A, 1 B, 2 C }
1603tuple_impl! { 0 A, 1 B, 2 C, 3 D }
1604tuple_impl! { 0 A, 1 B, 2 C, 3 D, 4 E }
1605tuple_impl! { 0 A, 1 B, 2 C, 3 D, 4 E, 5 F }
1606tuple_impl! { 0 A, 1 B, 2 C, 3 D, 4 E, 5 F, 6 G }
1607tuple_impl! { 0 A, 1 B, 2 C, 3 D, 4 E, 5 F, 6 G, 7 H }
1608
1609pub trait UnaryComponentType: ComponentType {}
1611
1612macro_rules! impl_unary {
1614 ($([$($param: ident: $bound: ident),*] $ty: ty,)*) => {
1615 $( impl<$($param: $bound),*> UnaryComponentType for $ty {} )*
1616 };
1617}
1618
1619impl_unary!(
1620 [] bool,
1621 [] i8,
1622 [] u8,
1623 [] i16,
1624 [] u16,
1625 [] i32,
1626 [] u32,
1627 [] i64,
1628 [] u64,
1629 [] f32,
1630 [] f64,
1631 [] char,
1632 [] String,
1633 [] Box<str>,
1634 [] Arc<str>,
1635 [T: ComponentType] Option<T>,
1636 [T: ComponentType] Box<T>,
1637 [T: ComponentType] Vec<T>,
1638 [T: ComponentType, U: ComponentType] Result<T, U>,
1639 [] Result<(), ()>,
1640 [U: ComponentType] Result<(), U>,
1641 [T: ComponentType] Result<T, ()>,
1642);
1643
1644mod private {
1646 use super::*;
1647
1648 #[derive(Clone, Debug, PartialEq)]
1650 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1651 pub enum ListSpecialization {
1652 Bool(Arc<[bool]>),
1654 S8(#[cfg_attr(feature = "serde", serde(with = "serialize_specialized"))] Arc<[i8]>),
1656 U8(#[cfg_attr(feature = "serde", serde(with = "serialize_specialized"))] Arc<[u8]>),
1658 S16(#[cfg_attr(feature = "serde", serde(with = "serialize_specialized"))] Arc<[i16]>),
1660 U16(#[cfg_attr(feature = "serde", serde(with = "serialize_specialized"))] Arc<[u16]>),
1662 S32(#[cfg_attr(feature = "serde", serde(with = "serialize_specialized"))] Arc<[i32]>),
1664 U32(#[cfg_attr(feature = "serde", serde(with = "serialize_specialized"))] Arc<[u32]>),
1666 S64(#[cfg_attr(feature = "serde", serde(with = "serialize_specialized"))] Arc<[i64]>),
1668 U64(#[cfg_attr(feature = "serde", serde(with = "serialize_specialized"))] Arc<[u64]>),
1670 F32(#[cfg_attr(feature = "serde", serde(with = "serialize_specialized"))] Arc<[f32]>),
1672 F64(#[cfg_attr(feature = "serde", serde(with = "serialize_specialized"))] Arc<[f64]>),
1674 Char(Arc<[char]>),
1676 Other(Arc<[Value]>),
1678 }
1679
1680 #[cfg(feature = "serde")]
1681 mod serialize_specialized {
1683 use super::*;
1684
1685 pub fn serialize<S: Serializer, A: Pod>(
1687 value: &Arc<[A]>,
1688 serializer: S,
1689 ) -> Result<S::Ok, S::Error> {
1690 if cfg!(target_endian = "little") || size_of::<A>() == 1 {
1691 serializer.serialize_bytes(cast_slice(value))
1692 } else {
1693 let mut bytes = cast_slice::<_, u8>(value).to_vec();
1694
1695 for chunk in bytes.chunks_exact_mut(size_of::<A>()) {
1696 chunk.reverse();
1697 }
1698
1699 serializer.serialize_bytes(&bytes)
1700 }
1701 }
1702
1703 pub fn deserialize<'a, D: Deserializer<'a>, A: Pod>(
1705 deserializer: D,
1706 ) -> Result<Arc<[A]>, D::Error> {
1707 use serde::de::*;
1708
1709 let mut byte_data = Arc::<[u8]>::deserialize(deserializer)?;
1710
1711 if !(cfg!(target_endian = "little") || size_of::<A>() == 1) {
1712 for chunk in Arc::get_mut(&mut byte_data)
1713 .expect("Could not get exclusive reference.")
1714 .chunks_exact_mut(size_of::<A>())
1715 {
1716 chunk.reverse();
1717 }
1718 }
1719
1720 try_cast_slice_arc(byte_data).map_err(|(x, _)| D::Error::custom(x))
1721 }
1722 }
1723
1724 impl<'a> IntoIterator for &'a ListSpecialization {
1725 type Item = Value;
1726
1727 type IntoIter = ListSpecializationIter<'a>;
1728
1729 fn into_iter(self) -> Self::IntoIter {
1730 match self {
1731 ListSpecialization::Bool(x) => ListSpecializationIter::Bool(x.iter()),
1732 ListSpecialization::S8(x) => ListSpecializationIter::S8(x.iter()),
1733 ListSpecialization::U8(x) => ListSpecializationIter::U8(x.iter()),
1734 ListSpecialization::S16(x) => ListSpecializationIter::S16(x.iter()),
1735 ListSpecialization::U16(x) => ListSpecializationIter::U16(x.iter()),
1736 ListSpecialization::S32(x) => ListSpecializationIter::S32(x.iter()),
1737 ListSpecialization::U32(x) => ListSpecializationIter::U32(x.iter()),
1738 ListSpecialization::S64(x) => ListSpecializationIter::S64(x.iter()),
1739 ListSpecialization::U64(x) => ListSpecializationIter::U64(x.iter()),
1740 ListSpecialization::F32(x) => ListSpecializationIter::F32(x.iter()),
1741 ListSpecialization::F64(x) => ListSpecializationIter::F64(x.iter()),
1742 ListSpecialization::Char(x) => ListSpecializationIter::Char(x.iter()),
1743 ListSpecialization::Other(x) => ListSpecializationIter::Other(x.iter()),
1744 }
1745 }
1746 }
1747
1748 pub enum ListSpecializationIter<'a> {
1750 Bool(std::slice::Iter<'a, bool>),
1752 S8(std::slice::Iter<'a, i8>),
1754 U8(std::slice::Iter<'a, u8>),
1756 S16(std::slice::Iter<'a, i16>),
1758 U16(std::slice::Iter<'a, u16>),
1760 S32(std::slice::Iter<'a, i32>),
1762 U32(std::slice::Iter<'a, u32>),
1764 S64(std::slice::Iter<'a, i64>),
1766 U64(std::slice::Iter<'a, u64>),
1768 F32(std::slice::Iter<'a, f32>),
1770 F64(std::slice::Iter<'a, f64>),
1772 Char(std::slice::Iter<'a, char>),
1774 Other(std::slice::Iter<'a, Value>),
1776 }
1777
1778 impl<'a> Iterator for ListSpecializationIter<'a> {
1779 type Item = Value;
1780
1781 fn next(&mut self) -> Option<Self::Item> {
1782 Some(match self {
1783 ListSpecializationIter::Bool(x) => Value::from(x.next()?),
1784 ListSpecializationIter::S8(x) => Value::from(x.next()?),
1785 ListSpecializationIter::U8(x) => Value::from(x.next()?),
1786 ListSpecializationIter::S16(x) => Value::from(x.next()?),
1787 ListSpecializationIter::U16(x) => Value::from(x.next()?),
1788 ListSpecializationIter::S32(x) => Value::from(x.next()?),
1789 ListSpecializationIter::U32(x) => Value::from(x.next()?),
1790 ListSpecializationIter::S64(x) => Value::from(x.next()?),
1791 ListSpecializationIter::U64(x) => Value::from(x.next()?),
1792 ListSpecializationIter::F32(x) => Value::from(x.next()?),
1793 ListSpecializationIter::F64(x) => Value::from(x.next()?),
1794 ListSpecializationIter::Char(x) => Value::from(x.next()?),
1795 ListSpecializationIter::Other(x) => x.next()?.clone(),
1796 })
1797 }
1798 }
1799
1800 pub trait ListPrimitive: Copy + Sized {
1802 fn from_arc(arc: Arc<[Self]>) -> ListSpecialization;
1804 fn from_value_iter(iter: impl IntoIterator<Item = Value>) -> Result<ListSpecialization>;
1806 fn from_specialization(specialization: &ListSpecialization) -> &[Self];
1808 fn ty() -> ValueType;
1810 }
1811
1812 macro_rules! impl_list_primitive {
1814 ($(($type_name: ident, $enum_name: ident))*) => {
1815 $(
1816 impl ListPrimitive for $type_name {
1817 fn from_arc(arc: Arc<[Self]>) -> ListSpecialization {
1818 ListSpecialization::$enum_name(arc)
1819 }
1820
1821 fn from_value_iter(iter: impl IntoIterator<Item = Value>) -> Result<ListSpecialization> {
1822 let values: Arc<[Self]> = iter.into_iter().map(|x| TryInto::try_into(&x)).collect::<Result<_>>()?;
1823 Ok(ListSpecialization::$enum_name(values))
1824 }
1825
1826 fn from_specialization(specialization: &ListSpecialization) -> &[Self] {
1827 if let ListSpecialization::$enum_name(vals) = specialization {
1828 &vals
1829 }
1830 else {
1831 panic!("Incorrect specialization type.");
1832 }
1833 }
1834
1835 fn ty() -> ValueType {
1836 ValueType::$enum_name
1837 }
1838 }
1839 )*
1840 };
1841 }
1842
1843 impl_list_primitive!((bool, Bool)(i8, S8)(u8, U8)(i16, S16)(u16, U16)(i32, S32)(
1844 u32, U32
1845 )(i64, S64)(u64, U64)(f32, F32)(f64, F64)(char, Char));
1846}