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