1use crate::structure::*;
23
24#[derive(Debug, Clone, PartialEq, Copy)]
25pub struct Name<'a> {
26 pub name: &'a str,
27}
28
29#[derive(Debug, Clone, PartialEq, Copy)]
30pub enum IntWidth {
31 I8,
32 I16,
33 I32,
34 I64,
35}
36impl IntWidth {
37 pub fn width(self) -> u8 {
38 match self {
39 IntWidth::I8 => 8,
40 IntWidth::I16 => 16,
41 IntWidth::I32 => 32,
42 IntWidth::I64 => 64,
43 }
44 }
45}
46
47#[derive(Debug, Clone, PartialEq, Copy)]
48pub enum FloatWidth {
49 F32,
50 F64,
51}
52impl FloatWidth {
53 pub fn width(self) -> u8 {
54 match self {
55 FloatWidth::F32 => 32,
56 FloatWidth::F64 => 64,
57 }
58 }
59}
60
61#[derive(Debug, Clone)]
63pub struct RecordField<'a> {
64 pub name: Name<'a>,
65 pub ty: Value<'a>,
66}
67
68#[derive(Debug, Clone)]
70pub struct VariantCase<'a> {
71 pub name: Name<'a>,
72 pub ty: Option<Value<'a>>,
73 pub refines: Option<u32>,
74}
75
76#[derive(Debug, Clone)]
78pub enum Value<'a> {
79 Bool,
80 S(IntWidth),
81 U(IntWidth),
82 F(FloatWidth),
83 Char,
84 String,
85 List(Box<Value<'a>>),
86 Record(Vec<RecordField<'a>>),
87 Tuple(Vec<Value<'a>>),
88 Flags(Vec<Name<'a>>),
89 Variant(Vec<VariantCase<'a>>),
90 Enum(Vec<Name<'a>>),
91 Option(Box<Value<'a>>),
92 Result(Box<Option<Value<'a>>>, Box<Option<Value<'a>>>),
93 Own(Handleable),
94 Borrow(Handleable),
95 Var(Option<Tyvar>, Box<Value<'a>>),
98}
99
100#[derive(Debug, Clone, Copy, PartialEq)]
102pub struct ResourceId {
103 pub(super) id: u32,
104}
105
106#[derive(Debug, Clone)]
113pub enum FreeTyvar {
114 U(u32, u32),
115 E(u32, u32),
116}
117
118#[derive(Debug, Clone)]
124pub enum Tyvar {
125 Bound(u32),
128 Free(FreeTyvar),
131}
132
133#[derive(Debug, Clone)]
134pub struct Param<'a> {
135 pub name: Name<'a>,
136 pub ty: Value<'a>,
137}
138
139#[derive(Debug, Clone)]
140pub enum Result<'a> {
141 Unnamed(Value<'a>),
142 Named(Vec<Param<'a>>),
143}
144
145#[derive(Debug, Clone)]
147pub struct Func<'a> {
148 pub params: Vec<Param<'a>>,
149 pub result: Result<'a>,
150}
151
152#[derive(Debug, Clone)]
155pub enum Handleable {
156 Var(Tyvar),
157 Resource(ResourceId),
158}
159
160#[derive(Debug, Clone)]
162pub enum Defined<'a> {
163 Handleable(Handleable),
164 Value(Value<'a>),
165 Func(Func<'a>),
166 Instance(QualifiedInstance<'a>),
167 Component(Component<'a>),
168}
169
170#[derive(Debug, Clone)]
172pub enum TypeBound<'a> {
173 Eq(Defined<'a>),
174 SubResource,
175}
176
177#[derive(Debug, Clone, PartialEq)]
184pub enum ImportExport<'a> {
185 Import(&'a str),
186 Export(&'a str),
187}
188impl<'a> ImportExport<'a> {
189 pub fn name(&self) -> &'a str {
190 match self {
191 ImportExport::Import(s) => s,
192 ImportExport::Export(s) => s,
193 }
194 }
195 pub fn imported(&self) -> bool {
196 match self {
197 ImportExport::Import(_) => true,
198 ImportExport::Export(_) => false,
199 }
200 }
201}
202
203#[derive(Default, Debug, Clone, PartialEq)]
207pub struct TyvarOrigin<'a> {
208 pub path: Option<Vec<ImportExport<'a>>>,
210}
211
212impl<'a> TyvarOrigin<'a> {
213 pub fn new() -> Self {
214 TyvarOrigin { path: Some(vec![]) }
215 }
216 pub fn push(&self, x: Option<ImportExport<'a>>) -> Self {
217 match (&self.path, x) {
218 (None, _) => TyvarOrigin { path: None },
219 (_, None) => self.clone(),
220 (Some(xs), Some(x)) => {
221 let mut xs = xs.clone();
222 xs.push(x);
223 TyvarOrigin { path: Some(xs) }
224 }
225 }
226 }
227 pub fn matches<I: Iterator<Item = &'a ImportExport<'a>>>(&self, path: I) -> bool {
228 self.path
229 .as_ref()
230 .map(|p| p.iter().rev().eq(path))
231 .unwrap_or(false)
232 }
233 pub fn is_local<
234 I: DoubleEndedIterator<Item = &'a ImportExport<'a>>
235 + ExactSizeIterator<Item = &'a ImportExport<'a>>,
236 >(
237 &self,
238 path: I,
239 ) -> Option<Vec<ImportExport<'a>>> {
240 let other = path.rev().skip(1).rev();
241 let path = self.path.as_ref()?;
242 let path = path.iter();
243 let mut path = path.rev();
244 for elem in other {
245 match path.next() {
246 None => break,
247 Some(oe) if oe != elem => return None,
248 _ => (),
249 }
250 }
251 Some(path.cloned().collect())
252 }
253 pub fn last_name(&self) -> Option<&'a str> {
254 self.path
255 .as_ref()
256 .and_then(|x| x.first())
257 .map(|ie| ie.name())
258 }
259 pub fn is_imported(&self) -> bool {
260 let Some(p) = &self.path else {
261 return false;
262 };
263 p[p.len() - 1].imported()
264 }
265}
266
267#[derive(Debug, Clone)]
273pub struct BoundedTyvar<'a> {
274 pub origin: TyvarOrigin<'a>,
279 pub bound: TypeBound<'a>,
280}
281
282impl<'a> BoundedTyvar<'a> {
283 pub fn new(bound: TypeBound<'a>) -> Self {
284 BoundedTyvar {
285 origin: TyvarOrigin::new(),
286 bound,
287 }
288 }
289 pub fn push_origin(&self, x: Option<ImportExport<'a>>) -> Self {
290 BoundedTyvar {
291 origin: self.origin.push(x),
292 ..self.clone()
293 }
294 }
295}
296
297#[derive(Debug, Clone)]
299pub enum ExternDesc<'a> {
300 CoreModule(CoreModule<'a>),
301 Func(Func<'a>),
302 Type(Defined<'a>),
304 Instance(Instance<'a>),
309 Component(Component<'a>),
310}
311
312#[derive(Debug, Clone)]
314pub enum CoreOrComponentExternDesc<'a> {
315 Core(CoreExternDesc),
316 Component(ExternDesc<'a>),
317}
318
319#[derive(Debug, Clone)]
321pub struct ExternDecl<'a> {
322 pub kebab_name: &'a str,
323 pub desc: ExternDesc<'a>,
324}
325
326#[derive(Debug, Clone)]
331pub struct Instance<'a> {
332 pub exports: Vec<ExternDecl<'a>>,
333}
334
335#[derive(Debug, Clone)]
340pub struct QualifiedInstance<'a> {
341 pub evars: Vec<BoundedTyvar<'a>>,
348 pub unqualified: Instance<'a>,
349}
350
351#[derive(Debug, Clone)]
353pub struct Component<'a> {
354 pub uvars: Vec<BoundedTyvar<'a>>,
361 pub imports: Vec<ExternDecl<'a>>,
362 pub instance: QualifiedInstance<'a>,
370}
371
372#[derive(Debug, Clone)]
376pub enum CoreExternDesc {
377 Func(wasmparser::FuncType),
378 Table(wasmparser::TableType),
379 Memory(wasmparser::MemoryType),
380 Global(wasmparser::GlobalType),
381}
382
383#[derive(Debug, Clone)]
385pub struct CoreExportDecl<'a> {
386 pub name: Name<'a>,
387 pub desc: CoreExternDesc,
388}
389
390#[derive(Debug, Clone)]
394pub struct CoreInstance<'a> {
395 pub exports: Vec<CoreExportDecl<'a>>,
396}
397
398#[derive(Debug, Clone)]
400pub struct CoreModule<'a> {
401 pub _imports: Vec<wasmparser::Import<'a>>,
402 pub _exports: Vec<CoreExportDecl<'a>>,
403}
404
405#[derive(Debug, Clone)]
407pub enum CoreDefined<'a> {
408 Func(wasmparser::FuncType),
409 Module(CoreModule<'a>),
410}
411
412#[derive(Default, Debug, Clone)]
414pub struct CoreCtx<'a> {
415 pub types: Vec<CoreDefined<'a>>,
416 pub funcs: Vec<wasmparser::FuncType>,
417 pub modules: Vec<CoreModule<'a>>,
418 pub instances: Vec<CoreInstance<'a>>,
419 pub tables: Vec<wasmparser::TableType>,
420 pub mems: Vec<wasmparser::MemoryType>,
421 pub globals: Vec<wasmparser::GlobalType>,
422}
423
424impl<'a> CoreCtx<'a> {
425 pub fn new() -> Self {
426 CoreCtx {
427 types: Vec::new(),
428 funcs: Vec::new(),
429 modules: Vec::new(),
430 instances: Vec::new(),
431 tables: Vec::new(),
432 mems: Vec::new(),
433 globals: Vec::new(),
434 }
435 }
436}
437
438#[derive(Debug, Clone)]
440pub struct Resource {
441 pub _dtor: Option<FuncIdx>,
443}
444
445#[derive(Debug, Clone)]
447pub struct Ctx<'p, 'a> {
448 pub parent: Option<&'p Ctx<'p, 'a>>,
449 pub outer_boundary: bool,
450 pub core: CoreCtx<'a>,
451 pub uvars: Vec<(BoundedTyvar<'a>, bool)>,
458 pub evars: Vec<(BoundedTyvar<'a>, Option<Defined<'a>>)>,
462 pub rtypes: Vec<Resource>,
463 pub types: Vec<Defined<'a>>,
464 pub components: Vec<Component<'a>>,
465 pub instances: Vec<Instance<'a>>,
466 pub funcs: Vec<Func<'a>>,
467}
468
469impl<'p, 'a> Ctx<'p, 'a> {
470 pub fn new<'c>(parent: Option<&'p Ctx<'c, 'a>>, outer_boundary: bool) -> Self {
471 Ctx {
472 parent,
473 outer_boundary,
474 core: CoreCtx::new(),
475 uvars: Vec::new(),
476 evars: Vec::new(),
477 rtypes: Vec::new(),
478 types: Vec::new(),
479 components: Vec::new(),
480 instances: Vec::new(),
481 funcs: Vec::new(),
482 }
483 }
484}
485
486pub struct CtxParentIterator<'i, 'p: 'i, 'a: 'i> {
487 ctx: Option<&'i Ctx<'p, 'a>>,
488}
489impl<'i, 'p, 'a> Iterator for CtxParentIterator<'i, 'p, 'a> {
490 type Item = &'i Ctx<'p, 'a>;
491 fn next(&mut self) -> Option<Self::Item> {
492 match self.ctx {
493 Some(ctx) => {
494 self.ctx = ctx.parent;
495 Some(ctx)
496 }
497 None => None,
498 }
499 }
500}
501
502impl<'p, 'a> Ctx<'p, 'a> {
503 pub fn parents<'i>(&'i self) -> CtxParentIterator<'i, 'p, 'a> {
504 CtxParentIterator { ctx: Some(self) }
505 }
506}