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) => 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#[derive(Clone, Copy, Debug, PartialEq)]
55pub enum StoredRef {
56 Null(RefType),
57 Func(Stored<FuncAddr>),
58 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}