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