wasm/execution/checked/
value.rs

1use crate::{
2    addrs::FuncAddr,
3    value::{ExternAddr, Ref, ValueTypeMismatchError, F32, F64},
4    RefType, Value,
5};
6
7use super::{AbstractStored, Stored};
8
9/// A stored variant of [`Value`]
10#[derive(Clone, Copy, Debug, PartialEq)]
11pub enum StoredValue {
12    I32(u32),
13    I64(u64),
14    F32(F32),
15    F64(F64),
16    V128([u8; 16]),
17    Ref(StoredRef),
18}
19
20impl AbstractStored for StoredValue {
21    type BareTy = Value;
22
23    unsafe fn from_bare(bare_value: Self::BareTy, id: crate::StoreId) -> Self {
24        match bare_value {
25            Value::I32(x) => Self::I32(x),
26            Value::I64(x) => Self::I64(x),
27            Value::F32(x) => Self::F32(x),
28            Value::F64(x) => Self::F64(x),
29            Value::V128(x) => Self::V128(x),
30            Value::Ref(r#ref) => Self::Ref(StoredRef::from_bare(r#ref, id)),
31        }
32    }
33
34    fn id(&self) -> Option<crate::StoreId> {
35        match self {
36            Self::Ref(r#ref) => r#ref.id(),
37            _ => None,
38        }
39    }
40
41    fn into_bare(self) -> Self::BareTy {
42        match self {
43            Self::I32(x) => Value::I32(x),
44            Self::I64(x) => Value::I64(x),
45            Self::F32(x) => Value::F32(x),
46            Self::F64(x) => Value::F64(x),
47            Self::V128(x) => Value::V128(x),
48            Self::Ref(stored_ref) => Value::Ref(stored_ref.into_bare()),
49        }
50    }
51}
52
53/// A stored variant of [`Ref`]
54#[derive(Clone, Copy, Debug, PartialEq)]
55pub enum StoredRef {
56    Null(RefType),
57    Func(Stored<FuncAddr>),
58    /// We do not wrap [`ExternAddr`]s in a [`Stored`] object because they are
59    /// not stored in the [`Store`](crate::Store).
60    Extern(ExternAddr),
61}
62
63impl AbstractStored for StoredRef {
64    type BareTy = Ref;
65
66    unsafe fn from_bare(bare_value: Self::BareTy, id: crate::StoreId) -> Self {
67        match bare_value {
68            Ref::Null(ref_type) => Self::Null(ref_type),
69            Ref::Func(func_addr) => Self::Func(Stored::from_bare(func_addr, id)),
70            Ref::Extern(extern_addr) => Self::Extern(extern_addr),
71        }
72    }
73
74    fn id(&self) -> Option<crate::StoreId> {
75        match self {
76            StoredRef::Func(stored_func_addr) => stored_func_addr.id(),
77            StoredRef::Null(_) | StoredRef::Extern(_) => None,
78        }
79    }
80
81    fn into_bare(self) -> Self::BareTy {
82        match self {
83            Self::Null(ref_type) => Ref::Null(ref_type),
84            Self::Func(stored_func_addr) => Ref::Func(stored_func_addr.into_bare()),
85            Self::Extern(extern_addr) => Ref::Extern(extern_addr),
86        }
87    }
88}
89
90impl From<u32> for StoredValue {
91    fn from(value: u32) -> Self {
92        StoredValue::I32(value)
93    }
94}
95impl TryFrom<StoredValue> for u32 {
96    type Error = ValueTypeMismatchError;
97
98    fn try_from(value: StoredValue) -> Result<Self, Self::Error> {
99        match value {
100            StoredValue::I32(value) => Ok(value),
101            _ => Err(ValueTypeMismatchError),
102        }
103    }
104}
105
106impl From<i32> for StoredValue {
107    fn from(value: i32) -> Self {
108        StoredValue::I32(u32::from_le_bytes(value.to_le_bytes()))
109    }
110}
111impl TryFrom<StoredValue> for i32 {
112    type Error = ValueTypeMismatchError;
113
114    fn try_from(value: StoredValue) -> Result<Self, Self::Error> {
115        match value {
116            StoredValue::I32(value) => Ok(i32::from_le_bytes(value.to_le_bytes())),
117            _ => Err(ValueTypeMismatchError),
118        }
119    }
120}
121
122impl From<u64> for StoredValue {
123    fn from(value: u64) -> Self {
124        StoredValue::I64(value)
125    }
126}
127impl TryFrom<StoredValue> for u64 {
128    type Error = ValueTypeMismatchError;
129
130    fn try_from(value: StoredValue) -> Result<Self, Self::Error> {
131        match value {
132            StoredValue::I64(value) => Ok(value),
133            _ => Err(ValueTypeMismatchError),
134        }
135    }
136}
137
138impl From<i64> for StoredValue {
139    fn from(value: i64) -> Self {
140        StoredValue::I64(u64::from_le_bytes(value.to_le_bytes()))
141    }
142}
143impl TryFrom<StoredValue> for i64 {
144    type Error = ValueTypeMismatchError;
145
146    fn try_from(value: StoredValue) -> Result<Self, Self::Error> {
147        match value {
148            StoredValue::I64(value) => Ok(i64::from_le_bytes(value.to_le_bytes())),
149            _ => Err(ValueTypeMismatchError),
150        }
151    }
152}
153
154impl From<F32> for StoredValue {
155    fn from(value: F32) -> Self {
156        StoredValue::F32(value)
157    }
158}
159impl TryFrom<StoredValue> for F32 {
160    type Error = ValueTypeMismatchError;
161
162    fn try_from(value: StoredValue) -> Result<Self, Self::Error> {
163        match value {
164            StoredValue::F32(value) => Ok(value),
165            _ => Err(ValueTypeMismatchError),
166        }
167    }
168}
169
170impl From<F64> for StoredValue {
171    fn from(value: F64) -> Self {
172        StoredValue::F64(value)
173    }
174}
175impl TryFrom<StoredValue> for F64 {
176    type Error = ValueTypeMismatchError;
177
178    fn try_from(value: StoredValue) -> Result<Self, Self::Error> {
179        match value {
180            StoredValue::F64(value) => Ok(value),
181            _ => Err(ValueTypeMismatchError),
182        }
183    }
184}
185
186impl From<[u8; 16]> for StoredValue {
187    fn from(value: [u8; 16]) -> Self {
188        StoredValue::V128(value)
189    }
190}
191impl TryFrom<StoredValue> for [u8; 16] {
192    type Error = ValueTypeMismatchError;
193
194    fn try_from(value: StoredValue) -> Result<Self, Self::Error> {
195        match value {
196            StoredValue::V128(value) => Ok(value),
197            _ => Err(ValueTypeMismatchError),
198        }
199    }
200}
201
202impl From<StoredRef> for StoredValue {
203    fn from(value: StoredRef) -> Self {
204        StoredValue::Ref(value)
205    }
206}
207impl TryFrom<StoredValue> for StoredRef {
208    type Error = ValueTypeMismatchError;
209
210    fn try_from(value: StoredValue) -> Result<Self, Self::Error> {
211        match value {
212            StoredValue::Ref(value) => Ok(value),
213            _ => Err(ValueTypeMismatchError),
214        }
215    }
216}