dusk_wasmtime/runtime/
v128.rs

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 std::cmp::Ordering;
9use std::fmt;
10use wasmtime_runtime::V128Abi;
11
12/// Representation of a 128-bit vector type, `v128`, for WebAssembly.
13///
14/// This type corresponds to the `v128` type in WebAssembly and can be used with
15/// the [`TypedFunc`] API for example. This is additionally
16/// the payload of [`Val::V128`](crate::Val).
17///
18/// # Platform specifics
19///
20/// This type can currently only be used on x86_64 and AArch64 with the
21/// [`TypedFunc`] API. Rust does not have stable support on other platforms for
22/// this type so invoking functions with `v128` parameters requires the
23/// [`Func::call`](crate::Func::call) API (or perhaps
24/// [`Func::call_unchecked`](crate::Func::call_unchecked).
25///
26/// [`TypedFunc`]: crate::TypedFunc
27#[derive(Copy, Clone)]
28#[repr(transparent)]
29pub struct V128(V128Abi);
30
31union Reinterpret {
32    abi: V128Abi,
33    u128: u128,
34}
35
36impl V128 {
37    /// Returns the representation of this `v128` as a 128-bit integer in Rust.
38    pub fn as_u128(&self) -> u128 {
39        unsafe { Reinterpret { abi: self.0 }.u128 }
40    }
41}
42
43/// Primary constructor of a `V128` type.
44impl From<u128> for V128 {
45    fn from(val: u128) -> V128 {
46        unsafe { V128(Reinterpret { u128: val }.abi) }
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// Note that this trait is conditionally implemented which is intentional. See
83// the documentation above in the `cfg_if!` for why this is conditional.
84#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
85unsafe impl WasmTy for V128 {
86    type Abi = V128Abi;
87
88    #[inline]
89    fn valtype() -> ValType {
90        ValType::V128
91    }
92
93    #[inline]
94    fn compatible_with_store(&self, _: &StoreOpaque) -> bool {
95        true
96    }
97
98    fn dynamic_concrete_type_check(
99        &self,
100        _: &StoreOpaque,
101        _: bool,
102        _: &crate::FuncType,
103    ) -> anyhow::Result<()> {
104        unreachable!()
105    }
106
107    #[inline]
108    fn is_non_i31_gc_ref(&self) -> bool {
109        false
110    }
111
112    #[inline]
113    unsafe fn abi_from_raw(raw: *mut ValRaw) -> Self::Abi {
114        V128::from((*raw).get_v128()).0
115    }
116
117    #[inline]
118    unsafe fn abi_into_raw(abi: Self::Abi, raw: *mut ValRaw) {
119        *raw = ValRaw::v128(V128(abi).as_u128());
120    }
121
122    #[inline]
123    fn into_abi(self, _store: &mut AutoAssertNoGc<'_>) -> Result<Self::Abi> {
124        Ok(self.0)
125    }
126
127    #[inline]
128    unsafe fn from_abi(abi: Self::Abi, _store: &mut AutoAssertNoGc<'_>) -> Self {
129        V128(abi)
130    }
131}