1pub use wasmparser;
5
6use cranelift_entity::entity_impl;
7
8use serde::{Deserialize, Serialize};
9use std::convert::{TryFrom, TryInto};
10use std::fmt;
11
12mod error;
13pub use error::*;
14
15#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
17pub enum WasmType {
18 I32,
20 I64,
22 F32,
24 F64,
26 V128,
28 FuncRef,
30 ExternRef,
32}
33
34impl TryFrom<wasmparser::ValType> for WasmType {
35 type Error = WasmError;
36 fn try_from(ty: wasmparser::ValType) -> Result<Self, Self::Error> {
37 use wasmparser::ValType::*;
38 match ty {
39 I32 => Ok(WasmType::I32),
40 I64 => Ok(WasmType::I64),
41 F32 => Ok(WasmType::F32),
42 F64 => Ok(WasmType::F64),
43 V128 => Ok(WasmType::V128),
44 Ref(r) => r.try_into(),
45 }
46 }
47}
48
49impl TryFrom<wasmparser::RefType> for WasmType {
50 type Error = WasmError;
51 fn try_from(ty: wasmparser::RefType) -> Result<Self, Self::Error> {
52 match ty {
53 wasmparser::RefType::FUNCREF => Ok(WasmType::FuncRef),
54 wasmparser::RefType::EXTERNREF => Ok(WasmType::ExternRef),
55 _ => Err(WasmError::Unsupported(
56 "function references proposal".to_string(),
57 )),
58 }
59 }
60}
61
62impl TryFrom<wasmparser::HeapType> for WasmType {
63 type Error = WasmError;
64 fn try_from(ty: wasmparser::HeapType) -> Result<Self, Self::Error> {
65 match ty {
66 wasmparser::HeapType::Func => Ok(WasmType::FuncRef),
67 wasmparser::HeapType::Extern => Ok(WasmType::ExternRef),
68 _ => Err(WasmError::Unsupported(
72 "function references proposal".to_string(),
73 )),
74 }
75 }
76}
77
78impl From<WasmType> for wasmparser::ValType {
79 fn from(ty: WasmType) -> wasmparser::ValType {
80 match ty {
81 WasmType::I32 => wasmparser::ValType::I32,
82 WasmType::I64 => wasmparser::ValType::I64,
83 WasmType::F32 => wasmparser::ValType::F32,
84 WasmType::F64 => wasmparser::ValType::F64,
85 WasmType::V128 => wasmparser::ValType::V128,
86 WasmType::FuncRef => wasmparser::ValType::FUNCREF,
87 WasmType::ExternRef => wasmparser::ValType::EXTERNREF,
88 }
89 }
90}
91
92impl fmt::Display for WasmType {
93 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94 match self {
95 WasmType::I32 => write!(f, "i32"),
96 WasmType::I64 => write!(f, "i64"),
97 WasmType::F32 => write!(f, "f32"),
98 WasmType::F64 => write!(f, "f64"),
99 WasmType::V128 => write!(f, "v128"),
100 WasmType::ExternRef => write!(f, "externref"),
101 WasmType::FuncRef => write!(f, "funcref"),
102 }
103 }
104}
105
106#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
108pub struct WasmFuncType {
109 params: Box<[WasmType]>,
110 externref_params_count: usize,
111 returns: Box<[WasmType]>,
112 externref_returns_count: usize,
113}
114
115impl WasmFuncType {
116 #[inline]
117 pub fn new(params: Box<[WasmType]>, returns: Box<[WasmType]>) -> Self {
118 let externref_params_count = params.iter().filter(|p| **p == WasmType::ExternRef).count();
119 let externref_returns_count = returns
120 .iter()
121 .filter(|r| **r == WasmType::ExternRef)
122 .count();
123 WasmFuncType {
124 params,
125 externref_params_count,
126 returns,
127 externref_returns_count,
128 }
129 }
130
131 #[inline]
133 pub fn params(&self) -> &[WasmType] {
134 &self.params
135 }
136
137 #[inline]
139 pub fn externref_params_count(&self) -> usize {
140 self.externref_params_count
141 }
142
143 #[inline]
145 pub fn returns(&self) -> &[WasmType] {
146 &self.returns
147 }
148
149 #[inline]
151 pub fn externref_returns_count(&self) -> usize {
152 self.externref_returns_count
153 }
154}
155
156impl TryFrom<wasmparser::FuncType> for WasmFuncType {
157 type Error = WasmError;
158 fn try_from(ty: wasmparser::FuncType) -> Result<Self, Self::Error> {
159 let params = ty
160 .params()
161 .iter()
162 .copied()
163 .map(WasmType::try_from)
164 .collect::<Result<_, Self::Error>>()?;
165 let returns = ty
166 .results()
167 .iter()
168 .copied()
169 .map(WasmType::try_from)
170 .collect::<Result<_, Self::Error>>()?;
171 Ok(Self::new(params, returns))
172 }
173}
174
175#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
177pub struct FuncIndex(u32);
178entity_impl!(FuncIndex);
179
180#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
182pub struct DefinedFuncIndex(u32);
183entity_impl!(DefinedFuncIndex);
184
185#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
187pub struct DefinedTableIndex(u32);
188entity_impl!(DefinedTableIndex);
189
190#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
192pub struct DefinedMemoryIndex(u32);
193entity_impl!(DefinedMemoryIndex);
194
195#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
197pub struct OwnedMemoryIndex(u32);
198entity_impl!(OwnedMemoryIndex);
199
200#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
202pub struct DefinedGlobalIndex(u32);
203entity_impl!(DefinedGlobalIndex);
204
205#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
207pub struct TableIndex(u32);
208entity_impl!(TableIndex);
209
210#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
212pub struct GlobalIndex(u32);
213entity_impl!(GlobalIndex);
214
215#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
217pub struct MemoryIndex(u32);
218entity_impl!(MemoryIndex);
219
220#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
222pub struct SignatureIndex(u32);
223entity_impl!(SignatureIndex);
224
225#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
227pub struct DataIndex(u32);
228entity_impl!(DataIndex);
229
230#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
232pub struct ElemIndex(u32);
233entity_impl!(ElemIndex);
234
235#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
237pub struct TypeIndex(u32);
238entity_impl!(TypeIndex);
239
240#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
242pub struct TagIndex(u32);
243entity_impl!(TagIndex);
244
245#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
247pub enum EntityIndex {
248 Function(FuncIndex),
250 Table(TableIndex),
252 Memory(MemoryIndex),
254 Global(GlobalIndex),
256}
257
258impl From<FuncIndex> for EntityIndex {
259 fn from(idx: FuncIndex) -> EntityIndex {
260 EntityIndex::Function(idx)
261 }
262}
263
264impl From<TableIndex> for EntityIndex {
265 fn from(idx: TableIndex) -> EntityIndex {
266 EntityIndex::Table(idx)
267 }
268}
269
270impl From<MemoryIndex> for EntityIndex {
271 fn from(idx: MemoryIndex) -> EntityIndex {
272 EntityIndex::Memory(idx)
273 }
274}
275
276impl From<GlobalIndex> for EntityIndex {
277 fn from(idx: GlobalIndex) -> EntityIndex {
278 EntityIndex::Global(idx)
279 }
280}
281
282#[allow(missing_docs)]
285#[derive(Clone, Debug, Serialize, Deserialize)]
286pub enum EntityType {
287 Global(Global),
289 Memory(Memory),
291 Tag(Tag),
293 Table(Table),
295 Function(SignatureIndex),
298}
299
300#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Serialize, Deserialize)]
308pub struct Global {
309 pub wasm_ty: crate::WasmType,
311 pub mutability: bool,
313 pub initializer: GlobalInit,
315}
316
317#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Serialize, Deserialize)]
319pub enum GlobalInit {
320 I32Const(i32),
322 I64Const(i64),
324 F32Const(u32),
326 F64Const(u64),
328 V128Const(u128),
330 GetGlobal(GlobalIndex),
332 RefNullConst,
334 RefFunc(FuncIndex),
336 Import,
338}
339
340impl Global {
341 pub fn new(ty: wasmparser::GlobalType, initializer: GlobalInit) -> WasmResult<Global> {
343 Ok(Global {
344 wasm_ty: ty.content_type.try_into()?,
345 mutability: ty.mutable,
346 initializer,
347 })
348 }
349}
350
351#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Serialize, Deserialize)]
353pub struct Table {
354 pub wasm_ty: WasmType,
356 pub minimum: u32,
358 pub maximum: Option<u32>,
360}
361
362impl TryFrom<wasmparser::TableType> for Table {
363 type Error = WasmError;
364
365 fn try_from(ty: wasmparser::TableType) -> WasmResult<Table> {
366 Ok(Table {
367 wasm_ty: ty.element_type.try_into()?,
368 minimum: ty.initial,
369 maximum: ty.maximum,
370 })
371 }
372}
373
374#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Serialize, Deserialize)]
376pub struct Memory {
377 pub minimum: u64,
379 pub maximum: Option<u64>,
381 pub shared: bool,
383 pub memory64: bool,
385}
386
387impl From<wasmparser::MemoryType> for Memory {
388 fn from(ty: wasmparser::MemoryType) -> Memory {
389 Memory {
390 minimum: ty.initial,
391 maximum: ty.maximum,
392 shared: ty.shared,
393 memory64: ty.memory64,
394 }
395 }
396}
397
398#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Serialize, Deserialize)]
400pub struct Tag {
401 pub ty: TypeIndex,
403}
404
405impl From<wasmparser::TagType> for Tag {
406 fn from(ty: wasmparser::TagType) -> Tag {
407 match ty.kind {
408 wasmparser::TagKind::Exception => Tag {
409 ty: TypeIndex::from_u32(ty.func_type_idx),
410 },
411 }
412 }
413}