1use crate::structure::*;
10
11#[derive(Debug, Clone, PartialEq, Copy)]
12pub struct Name<'a> {
13 pub name: &'a str,
14}
15
16#[derive(Debug, Clone, PartialEq, Copy)]
17pub enum IntWidth {
18 I8,
19 I16,
20 I32,
21 I64,
22}
23impl IntWidth {
24 pub fn width(self) -> u8 {
25 match self {
26 IntWidth::I8 => 8,
27 IntWidth::I16 => 16,
28 IntWidth::I32 => 32,
29 IntWidth::I64 => 64,
30 }
31 }
32}
33
34#[derive(Debug, Clone, PartialEq, Copy)]
35pub enum FloatWidth {
36 F32,
37 F64,
38}
39impl FloatWidth {
40 pub fn width(self) -> u8 {
41 match self {
42 FloatWidth::F32 => 32,
43 FloatWidth::F64 => 64,
44 }
45 }
46}
47
48#[derive(Debug, Clone)]
50pub struct RecordField<'a> {
51 pub name: Name<'a>,
52 pub ty: Value<'a>,
53}
54
55#[derive(Debug, Clone)]
57pub struct VariantCase<'a> {
58 pub name: Name<'a>,
59 pub ty: Option<Value<'a>>,
60}
61
62#[derive(Debug, Clone)]
64pub enum Value<'a> {
65 Bool,
66 S(IntWidth),
67 U(IntWidth),
68 F(FloatWidth),
69 Char,
70 String,
71 List(Box<Value<'a>>),
72 FixList(Box<Value<'a>>, u32),
73 Record(Vec<RecordField<'a>>),
74 Tuple(Vec<Value<'a>>),
75 Flags(Vec<Name<'a>>),
76 Variant(Vec<VariantCase<'a>>),
77 Enum(Vec<Name<'a>>),
78 Option(Box<Value<'a>>),
79 Result(Box<Option<Value<'a>>>, Box<Option<Value<'a>>>),
80 Own(Handleable),
81 Borrow(Handleable),
82 Var(Option<Tyvar>, Box<Value<'a>>),
85}
86
87#[derive(Debug, Clone, Copy, PartialEq)]
89pub struct ResourceId {
90 pub(super) id: u32,
91}
92
93#[derive(Debug, Clone)]
100pub enum FreeTyvar {
101 U(u32, u32),
102 E(u32, u32),
103}
104
105#[derive(Debug, Clone)]
111pub enum Tyvar {
112 Bound(u32),
115 Free(FreeTyvar),
118}
119
120#[derive(Debug, Clone)]
121pub struct Param<'a> {
122 pub name: Name<'a>,
123 pub ty: Value<'a>,
124}
125
126pub type Result<'a> = Option<Value<'a>>;
127
128#[derive(Debug, Clone)]
130pub struct Func<'a> {
131 pub params: Vec<Param<'a>>,
132 pub result: Result<'a>,
133}
134
135#[derive(Debug, Clone)]
138pub enum Handleable {
139 Var(Tyvar),
140 Resource(ResourceId),
141}
142
143#[derive(Debug, Clone)]
145pub enum Defined<'a> {
146 Handleable(Handleable),
147 Value(Value<'a>),
148 Func(Func<'a>),
149 Instance(QualifiedInstance<'a>),
150 Component(Component<'a>),
151}
152
153#[derive(Debug, Clone)]
155pub enum TypeBound<'a> {
156 Eq(Defined<'a>),
157 SubResource,
158}
159
160#[derive(Debug, Clone, PartialEq)]
167pub enum ImportExport<'a> {
168 Import(&'a str),
169 Export(&'a str),
170}
171impl<'a> ImportExport<'a> {
172 pub fn name(&self) -> &'a str {
173 match self {
174 ImportExport::Import(s) => s,
175 ImportExport::Export(s) => s,
176 }
177 }
178 pub fn imported(&self) -> bool {
179 match self {
180 ImportExport::Import(_) => true,
181 ImportExport::Export(_) => false,
182 }
183 }
184}
185
186#[derive(Default, Debug, Clone, PartialEq)]
190pub struct TyvarOrigin<'a> {
191 pub path: Option<Vec<ImportExport<'a>>>,
193}
194
195impl<'a> TyvarOrigin<'a> {
196 pub fn new() -> Self {
197 TyvarOrigin { path: Some(vec![]) }
198 }
199 pub fn push(&self, x: Option<ImportExport<'a>>) -> Self {
200 match (&self.path, x) {
201 (None, _) => TyvarOrigin { path: None },
202 (_, None) => self.clone(),
203 (Some(xs), Some(x)) => {
204 let mut xs = xs.clone();
205 xs.push(x);
206 TyvarOrigin { path: Some(xs) }
207 }
208 }
209 }
210 pub fn matches<I: Iterator<Item = &'a ImportExport<'a>>>(&self, path: I) -> bool {
211 self.path
212 .as_ref()
213 .map(|p| p.iter().rev().eq(path))
214 .unwrap_or(false)
215 }
216 pub fn is_local<
217 I: DoubleEndedIterator<Item = &'a ImportExport<'a>>
218 + ExactSizeIterator<Item = &'a ImportExport<'a>>,
219 >(
220 &self,
221 path: I,
222 ) -> Option<Vec<ImportExport<'a>>> {
223 let other = path.rev().skip(1).rev();
224 let path = self.path.as_ref()?;
225 let path = path.iter();
226 let mut path = path.rev();
227 for elem in other {
228 match path.next() {
229 None => break,
230 Some(oe) if oe != elem => return None,
231 _ => (),
232 }
233 }
234 Some(path.cloned().collect())
235 }
236 pub fn last_name(&self) -> Option<&'a str> {
237 self.path
238 .as_ref()
239 .and_then(|x| x.first())
240 .map(|ie| ie.name())
241 }
242 pub fn is_imported(&self) -> bool {
243 let Some(p) = &self.path else {
244 return false;
245 };
246 p[p.len() - 1].imported()
247 }
248}
249
250#[derive(Debug, Clone)]
256pub struct BoundedTyvar<'a> {
257 pub origin: TyvarOrigin<'a>,
262 pub bound: TypeBound<'a>,
263}
264
265impl<'a> BoundedTyvar<'a> {
266 pub fn new(bound: TypeBound<'a>) -> Self {
267 BoundedTyvar {
268 origin: TyvarOrigin::new(),
269 bound,
270 }
271 }
272 pub fn push_origin(&self, x: Option<ImportExport<'a>>) -> Self {
273 BoundedTyvar {
274 origin: self.origin.push(x),
275 ..self.clone()
276 }
277 }
278}
279
280#[derive(Debug, Clone)]
282pub enum ExternDesc<'a> {
283 CoreModule(CoreModule<'a>),
284 Func(Func<'a>),
285 Type(Defined<'a>),
287 Instance(Instance<'a>),
292 Component(Component<'a>),
293}
294
295#[derive(Debug, Clone)]
297pub enum CoreOrComponentExternDesc<'a> {
298 Core(CoreExternDesc),
299 Component(ExternDesc<'a>),
300}
301
302#[derive(Debug, Clone)]
304pub struct ExternDecl<'a> {
305 pub kebab_name: &'a str,
306 pub desc: ExternDesc<'a>,
307}
308
309#[derive(Debug, Clone)]
314pub struct Instance<'a> {
315 pub exports: Vec<ExternDecl<'a>>,
316}
317
318#[derive(Debug, Clone)]
323pub struct QualifiedInstance<'a> {
324 pub evars: Vec<BoundedTyvar<'a>>,
331 pub unqualified: Instance<'a>,
332}
333
334#[derive(Debug, Clone)]
336pub struct Component<'a> {
337 pub uvars: Vec<BoundedTyvar<'a>>,
344 pub imports: Vec<ExternDecl<'a>>,
345 pub instance: QualifiedInstance<'a>,
353}
354
355#[derive(Debug, Clone)]
359pub enum CoreExternDesc {
360 Func(wasmparser::FuncType),
361 Table(wasmparser::TableType),
362 Memory(wasmparser::MemoryType),
363 Global(wasmparser::GlobalType),
364}
365
366#[derive(Debug, Clone)]
368pub struct CoreExportDecl<'a> {
369 pub name: Name<'a>,
370 pub desc: CoreExternDesc,
371}
372
373#[derive(Debug, Clone)]
377pub struct CoreInstance<'a> {
378 pub exports: Vec<CoreExportDecl<'a>>,
379}
380
381#[derive(Debug, Clone)]
383pub struct CoreModule<'a> {
384 pub _imports: Vec<wasmparser::Import<'a>>,
385 pub _exports: Vec<CoreExportDecl<'a>>,
386}
387
388#[derive(Debug, Clone)]
390pub enum CoreDefined<'a> {
391 Func(wasmparser::FuncType),
392 Module(CoreModule<'a>),
393}
394
395#[derive(Default, Debug, Clone)]
397pub struct CoreCtx<'a> {
398 pub types: Vec<CoreDefined<'a>>,
399 pub funcs: Vec<wasmparser::FuncType>,
400 pub modules: Vec<CoreModule<'a>>,
401 pub instances: Vec<CoreInstance<'a>>,
402 pub tables: Vec<wasmparser::TableType>,
403 pub mems: Vec<wasmparser::MemoryType>,
404 pub globals: Vec<wasmparser::GlobalType>,
405}
406
407impl<'a> CoreCtx<'a> {
408 pub fn new() -> Self {
409 CoreCtx {
410 types: Vec::new(),
411 funcs: Vec::new(),
412 modules: Vec::new(),
413 instances: Vec::new(),
414 tables: Vec::new(),
415 mems: Vec::new(),
416 globals: Vec::new(),
417 }
418 }
419}
420
421#[derive(Debug, Clone)]
423pub struct Resource {
424 pub _dtor: Option<FuncIdx>,
426}
427
428#[derive(Debug, Clone)]
430pub struct Ctx<'p, 'a> {
431 pub parent: Option<&'p Ctx<'p, 'a>>,
432 pub outer_boundary: bool,
433 pub core: CoreCtx<'a>,
434 pub uvars: Vec<(BoundedTyvar<'a>, bool)>,
441 pub evars: Vec<(BoundedTyvar<'a>, Option<Defined<'a>>)>,
445 pub rtypes: Vec<Resource>,
446 pub types: Vec<Defined<'a>>,
447 pub components: Vec<Component<'a>>,
448 pub instances: Vec<Instance<'a>>,
449 pub funcs: Vec<Func<'a>>,
450}
451
452impl<'p, 'a> Ctx<'p, 'a> {
453 pub fn new<'c>(parent: Option<&'p Ctx<'c, 'a>>, outer_boundary: bool) -> Self {
454 Ctx {
455 parent,
456 outer_boundary,
457 core: CoreCtx::new(),
458 uvars: Vec::new(),
459 evars: Vec::new(),
460 rtypes: Vec::new(),
461 types: Vec::new(),
462 components: Vec::new(),
463 instances: Vec::new(),
464 funcs: Vec::new(),
465 }
466 }
467}
468
469pub struct CtxParentIterator<'i, 'p: 'i, 'a: 'i> {
470 ctx: Option<&'i Ctx<'p, 'a>>,
471}
472impl<'i, 'p, 'a> Iterator for CtxParentIterator<'i, 'p, 'a> {
473 type Item = &'i Ctx<'p, 'a>;
474 fn next(&mut self) -> Option<Self::Item> {
475 match self.ctx {
476 Some(ctx) => {
477 self.ctx = ctx.parent;
478 Some(ctx)
479 }
480 None => None,
481 }
482 }
483}
484
485impl<'p, 'a> Ctx<'p, 'a> {
486 pub fn parents<'i>(&'i self) -> CtxParentIterator<'i, 'p, 'a> {
487 CtxParentIterator { ctx: Some(self) }
488 }
489}