1use crate::store::{AutoAssertNoGc, StoreOpaque};
2use crate::{Result, ValRaw, ValType, WasmTy};
3use core::cmp::Ordering;
4use core::mem::MaybeUninit;
5use core::{fmt, mem};
6
7#[derive(Copy, Clone)]
23#[repr(transparent)]
24pub struct V128(
25 [u8; mem::size_of::<u128>()],
29);
30
31impl V128 {
32 pub fn as_u128(&self) -> u128 {
34 u128::from_ne_bytes(self.0)
35 }
36}
37
38impl From<u128> for V128 {
40 fn from(val: u128) -> V128 {
41 Self(val.to_ne_bytes())
42 }
43}
44
45impl From<V128> for u128 {
46 fn from(val: V128) -> u128 {
47 val.as_u128()
48 }
49}
50
51impl fmt::Debug for V128 {
52 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53 self.as_u128().fmt(f)
54 }
55}
56
57impl PartialEq for V128 {
58 fn eq(&self, other: &V128) -> bool {
59 self.as_u128() == other.as_u128()
60 }
61}
62
63impl Eq for V128 {}
64
65impl PartialOrd for V128 {
66 fn partial_cmp(&self, other: &V128) -> Option<Ordering> {
67 Some(self.cmp(other))
68 }
69}
70
71impl Ord for V128 {
72 fn cmp(&self, other: &V128) -> Ordering {
73 self.as_u128().cmp(&other.as_u128())
74 }
75}
76
77unsafe impl WasmTy for V128 {
80 #[inline]
81 fn valtype() -> ValType {
82 ValType::V128
83 }
84
85 #[inline]
86 fn compatible_with_store(&self, _: &StoreOpaque) -> bool {
87 true
88 }
89
90 fn dynamic_concrete_type_check(
91 &self,
92 _: &StoreOpaque,
93 _: bool,
94 _: &crate::HeapType,
95 ) -> anyhow::Result<()> {
96 unreachable!()
97 }
98
99 #[inline]
100 fn store(self, _store: &mut AutoAssertNoGc<'_>, ptr: &mut MaybeUninit<ValRaw>) -> Result<()> {
101 ptr.write(ValRaw::v128(self.as_u128()));
102 Ok(())
103 }
104
105 #[inline]
106 unsafe fn load(_store: &mut AutoAssertNoGc<'_>, ptr: &ValRaw) -> Self {
107 V128::from(ptr.get_v128())
108 }
109}