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}
74
75#[derive(Debug, Clone)]
77pub enum Value<'a> {
78 Bool,
79 S(IntWidth),
80 U(IntWidth),
81 F(FloatWidth),
82 Char,
83 String,
84 List(Box<Value<'a>>),
85 FixList(Box<Value<'a>>, u32),
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
139pub type Result<'a> = Option<Value<'a>>;
140
141#[derive(Debug, Clone)]
143pub struct Func<'a> {
144 pub params: Vec<Param<'a>>,
145 pub result: Result<'a>,
146}
147
148#[derive(Debug, Clone)]
151pub enum Handleable {
152 Var(Tyvar),
153 Resource(ResourceId),
154}
155
156#[derive(Debug, Clone)]
158pub enum Defined<'a> {
159 Handleable(Handleable),
160 Value(Value<'a>),
161 Func(Func<'a>),
162 Instance(QualifiedInstance<'a>),
163 Component(Component<'a>),
164}
165
166#[derive(Debug, Clone)]
168pub enum TypeBound<'a> {
169 Eq(Defined<'a>),
170 SubResource,
171}
172
173#[derive(Debug, Clone, PartialEq)]
180pub enum ImportExport<'a> {
181 Import(&'a str),
182 Export(&'a str),
183}
184impl<'a> ImportExport<'a> {
185 pub fn name(&self) -> &'a str {
186 match self {
187 ImportExport::Import(s) => s,
188 ImportExport::Export(s) => s,
189 }
190 }
191 pub fn imported(&self) -> bool {
192 match self {
193 ImportExport::Import(_) => true,
194 ImportExport::Export(_) => false,
195 }
196 }
197}
198
199#[derive(Default, Debug, Clone, PartialEq)]
203pub struct TyvarOrigin<'a> {
204 pub path: Option<Vec<ImportExport<'a>>>,
206}
207
208impl<'a> TyvarOrigin<'a> {
209 pub fn new() -> Self {
210 TyvarOrigin { path: Some(vec![]) }
211 }
212 pub fn push(&self, x: Option<ImportExport<'a>>) -> Self {
213 match (&self.path, x) {
214 (None, _) => TyvarOrigin { path: None },
215 (_, None) => self.clone(),
216 (Some(xs), Some(x)) => {
217 let mut xs = xs.clone();
218 xs.push(x);
219 TyvarOrigin { path: Some(xs) }
220 }
221 }
222 }
223 pub fn matches<I: Iterator<Item = &'a ImportExport<'a>>>(&self, path: I) -> bool {
224 self.path
225 .as_ref()
226 .map(|p| p.iter().rev().eq(path))
227 .unwrap_or(false)
228 }
229 pub fn is_local<
230 I: DoubleEndedIterator<Item = &'a ImportExport<'a>>
231 + ExactSizeIterator<Item = &'a ImportExport<'a>>,
232 >(
233 &self,
234 path: I,
235 ) -> Option<Vec<ImportExport<'a>>> {
236 let other = path.rev().skip(1).rev();
237 let path = self.path.as_ref()?;
238 let path = path.iter();
239 let mut path = path.rev();
240 for elem in other {
241 match path.next() {
242 None => break,
243 Some(oe) if oe != elem => return None,
244 _ => (),
245 }
246 }
247 Some(path.cloned().collect())
248 }
249 pub fn last_name(&self) -> Option<&'a str> {
250 self.path
251 .as_ref()
252 .and_then(|x| x.first())
253 .map(|ie| ie.name())
254 }
255 pub fn is_imported(&self) -> bool {
256 let Some(p) = &self.path else {
257 return false;
258 };
259 p[p.len() - 1].imported()
260 }
261}
262
263#[derive(Debug, Clone)]
269pub struct BoundedTyvar<'a> {
270 pub origin: TyvarOrigin<'a>,
275 pub bound: TypeBound<'a>,
276}
277
278impl<'a> BoundedTyvar<'a> {
279 pub fn new(bound: TypeBound<'a>) -> Self {
280 BoundedTyvar {
281 origin: TyvarOrigin::new(),
282 bound,
283 }
284 }
285 pub fn push_origin(&self, x: Option<ImportExport<'a>>) -> Self {
286 BoundedTyvar {
287 origin: self.origin.push(x),
288 ..self.clone()
289 }
290 }
291}
292
293#[derive(Debug, Clone)]
295pub enum ExternDesc<'a> {
296 CoreModule(CoreModule<'a>),
297 Func(Func<'a>),
298 Type(Defined<'a>),
300 Instance(Instance<'a>),
305 Component(Component<'a>),
306}
307
308#[derive(Debug, Clone)]
310pub enum CoreOrComponentExternDesc<'a> {
311 Core(CoreExternDesc),
312 Component(ExternDesc<'a>),
313}
314
315#[derive(Debug, Clone)]
317pub struct ExternDecl<'a> {
318 pub kebab_name: &'a str,
319 pub desc: ExternDesc<'a>,
320}
321
322#[derive(Debug, Clone)]
327pub struct Instance<'a> {
328 pub exports: Vec<ExternDecl<'a>>,
329}
330
331#[derive(Debug, Clone)]
336pub struct QualifiedInstance<'a> {
337 pub evars: Vec<BoundedTyvar<'a>>,
344 pub unqualified: Instance<'a>,
345}
346
347#[derive(Debug, Clone)]
349pub struct Component<'a> {
350 pub uvars: Vec<BoundedTyvar<'a>>,
357 pub imports: Vec<ExternDecl<'a>>,
358 pub instance: QualifiedInstance<'a>,
366}
367
368#[derive(Debug, Clone)]
372pub enum CoreExternDesc {
373 Func(wasmparser::FuncType),
374 Table(wasmparser::TableType),
375 Memory(wasmparser::MemoryType),
376 Global(wasmparser::GlobalType),
377}
378
379#[derive(Debug, Clone)]
381pub struct CoreExportDecl<'a> {
382 pub name: Name<'a>,
383 pub desc: CoreExternDesc,
384}
385
386#[derive(Debug, Clone)]
390pub struct CoreInstance<'a> {
391 pub exports: Vec<CoreExportDecl<'a>>,
392}
393
394#[derive(Debug, Clone)]
396pub struct CoreModule<'a> {
397 pub _imports: Vec<wasmparser::Import<'a>>,
398 pub _exports: Vec<CoreExportDecl<'a>>,
399}
400
401#[derive(Debug, Clone)]
403pub enum CoreDefined<'a> {
404 Func(wasmparser::FuncType),
405 Module(CoreModule<'a>),
406}
407
408#[derive(Default, Debug, Clone)]
410pub struct CoreCtx<'a> {
411 pub types: Vec<CoreDefined<'a>>,
412 pub funcs: Vec<wasmparser::FuncType>,
413 pub modules: Vec<CoreModule<'a>>,
414 pub instances: Vec<CoreInstance<'a>>,
415 pub tables: Vec<wasmparser::TableType>,
416 pub mems: Vec<wasmparser::MemoryType>,
417 pub globals: Vec<wasmparser::GlobalType>,
418}
419
420impl<'a> CoreCtx<'a> {
421 pub fn new() -> Self {
422 CoreCtx {
423 types: Vec::new(),
424 funcs: Vec::new(),
425 modules: Vec::new(),
426 instances: Vec::new(),
427 tables: Vec::new(),
428 mems: Vec::new(),
429 globals: Vec::new(),
430 }
431 }
432}
433
434#[derive(Debug, Clone)]
436pub struct Resource {
437 pub _dtor: Option<FuncIdx>,
439}
440
441#[derive(Debug, Clone)]
443pub struct Ctx<'p, 'a> {
444 pub parent: Option<&'p Ctx<'p, 'a>>,
445 pub outer_boundary: bool,
446 pub core: CoreCtx<'a>,
447 pub uvars: Vec<(BoundedTyvar<'a>, bool)>,
454 pub evars: Vec<(BoundedTyvar<'a>, Option<Defined<'a>>)>,
458 pub rtypes: Vec<Resource>,
459 pub types: Vec<Defined<'a>>,
460 pub components: Vec<Component<'a>>,
461 pub instances: Vec<Instance<'a>>,
462 pub funcs: Vec<Func<'a>>,
463}
464
465impl<'p, 'a> Ctx<'p, 'a> {
466 pub fn new<'c>(parent: Option<&'p Ctx<'c, 'a>>, outer_boundary: bool) -> Self {
467 Ctx {
468 parent,
469 outer_boundary,
470 core: CoreCtx::new(),
471 uvars: Vec::new(),
472 evars: Vec::new(),
473 rtypes: Vec::new(),
474 types: Vec::new(),
475 components: Vec::new(),
476 instances: Vec::new(),
477 funcs: Vec::new(),
478 }
479 }
480}
481
482pub struct CtxParentIterator<'i, 'p: 'i, 'a: 'i> {
483 ctx: Option<&'i Ctx<'p, 'a>>,
484}
485impl<'i, 'p, 'a> Iterator for CtxParentIterator<'i, 'p, 'a> {
486 type Item = &'i Ctx<'p, 'a>;
487 fn next(&mut self) -> Option<Self::Item> {
488 match self.ctx {
489 Some(ctx) => {
490 self.ctx = ctx.parent;
491 Some(ctx)
492 }
493 None => None,
494 }
495 }
496}
497
498impl<'p, 'a> Ctx<'p, 'a> {
499 pub fn parents<'i>(&'i self) -> CtxParentIterator<'i, 'p, 'a> {
500 CtxParentIterator { ctx: Some(self) }
501 }
502}