Coverage Report

Created: 2026-06-21 07:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wasm-tools/crates/wasmprinter/src/component.rs
Line
Count
Source
1
use crate::{Naming, Printer, State, name_map};
2
use anyhow::{Result, bail};
3
use wasmparser::*;
4
5
impl Printer<'_, '_> {
6
0
    pub(crate) fn register_component_names(
7
0
        &mut self,
8
0
        state: &mut State,
9
0
        names: ComponentNameSectionReader<'_>,
10
0
    ) -> Result<()> {
11
0
        for section in names {
12
0
            match section? {
13
0
                ComponentName::Component { name, .. } => {
14
0
                    let name = Naming::new(name, 0, "component", None);
15
0
                    state.name = Some(name);
16
0
                }
17
0
                ComponentName::CoreFuncs(n) => {
18
0
                    name_map(&mut state.core.func_names, n, "core-func")?
19
                }
20
0
                ComponentName::CoreTypes(n) => {
21
0
                    name_map(&mut state.core.type_names, n, "core-type")?
22
                }
23
0
                ComponentName::CoreTables(n) => {
24
0
                    name_map(&mut state.core.table_names, n, "core-table")?
25
                }
26
0
                ComponentName::CoreMemories(n) => {
27
0
                    name_map(&mut state.core.memory_names, n, "core-memory")?
28
                }
29
0
                ComponentName::CoreGlobals(n) => {
30
0
                    name_map(&mut state.core.global_names, n, "core-global")?
31
                }
32
0
                ComponentName::CoreTags(n) => name_map(&mut state.core.tag_names, n, "core-tag")?,
33
0
                ComponentName::CoreModules(n) => {
34
0
                    name_map(&mut state.core.module_names, n, "core-module")?
35
                }
36
0
                ComponentName::CoreInstances(n) => {
37
0
                    name_map(&mut state.core.instance_names, n, "core-instance")?
38
                }
39
0
                ComponentName::Types(n) => name_map(&mut state.component.type_names, n, "type")?,
40
0
                ComponentName::Instances(n) => {
41
0
                    name_map(&mut state.component.instance_names, n, "instance")?
42
                }
43
0
                ComponentName::Components(n) => {
44
0
                    name_map(&mut state.component.component_names, n, "component")?
45
                }
46
0
                ComponentName::Funcs(n) => name_map(&mut state.component.func_names, n, "func")?,
47
0
                ComponentName::Values(n) => name_map(&mut state.component.value_names, n, "value")?,
48
0
                ComponentName::Unknown { .. } => (),
49
            }
50
        }
51
0
        Ok(())
52
0
    }
53
54
0
    pub(crate) fn print_core_types(
55
0
        &mut self,
56
0
        states: &mut Vec<State>,
57
0
        parser: CoreTypeSectionReader<'_>,
58
0
    ) -> Result<()> {
59
0
        for ty in parser.into_iter_with_offsets() {
60
0
            let (offset, ty) = ty?;
61
0
            self.newline(offset)?;
62
0
            self.print_core_type(states, ty)?;
63
        }
64
65
0
        Ok(())
66
0
    }
67
68
0
    pub(crate) fn print_core_type(&mut self, states: &mut Vec<State>, ty: CoreType) -> Result<()> {
69
0
        match ty {
70
0
            CoreType::Rec(rec) => {
71
0
                self.print_rec(states.last_mut().unwrap(), None, rec, true)?;
72
            }
73
0
            CoreType::Module(decls) => {
74
0
                self.start_group("core type ")?;
75
0
                self.print_name(
76
0
                    &states.last().unwrap().core.type_names,
77
0
                    states.last().unwrap().core.types.len() as u32,
78
0
                )?;
79
0
                self.print_module_type(states, decls.into_vec())?;
80
0
                self.end_group()?; // `core type` itself
81
0
                states.last_mut().unwrap().core.types.push(None);
82
            }
83
        }
84
0
        Ok(())
85
0
    }
86
87
0
    pub(crate) fn print_component_type_ref(&mut self, state: &State, idx: u32) -> Result<()> {
88
0
        self.start_group("type ")?;
89
0
        self.print_idx(&state.component.type_names, idx)?;
90
0
        self.end_group()?;
91
0
        Ok(())
92
0
    }
93
94
0
    pub(crate) fn print_primitive_val_type(&mut self, ty: &PrimitiveValType) -> Result<()> {
95
0
        match ty {
96
0
            PrimitiveValType::Bool => self.print_type_keyword("bool")?,
97
0
            PrimitiveValType::S8 => self.print_type_keyword("s8")?,
98
0
            PrimitiveValType::U8 => self.print_type_keyword("u8")?,
99
0
            PrimitiveValType::S16 => self.print_type_keyword("s16")?,
100
0
            PrimitiveValType::U16 => self.print_type_keyword("u16")?,
101
0
            PrimitiveValType::S32 => self.print_type_keyword("s32")?,
102
0
            PrimitiveValType::U32 => self.print_type_keyword("u32")?,
103
0
            PrimitiveValType::S64 => self.print_type_keyword("s64")?,
104
0
            PrimitiveValType::U64 => self.print_type_keyword("u64")?,
105
0
            PrimitiveValType::F32 => self.print_type_keyword("f32")?,
106
0
            PrimitiveValType::F64 => self.print_type_keyword("f64")?,
107
0
            PrimitiveValType::Char => self.print_type_keyword("char")?,
108
0
            PrimitiveValType::String => self.print_type_keyword("string")?,
109
0
            PrimitiveValType::ErrorContext => self.print_type_keyword("error-context")?,
110
        }
111
0
        Ok(())
112
0
    }
113
114
0
    pub(crate) fn print_record_type(
115
0
        &mut self,
116
0
        state: &State,
117
0
        fields: &[(&str, ComponentValType)],
118
0
    ) -> Result<()> {
119
0
        self.start_group("record")?;
120
0
        for (name, ty) in fields.iter() {
121
0
            self.result.write_str(" ")?;
122
0
            self.start_group("field ")?;
123
0
            self.print_str(name)?;
124
0
            self.result.write_str(" ")?;
125
0
            self.print_component_val_type(state, ty)?;
126
0
            self.end_group()?;
127
        }
128
0
        self.end_group()?;
129
0
        Ok(())
130
0
    }
131
132
0
    pub(crate) fn print_variant_type(
133
0
        &mut self,
134
0
        state: &State,
135
0
        cases: &[VariantCase],
136
0
    ) -> Result<()> {
137
0
        self.start_group("variant")?;
138
0
        for case in cases {
139
0
            self.result.write_str(" ")?;
140
0
            self.start_group("case ")?;
141
0
            self.print_str(case.name)?;
142
143
0
            if let Some(ty) = case.ty {
144
0
                self.result.write_str(" ")?;
145
0
                self.print_component_val_type(state, &ty)?;
146
0
            }
147
148
0
            self.end_group()?;
149
        }
150
0
        self.end_group()?;
151
152
0
        Ok(())
153
0
    }
154
155
0
    pub(crate) fn print_list_type(
156
0
        &mut self,
157
0
        state: &State,
158
0
        element_ty: &ComponentValType,
159
0
    ) -> Result<()> {
160
0
        self.start_group("list ")?;
161
0
        self.print_component_val_type(state, element_ty)?;
162
0
        self.end_group()?;
163
0
        Ok(())
164
0
    }
165
166
0
    pub(crate) fn print_map_type(
167
0
        &mut self,
168
0
        state: &State,
169
0
        key_ty: &ComponentValType,
170
0
        value_ty: &ComponentValType,
171
0
    ) -> Result<()> {
172
0
        self.start_group("map ")?;
173
0
        self.print_component_val_type(state, key_ty)?;
174
0
        self.result.write_str(" ")?;
175
0
        self.print_component_val_type(state, value_ty)?;
176
0
        self.end_group()?;
177
0
        Ok(())
178
0
    }
179
180
0
    pub(crate) fn print_fixed_length_list_type(
181
0
        &mut self,
182
0
        state: &State,
183
0
        element_ty: &ComponentValType,
184
0
        elements: u32,
185
0
    ) -> Result<()> {
186
0
        self.start_group("list ")?;
187
0
        self.print_component_val_type(state, element_ty)?;
188
0
        self.result.write_str(&format!(" {elements}"))?;
189
0
        self.end_group()?;
190
0
        Ok(())
191
0
    }
192
193
0
    pub(crate) fn print_tuple_type(
194
0
        &mut self,
195
0
        state: &State,
196
0
        tys: &[ComponentValType],
197
0
    ) -> Result<()> {
198
0
        self.start_group("tuple")?;
199
0
        for ty in tys {
200
0
            self.result.write_str(" ")?;
201
0
            self.print_component_val_type(state, ty)?;
202
        }
203
0
        self.end_group()?;
204
0
        Ok(())
205
0
    }
206
207
0
    pub(crate) fn print_flag_or_enum_type(&mut self, ty: &str, names: &[&str]) -> Result<()> {
208
0
        self.start_group(ty)?;
209
0
        for name in names {
210
0
            self.result.write_str(" ")?;
211
0
            self.print_str(name)?;
212
        }
213
0
        self.end_group()?;
214
0
        Ok(())
215
0
    }
216
217
0
    pub(crate) fn print_option_type(
218
0
        &mut self,
219
0
        state: &State,
220
0
        inner: &ComponentValType,
221
0
    ) -> Result<()> {
222
0
        self.start_group("option ")?;
223
0
        self.print_component_val_type(state, inner)?;
224
0
        self.end_group()?;
225
0
        Ok(())
226
0
    }
227
228
0
    pub(crate) fn print_result_type(
229
0
        &mut self,
230
0
        state: &State,
231
0
        ok: Option<ComponentValType>,
232
0
        err: Option<ComponentValType>,
233
0
    ) -> Result<()> {
234
0
        self.start_group("result")?;
235
236
0
        if let Some(ok) = ok {
237
0
            self.result.write_str(" ")?;
238
0
            self.print_component_val_type(state, &ok)?;
239
0
        }
240
241
0
        if let Some(err) = err {
242
0
            self.result.write_str(" ")?;
243
0
            self.start_group("error ")?;
244
0
            self.print_component_val_type(state, &err)?;
245
0
            self.end_group()?;
246
0
        }
247
248
0
        self.end_group()?;
249
250
0
        Ok(())
251
0
    }
252
253
0
    fn print_future_type(&mut self, state: &State, ty: Option<ComponentValType>) -> Result<()> {
254
0
        self.start_group("future")?;
255
256
0
        if let Some(ty) = ty {
257
0
            self.result.write_str(" ")?;
258
0
            self.print_component_val_type(state, &ty)?;
259
0
        }
260
261
0
        self.end_group()?;
262
263
0
        Ok(())
264
0
    }
265
266
0
    fn print_stream_type(&mut self, state: &State, ty: Option<ComponentValType>) -> Result<()> {
267
0
        self.start_group("stream")?;
268
269
0
        if let Some(ty) = ty {
270
0
            self.result.write_str(" ")?;
271
0
            self.print_component_val_type(state, &ty)?;
272
0
        }
273
274
0
        self.end_group()?;
275
276
0
        Ok(())
277
0
    }
278
279
0
    pub(crate) fn print_defined_type(
280
0
        &mut self,
281
0
        state: &State,
282
0
        ty: &ComponentDefinedType,
283
0
    ) -> Result<()> {
284
0
        match ty {
285
0
            ComponentDefinedType::Primitive(ty) => self.print_primitive_val_type(ty)?,
286
0
            ComponentDefinedType::Record(fields) => self.print_record_type(state, fields)?,
287
0
            ComponentDefinedType::Variant(cases) => self.print_variant_type(state, cases)?,
288
0
            ComponentDefinedType::List(ty) => self.print_list_type(state, ty)?,
289
0
            ComponentDefinedType::Map(key, value) => self.print_map_type(state, key, value)?,
290
0
            ComponentDefinedType::FixedLengthList(ty, elements) => {
291
0
                self.print_fixed_length_list_type(state, ty, *elements)?
292
            }
293
0
            ComponentDefinedType::Tuple(tys) => self.print_tuple_type(state, tys)?,
294
0
            ComponentDefinedType::Flags(names) => self.print_flag_or_enum_type("flags", names)?,
295
0
            ComponentDefinedType::Enum(cases) => self.print_flag_or_enum_type("enum", cases)?,
296
0
            ComponentDefinedType::Option(ty) => self.print_option_type(state, ty)?,
297
0
            ComponentDefinedType::Result { ok, err } => self.print_result_type(state, *ok, *err)?,
298
0
            ComponentDefinedType::Own(idx) => {
299
0
                self.start_group("own ")?;
300
0
                self.print_idx(&state.component.type_names, *idx)?;
301
0
                self.end_group()?;
302
            }
303
0
            ComponentDefinedType::Borrow(idx) => {
304
0
                self.start_group("borrow ")?;
305
0
                self.print_idx(&state.component.type_names, *idx)?;
306
0
                self.end_group()?;
307
            }
308
0
            ComponentDefinedType::Future(ty) => self.print_future_type(state, *ty)?,
309
0
            ComponentDefinedType::Stream(ty) => self.print_stream_type(state, *ty)?,
310
        }
311
312
0
        Ok(())
313
0
    }
314
315
0
    pub(crate) fn print_component_val_type(
316
0
        &mut self,
317
0
        state: &State,
318
0
        ty: &ComponentValType,
319
0
    ) -> Result<()> {
320
0
        match ty {
321
0
            ComponentValType::Primitive(ty) => self.print_primitive_val_type(ty),
322
0
            ComponentValType::Type(idx) => self.print_idx(&state.component.type_names, *idx),
323
        }
324
0
    }
325
326
0
    pub(crate) fn print_module_type(
327
0
        &mut self,
328
0
        states: &mut Vec<State>,
329
0
        decls: Vec<ModuleTypeDeclaration>,
330
0
    ) -> Result<()> {
331
0
        states.push(State::new(Encoding::Module));
332
0
        self.newline_unknown_pos()?;
333
0
        self.start_group("module")?;
334
0
        for decl in decls {
335
0
            self.newline_unknown_pos()?;
336
0
            match decl {
337
0
                ModuleTypeDeclaration::Type(rec) => {
338
0
                    self.print_rec(states.last_mut().unwrap(), None, rec, false)?
339
                }
340
0
                ModuleTypeDeclaration::OuterAlias { kind, count, index } => {
341
0
                    self.print_outer_alias(states, kind, count, index)?;
342
                }
343
0
                ModuleTypeDeclaration::Export { name, ty } => {
344
0
                    self.start_group("export ")?;
345
0
                    self.print_str(name)?;
346
0
                    self.result.write_str(" ")?;
347
0
                    self.print_import_ty(states.last_mut().unwrap(), &ty, false)?;
348
0
                    self.end_group()?;
349
                }
350
0
                ModuleTypeDeclaration::Import(import) => {
351
0
                    self.print_import(states.last_mut().unwrap(), &import, false)?;
352
                }
353
            }
354
        }
355
0
        self.end_group()?;
356
0
        states.pop();
357
0
        Ok(())
358
0
    }
359
360
0
    pub(crate) fn print_component_type<'a>(
361
0
        &mut self,
362
0
        states: &mut Vec<State>,
363
0
        decls: Vec<ComponentTypeDeclaration<'a>>,
364
0
    ) -> Result<()> {
365
0
        states.push(State::new(Encoding::Component));
366
0
        self.newline_unknown_pos()?;
367
0
        self.start_group("component")?;
368
0
        for decl in decls {
369
0
            self.newline_unknown_pos()?;
370
0
            match decl {
371
0
                ComponentTypeDeclaration::CoreType(ty) => self.print_core_type(states, ty)?,
372
0
                ComponentTypeDeclaration::Type(ty) => self.print_component_type_def(states, ty)?,
373
0
                ComponentTypeDeclaration::Alias(alias) => {
374
0
                    self.print_component_alias(states, alias)?;
375
                }
376
0
                ComponentTypeDeclaration::Export { name, ty } => {
377
0
                    self.start_group("export ")?;
378
0
                    self.print_component_kind_name(states.last_mut().unwrap(), ty.kind())?;
379
0
                    self.result.write_str(" ")?;
380
0
                    self.print_component_extern_name(&name)?;
381
0
                    self.result.write_str(" ")?;
382
0
                    self.print_component_import_ty(states.last_mut().unwrap(), &ty, false)?;
383
0
                    self.end_group()?;
384
                }
385
0
                ComponentTypeDeclaration::Import(import) => {
386
0
                    self.print_component_import(states.last_mut().unwrap(), &import, true)?
387
                }
388
            }
389
        }
390
0
        self.end_group()?;
391
0
        states.pop().unwrap();
392
0
        Ok(())
393
0
    }
394
395
0
    fn print_component_extern_name(&mut self, name: &ComponentExternName<'_>) -> Result<()> {
396
0
        self.print_str(name.name)?;
397
0
        if let Some(implements) = name.implements {
398
0
            self.result.write_str(" ")?;
399
0
            self.start_group("implements ")?;
400
0
            self.print_str(implements)?;
401
0
            self.end_group()?;
402
0
        }
403
0
        Ok(())
404
0
    }
405
406
0
    pub(crate) fn print_instance_type<'a>(
407
0
        &mut self,
408
0
        states: &mut Vec<State>,
409
0
        decls: Vec<InstanceTypeDeclaration<'a>>,
410
0
    ) -> Result<()> {
411
0
        states.push(State::new(Encoding::Component));
412
0
        self.newline_unknown_pos()?;
413
0
        self.start_group("instance")?;
414
0
        for decl in decls {
415
0
            self.newline_unknown_pos()?;
416
0
            match decl {
417
0
                InstanceTypeDeclaration::CoreType(ty) => self.print_core_type(states, ty)?,
418
0
                InstanceTypeDeclaration::Type(ty) => self.print_component_type_def(states, ty)?,
419
0
                InstanceTypeDeclaration::Alias(alias) => {
420
0
                    self.print_component_alias(states, alias)?;
421
                }
422
0
                InstanceTypeDeclaration::Export { name, ty } => {
423
0
                    self.start_group("export ")?;
424
0
                    self.print_component_kind_name(states.last_mut().unwrap(), ty.kind())?;
425
0
                    self.result.write_str(" ")?;
426
0
                    self.print_component_extern_name(&name)?;
427
0
                    self.result.write_str(" ")?;
428
0
                    self.print_component_import_ty(states.last_mut().unwrap(), &ty, false)?;
429
0
                    self.end_group()?;
430
                }
431
            }
432
        }
433
0
        self.end_group()?;
434
0
        states.pop().unwrap();
435
0
        Ok(())
436
0
    }
437
438
0
    pub(crate) fn outer_state(states: &[State], count: u32) -> Result<&State> {
439
0
        if count as usize >= states.len() {
440
0
            bail!("invalid outer alias count {count}");
441
0
        }
442
443
0
        let count: usize = std::cmp::min(count as usize, states.len() - 1);
444
0
        Ok(&states[states.len() - count - 1])
445
0
    }
446
447
0
    pub(crate) fn print_outer_alias(
448
0
        &mut self,
449
0
        states: &mut [State],
450
0
        kind: OuterAliasKind,
451
0
        count: u32,
452
0
        index: u32,
453
0
    ) -> Result<()> {
454
0
        let state = states.last().unwrap();
455
0
        let default_state = State::new(Encoding::Component);
456
0
        let outer = match Self::outer_state(states, count) {
457
0
            Ok(o) => o,
458
0
            Err(e) => {
459
0
                write!(self.result, "(; {e} ;) ")?;
460
0
                &default_state
461
            }
462
        };
463
0
        self.start_group("alias outer ")?;
464
0
        if let Some(name) = outer.name.as_ref() {
465
0
            name.write(self)?;
466
        } else {
467
0
            write!(self.result, "{count}")?;
468
        }
469
0
        self.result.write_str(" ")?;
470
0
        match kind {
471
            OuterAliasKind::Type => {
472
0
                self.print_idx(&outer.core.type_names, index)?;
473
0
                self.result.write_str(" ")?;
474
0
                self.start_group("type ")?;
475
0
                self.print_name(&state.core.type_names, state.core.types.len() as u32)?;
476
            }
477
        }
478
0
        self.end_group()?; // kind
479
0
        self.end_group()?; // alias
480
481
0
        let state = states.last_mut().unwrap();
482
0
        match kind {
483
0
            OuterAliasKind::Type => state.core.types.push(None),
484
        }
485
486
0
        Ok(())
487
0
    }
488
489
0
    pub(crate) fn print_component_func_type(
490
0
        &mut self,
491
0
        state: &State,
492
0
        ty: &ComponentFuncType,
493
0
    ) -> Result<()> {
494
0
        self.start_group("func")?;
495
0
        if ty.async_ {
496
0
            self.print_type_keyword(" async")?;
497
0
        }
498
0
        for (name, ty) in ty.params.iter() {
499
0
            self.result.write_str(" ")?;
500
0
            self.start_group("param ")?;
501
0
            self.print_str(name)?;
502
0
            self.result.write_str(" ")?;
503
0
            self.print_component_val_type(state, ty)?;
504
0
            self.end_group()?;
505
        }
506
507
0
        if let Some(ty) = &ty.result {
508
0
            self.result.write_str(" ")?;
509
0
            self.start_group("result ")?;
510
0
            self.print_component_val_type(state, ty)?;
511
0
            self.end_group()?;
512
0
        }
513
514
0
        self.end_group()?;
515
516
0
        Ok(())
517
0
    }
518
519
0
    pub(crate) fn print_component_type_def<'a>(
520
0
        &mut self,
521
0
        states: &mut Vec<State>,
522
0
        ty: ComponentType<'a>,
523
0
    ) -> Result<()> {
524
0
        self.start_group("type ")?;
525
        {
526
0
            let state = states.last_mut().unwrap();
527
0
            self.print_name(&state.component.type_names, state.component.types)?;
528
        }
529
0
        match ty {
530
0
            ComponentType::Defined(ty) => {
531
0
                self.result.write_str(" ")?;
532
0
                self.print_defined_type(states.last_mut().unwrap(), &ty)?;
533
            }
534
0
            ComponentType::Func(ty) => {
535
0
                self.result.write_str(" ")?;
536
0
                self.print_component_func_type(states.last_mut().unwrap(), &ty)?;
537
            }
538
0
            ComponentType::Component(decls) => {
539
0
                self.print_component_type(states, decls.into_vec())?;
540
            }
541
0
            ComponentType::Instance(decls) => {
542
0
                self.print_instance_type(states, decls.into_vec())?;
543
            }
544
0
            ComponentType::Resource { rep, dtor } => {
545
0
                self.result.write_str(" ")?;
546
0
                self.start_group("resource ")?;
547
0
                self.start_group("rep ")?;
548
0
                self.print_valtype(states.last().unwrap(), rep)?;
549
0
                self.end_group()?;
550
0
                if let Some(dtor) = dtor {
551
0
                    self.result.write_str(" ")?;
552
0
                    self.start_group("dtor ")?;
553
0
                    self.start_group("func ")?;
554
0
                    self.print_idx(&states.last().unwrap().core.func_names, dtor)?;
555
0
                    self.end_group()?;
556
0
                    self.end_group()?;
557
0
                }
558
0
                self.end_group()?;
559
            }
560
        }
561
0
        self.end_group()?;
562
563
0
        states.last_mut().unwrap().component.types += 1;
564
565
0
        Ok(())
566
0
    }
567
568
0
    pub(crate) fn print_component_types<'a>(
569
0
        &mut self,
570
0
        states: &mut Vec<State>,
571
0
        parser: ComponentTypeSectionReader<'a>,
572
0
    ) -> Result<()> {
573
0
        for ty in parser.into_iter_with_offsets() {
574
0
            let (offset, ty) = ty?;
575
0
            self.newline(offset)?;
576
0
            self.print_component_type_def(states, ty)?;
577
        }
578
579
0
        Ok(())
580
0
    }
581
582
0
    pub(crate) fn print_component_imports(
583
0
        &mut self,
584
0
        state: &mut State,
585
0
        parser: ComponentImportSectionReader,
586
0
    ) -> Result<()> {
587
0
        for import in parser.into_iter_with_offsets() {
588
0
            let (offset, import) = import?;
589
0
            self.newline(offset)?;
590
0
            self.print_component_import(state, &import, true)?;
591
        }
592
593
0
        Ok(())
594
0
    }
595
596
0
    pub(crate) fn print_component_import(
597
0
        &mut self,
598
0
        state: &mut State,
599
0
        import: &ComponentImport,
600
0
        index: bool,
601
0
    ) -> Result<()> {
602
0
        self.start_group("import ")?;
603
0
        self.print_component_extern_name(&import.name)?;
604
0
        self.result.write_str(" ")?;
605
0
        self.print_component_import_ty(state, &import.ty, index)?;
606
0
        self.end_group()?;
607
0
        Ok(())
608
0
    }
609
610
0
    pub(crate) fn print_component_import_ty(
611
0
        &mut self,
612
0
        state: &mut State,
613
0
        ty: &ComponentTypeRef,
614
0
        index: bool,
615
0
    ) -> Result<()> {
616
0
        match ty {
617
0
            ComponentTypeRef::Module(idx) => {
618
0
                self.start_group("core module ")?;
619
0
                if index {
620
0
                    self.print_name(&state.core.module_names, state.core.modules)?;
621
0
                    self.result.write_str(" ")?;
622
0
                    state.core.modules += 1;
623
0
                }
624
0
                self.print_core_type_ref(state, *idx)?;
625
0
                self.end_group()?;
626
            }
627
0
            ComponentTypeRef::Func(idx) => {
628
0
                self.start_group("func ")?;
629
0
                if index {
630
0
                    self.print_name(&state.component.func_names, state.component.funcs)?;
631
0
                    self.result.write_str(" ")?;
632
0
                    state.component.funcs += 1;
633
0
                }
634
0
                self.print_component_type_ref(state, *idx)?;
635
0
                self.end_group()?;
636
            }
637
0
            ComponentTypeRef::Value(ty) => {
638
0
                self.start_group("value ")?;
639
0
                if index {
640
0
                    self.print_name(&state.component.value_names, state.component.values)?;
641
0
                    self.result.write_str(" ")?;
642
0
                    state.component.values += 1;
643
0
                }
644
0
                match ty {
645
0
                    ComponentValType::Primitive(ty) => self.print_primitive_val_type(ty)?,
646
0
                    ComponentValType::Type(idx) => self.print_component_type_ref(state, *idx)?,
647
                }
648
0
                self.end_group()?;
649
            }
650
0
            ComponentTypeRef::Type(bounds) => {
651
0
                self.start_group("type ")?;
652
0
                if index {
653
0
                    self.print_name(&state.component.type_names, state.component.types)?;
654
0
                    self.result.write_str(" ")?;
655
0
                    state.component.types += 1;
656
0
                }
657
0
                match bounds {
658
0
                    TypeBounds::Eq(idx) => {
659
0
                        self.start_group("eq ")?;
660
0
                        self.print_idx(&state.component.type_names, *idx)?;
661
0
                        self.end_group()?;
662
                    }
663
                    TypeBounds::SubResource => {
664
0
                        self.start_group("sub ")?;
665
0
                        self.print_type_keyword("resource")?;
666
0
                        self.end_group()?;
667
                    }
668
                };
669
0
                self.end_group()?;
670
            }
671
0
            ComponentTypeRef::Instance(idx) => {
672
0
                self.start_group("instance ")?;
673
0
                if index {
674
0
                    self.print_name(&state.component.instance_names, state.component.instances)?;
675
0
                    self.result.write_str(" ")?;
676
0
                    state.component.instances += 1;
677
0
                }
678
0
                self.print_component_type_ref(state, *idx)?;
679
0
                self.end_group()?;
680
            }
681
0
            ComponentTypeRef::Component(idx) => {
682
0
                self.start_group("component ")?;
683
0
                if index {
684
0
                    self.print_name(&state.component.component_names, state.component.components)?;
685
0
                    self.result.write_str(" ")?;
686
0
                    state.component.components += 1;
687
0
                }
688
0
                self.print_component_type_ref(state, *idx)?;
689
0
                self.end_group()?;
690
            }
691
        }
692
0
        Ok(())
693
0
    }
694
695
0
    pub(crate) fn print_component_exports(
696
0
        &mut self,
697
0
        state: &mut State,
698
0
        parser: ComponentExportSectionReader,
699
0
    ) -> Result<()> {
700
0
        for export in parser.into_iter_with_offsets() {
701
0
            let (offset, export) = export?;
702
0
            self.newline(offset)?;
703
0
            self.print_component_export(state, &export, true)?;
704
        }
705
0
        Ok(())
706
0
    }
707
708
0
    pub(crate) fn print_component_export(
709
0
        &mut self,
710
0
        state: &mut State,
711
0
        export: &ComponentExport,
712
0
        named: bool,
713
0
    ) -> Result<()> {
714
0
        self.start_group("export ")?;
715
0
        if named {
716
0
            self.print_component_kind_name(state, export.kind)?;
717
0
            self.result.write_str(" ")?;
718
0
        }
719
0
        self.print_component_extern_name(&export.name)?;
720
0
        self.result.write_str(" ")?;
721
0
        self.print_component_external_kind(state, export.kind, export.index)?;
722
0
        if let Some(ty) = &export.ty {
723
0
            self.result.write_str(" ")?;
724
0
            self.print_component_import_ty(state, &ty, false)?;
725
0
        }
726
0
        self.end_group()?;
727
0
        Ok(())
728
0
    }
729
730
0
    pub(crate) fn print_component_kind_name(
731
0
        &mut self,
732
0
        state: &mut State,
733
0
        kind: ComponentExternalKind,
734
0
    ) -> Result<()> {
735
0
        match kind {
736
            ComponentExternalKind::Func => {
737
0
                self.print_name(&state.component.func_names, state.component.funcs)?;
738
0
                state.component.funcs += 1;
739
            }
740
            ComponentExternalKind::Module => {
741
0
                self.print_name(&state.core.module_names, state.core.modules)?;
742
0
                state.core.modules += 1;
743
            }
744
            ComponentExternalKind::Value => {
745
0
                self.print_name(&state.component.value_names, state.component.values)?;
746
0
                state.component.values += 1;
747
            }
748
            ComponentExternalKind::Type => {
749
0
                self.print_name(&state.component.type_names, state.component.types)?;
750
0
                state.component.types += 1;
751
            }
752
            ComponentExternalKind::Instance => {
753
0
                self.print_name(&state.component.instance_names, state.component.instances)?;
754
0
                state.component.instances += 1;
755
            }
756
            ComponentExternalKind::Component => {
757
0
                self.print_name(&state.component.component_names, state.component.components)?;
758
0
                state.component.components += 1;
759
            }
760
        }
761
0
        Ok(())
762
0
    }
763
764
0
    pub(crate) fn start_component_external_kind_group(
765
0
        &mut self,
766
0
        kind: ComponentExternalKind,
767
0
    ) -> Result<()> {
768
0
        match kind {
769
            ComponentExternalKind::Module => {
770
0
                self.start_group("core module ")?;
771
            }
772
            ComponentExternalKind::Component => {
773
0
                self.start_group("component ")?;
774
            }
775
            ComponentExternalKind::Instance => {
776
0
                self.start_group("instance ")?;
777
            }
778
            ComponentExternalKind::Func => {
779
0
                self.start_group("func ")?;
780
            }
781
            ComponentExternalKind::Value => {
782
0
                self.start_group("value ")?;
783
            }
784
            ComponentExternalKind::Type => {
785
0
                self.start_group("type ")?;
786
            }
787
        }
788
0
        Ok(())
789
0
    }
790
791
0
    pub(crate) fn print_component_external_kind(
792
0
        &mut self,
793
0
        state: &State,
794
0
        kind: ComponentExternalKind,
795
0
        index: u32,
796
0
    ) -> Result<()> {
797
0
        self.start_component_external_kind_group(kind)?;
798
0
        match kind {
799
            ComponentExternalKind::Module => {
800
0
                self.print_idx(&state.core.module_names, index)?;
801
            }
802
            ComponentExternalKind::Component => {
803
0
                self.print_idx(&state.component.component_names, index)?;
804
            }
805
            ComponentExternalKind::Instance => {
806
0
                self.print_idx(&state.component.instance_names, index)?;
807
            }
808
            ComponentExternalKind::Func => {
809
0
                self.print_idx(&state.component.func_names, index)?;
810
            }
811
            ComponentExternalKind::Value => {
812
0
                self.print_idx(&state.component.value_names, index)?;
813
            }
814
            ComponentExternalKind::Type => {
815
0
                self.print_idx(&state.component.type_names, index)?;
816
            }
817
        }
818
0
        self.end_group()?;
819
0
        Ok(())
820
0
    }
821
822
0
    pub(crate) fn print_canonical_options(
823
0
        &mut self,
824
0
        state: &State,
825
0
        options: &[CanonicalOption],
826
0
    ) -> Result<()> {
827
0
        for option in options {
828
0
            self.result.write_str(" ")?;
829
0
            match option {
830
0
                CanonicalOption::UTF8 => self.result.write_str("string-encoding=utf8")?,
831
0
                CanonicalOption::UTF16 => self.result.write_str("string-encoding=utf16")?,
832
                CanonicalOption::CompactUTF16 => {
833
0
                    self.result.write_str("string-encoding=latin1+utf16")?
834
                }
835
0
                CanonicalOption::Memory(idx) => {
836
0
                    self.start_group("memory ")?;
837
0
                    self.print_idx(&state.core.memory_names, *idx)?;
838
0
                    self.end_group()?;
839
                }
840
0
                CanonicalOption::Realloc(idx) => {
841
0
                    self.start_group("realloc ")?;
842
0
                    self.print_idx(&state.core.func_names, *idx)?;
843
0
                    self.end_group()?;
844
                }
845
0
                CanonicalOption::PostReturn(idx) => {
846
0
                    self.start_group("post-return ")?;
847
0
                    self.print_idx(&state.core.func_names, *idx)?;
848
0
                    self.end_group()?;
849
                }
850
0
                CanonicalOption::Async => self.print_type_keyword("async")?,
851
0
                CanonicalOption::Callback(idx) => {
852
0
                    self.start_group("callback ")?;
853
0
                    self.print_idx(&state.core.func_names, *idx)?;
854
0
                    self.end_group()?;
855
                }
856
0
                CanonicalOption::CoreType(idx) => {
857
0
                    self.start_group("core-type ")?;
858
0
                    self.print_idx(&state.core.type_names, *idx)?;
859
0
                    self.end_group()?;
860
                }
861
0
                CanonicalOption::Gc => self.result.write_str("gc")?,
862
            }
863
        }
864
0
        Ok(())
865
0
    }
866
867
0
    fn print_intrinsic(
868
0
        &mut self,
869
0
        state: &mut State,
870
0
        group: &str,
871
0
        body: &dyn Fn(&mut Self, &mut State) -> Result<()>,
872
0
    ) -> Result<()> {
873
0
        self.start_group("core func ")?;
874
0
        self.print_name(&state.core.func_names, state.core.funcs)?;
875
0
        self.result.write_str(" ")?;
876
0
        self.start_group(group)?;
877
0
        body(self, state)?;
878
0
        self.end_group()?;
879
0
        self.end_group()?;
880
0
        debug_assert_eq!(state.core.func_to_type.len(), state.core.funcs as usize);
881
0
        state.core.funcs += 1;
882
0
        state.core.func_to_type.push(None);
883
0
        Ok(())
884
0
    }
885
886
0
    pub(crate) fn print_canonical_functions(
887
0
        &mut self,
888
0
        state: &mut State,
889
0
        parser: ComponentCanonicalSectionReader,
890
0
    ) -> Result<()> {
891
0
        for func in parser.into_iter_with_offsets() {
892
0
            let (offset, func) = func?;
893
0
            self.newline(offset)?;
894
0
            match func {
895
                CanonicalFunction::Lift {
896
0
                    core_func_index,
897
0
                    type_index,
898
0
                    options,
899
                } => {
900
0
                    self.start_group("func ")?;
901
0
                    self.print_name(&state.component.func_names, state.component.funcs)?;
902
0
                    self.result.write_str(" ")?;
903
0
                    self.start_group("type ")?;
904
0
                    self.print_idx(&state.component.type_names, type_index)?;
905
0
                    self.end_group()?;
906
0
                    self.result.write_str(" ")?;
907
0
                    self.start_group("canon lift ")?;
908
0
                    self.start_group("core func ")?;
909
0
                    self.print_idx(&state.core.func_names, core_func_index)?;
910
0
                    self.end_group()?;
911
0
                    self.print_canonical_options(state, &options)?;
912
0
                    self.end_group()?;
913
0
                    self.end_group()?;
914
0
                    state.component.funcs += 1;
915
                }
916
                CanonicalFunction::Lower {
917
0
                    func_index,
918
0
                    options,
919
                } => {
920
0
                    self.print_intrinsic(state, "canon lower ", &|me, state| {
921
0
                        me.start_group("func ")?;
922
0
                        me.print_idx(&state.component.func_names, func_index)?;
923
0
                        me.end_group()?;
924
0
                        me.print_canonical_options(state, &options)
925
0
                    })?;
926
                }
927
0
                CanonicalFunction::ResourceNew { resource } => {
928
0
                    self.print_intrinsic(state, "canon resource.new ", &|me, state| {
929
0
                        me.print_idx(&state.component.type_names, resource)
930
0
                    })?;
931
                }
932
0
                CanonicalFunction::ResourceDrop { resource } => {
933
0
                    self.print_intrinsic(state, "canon resource.drop ", &|me, state| {
934
0
                        me.print_idx(&state.component.type_names, resource)
935
0
                    })?;
936
                }
937
0
                CanonicalFunction::ResourceDropAsync { resource } => {
938
0
                    self.print_intrinsic(state, "canon resource.drop ", &|me, state| {
939
0
                        me.print_idx(&state.component.type_names, resource)?;
940
0
                        me.print_type_keyword(" async")
941
0
                    })?;
942
                }
943
0
                CanonicalFunction::ResourceRep { resource } => {
944
0
                    self.print_intrinsic(state, "canon resource.rep ", &|me, state| {
945
0
                        me.print_idx(&state.component.type_names, resource)
946
0
                    })?;
947
                }
948
0
                CanonicalFunction::ThreadSpawnRef { func_ty_index } => {
949
0
                    self.print_intrinsic(state, "canon thread.spawn-ref ", &|me, state| {
950
0
                        me.print_idx(&state.core.type_names, func_ty_index)
951
0
                    })?;
952
                }
953
                CanonicalFunction::ThreadSpawnIndirect {
954
0
                    func_ty_index,
955
0
                    table_index,
956
                } => {
957
0
                    self.print_intrinsic(state, "canon thread.spawn-indirect ", &|me, state| {
958
0
                        me.print_idx(&state.core.type_names, func_ty_index)?;
959
0
                        me.result.write_str(" ")?;
960
0
                        me.start_group("table ")?;
961
0
                        me.print_idx(&state.core.table_names, table_index)?;
962
0
                        me.end_group()
963
0
                    })?;
964
                }
965
                CanonicalFunction::ThreadAvailableParallelism => {
966
0
                    self.print_intrinsic(state, "canon thread.available_parallelism", &|_, _| {
967
0
                        Ok(())
968
0
                    })?;
969
                }
970
                CanonicalFunction::BackpressureInc => {
971
0
                    self.print_intrinsic(state, "canon backpressure.inc", &|_, _| Ok(()))?;
972
                }
973
                CanonicalFunction::BackpressureDec => {
974
0
                    self.print_intrinsic(state, "canon backpressure.dec", &|_, _| Ok(()))?;
975
                }
976
0
                CanonicalFunction::TaskReturn { result, options } => {
977
0
                    self.print_intrinsic(state, "canon task.return", &|me, state| {
978
0
                        if let Some(ty) = result {
979
0
                            me.result.write_str(" ")?;
980
0
                            me.start_group("result ")?;
981
0
                            me.print_component_val_type(state, &ty)?;
982
0
                            me.end_group()?;
983
0
                        }
984
0
                        me.print_canonical_options(state, &options)?;
985
0
                        Ok(())
986
0
                    })?;
987
                }
988
                CanonicalFunction::TaskCancel => {
989
0
                    self.print_intrinsic(state, "canon task.cancel", &|_, _| Ok(()))?;
990
                }
991
0
                CanonicalFunction::ContextGet { ty, slot } => {
992
0
                    self.print_intrinsic(state, "canon context.get", &|me, state| {
993
0
                        me.result.write_str(" ")?;
994
0
                        me.print_valtype(state, ty)?;
995
0
                        write!(me.result, " {slot}")?;
996
0
                        Ok(())
997
0
                    })?;
998
                }
999
0
                CanonicalFunction::ContextSet { ty, slot } => {
1000
0
                    self.print_intrinsic(state, "canon context.set", &|me, state| {
1001
0
                        me.result.write_str(" ")?;
1002
0
                        me.print_valtype(state, ty)?;
1003
0
                        write!(me.result, " {slot}")?;
1004
0
                        Ok(())
1005
0
                    })?;
1006
                }
1007
0
                CanonicalFunction::ThreadYield { cancellable } => {
1008
0
                    self.print_intrinsic(state, "canon thread.yield", &|me, _| {
1009
0
                        if cancellable {
1010
0
                            me.print_type_keyword(" cancellable")?;
1011
0
                        }
1012
0
                        Ok(())
1013
0
                    })?;
1014
                }
1015
                CanonicalFunction::SubtaskDrop => {
1016
0
                    self.print_intrinsic(state, "canon subtask.drop", &|_, _| Ok(()))?;
1017
                }
1018
0
                CanonicalFunction::SubtaskCancel { async_ } => {
1019
0
                    self.print_intrinsic(state, "canon subtask.cancel", &|me, _| {
1020
0
                        if async_ {
1021
0
                            me.print_type_keyword(" async")?;
1022
0
                        }
1023
0
                        Ok(())
1024
0
                    })?;
1025
                }
1026
0
                CanonicalFunction::StreamNew { ty } => {
1027
0
                    self.print_intrinsic(state, "canon stream.new ", &|me, state| {
1028
0
                        me.print_idx(&state.component.type_names, ty)
1029
0
                    })?;
1030
                }
1031
0
                CanonicalFunction::StreamRead { ty, options } => {
1032
0
                    self.print_intrinsic(state, "canon stream.read ", &|me, state| {
1033
0
                        me.print_idx(&state.component.type_names, ty)?;
1034
0
                        me.print_canonical_options(state, &options)
1035
0
                    })?;
1036
                }
1037
0
                CanonicalFunction::StreamWrite { ty, options } => {
1038
0
                    self.print_intrinsic(state, "canon stream.write ", &|me, state| {
1039
0
                        me.print_idx(&state.component.type_names, ty)?;
1040
0
                        me.print_canonical_options(state, &options)
1041
0
                    })?;
1042
                }
1043
0
                CanonicalFunction::StreamCancelRead { ty, async_ } => {
1044
0
                    self.print_intrinsic(state, "canon stream.cancel-read ", &|me, state| {
1045
0
                        me.print_idx(&state.component.type_names, ty)?;
1046
0
                        if async_ {
1047
0
                            me.print_type_keyword(" async")?;
1048
0
                        }
1049
0
                        Ok(())
1050
0
                    })?;
1051
                }
1052
0
                CanonicalFunction::StreamCancelWrite { ty, async_ } => {
1053
0
                    self.print_intrinsic(state, "canon stream.cancel-write ", &|me, state| {
1054
0
                        me.print_idx(&state.component.type_names, ty)?;
1055
0
                        if async_ {
1056
0
                            me.print_type_keyword(" async")?;
1057
0
                        }
1058
0
                        Ok(())
1059
0
                    })?;
1060
                }
1061
0
                CanonicalFunction::StreamDropReadable { ty } => {
1062
0
                    self.print_intrinsic(state, "canon stream.drop-readable ", &|me, state| {
1063
0
                        me.print_idx(&state.component.type_names, ty)
1064
0
                    })?;
1065
                }
1066
0
                CanonicalFunction::StreamDropWritable { ty } => {
1067
0
                    self.print_intrinsic(state, "canon stream.drop-writable ", &|me, state| {
1068
0
                        me.print_idx(&state.component.type_names, ty)
1069
0
                    })?;
1070
                }
1071
0
                CanonicalFunction::FutureNew { ty } => {
1072
0
                    self.print_intrinsic(state, "canon future.new ", &|me, state| {
1073
0
                        me.print_idx(&state.component.type_names, ty)
1074
0
                    })?;
1075
                }
1076
0
                CanonicalFunction::FutureRead { ty, options } => {
1077
0
                    self.print_intrinsic(state, "canon future.read ", &|me, state| {
1078
0
                        me.print_idx(&state.component.type_names, ty)?;
1079
0
                        me.print_canonical_options(state, &options)
1080
0
                    })?;
1081
                }
1082
0
                CanonicalFunction::FutureWrite { ty, options } => {
1083
0
                    self.print_intrinsic(state, "canon future.write ", &|me, state| {
1084
0
                        me.print_idx(&state.component.type_names, ty)?;
1085
0
                        me.print_canonical_options(state, &options)
1086
0
                    })?;
1087
                }
1088
0
                CanonicalFunction::FutureCancelRead { ty, async_ } => {
1089
0
                    self.print_intrinsic(state, "canon future.cancel-read ", &|me, state| {
1090
0
                        me.print_idx(&state.component.type_names, ty)?;
1091
0
                        if async_ {
1092
0
                            me.print_type_keyword(" async")?;
1093
0
                        }
1094
0
                        Ok(())
1095
0
                    })?;
1096
                }
1097
0
                CanonicalFunction::FutureCancelWrite { ty, async_ } => {
1098
0
                    self.print_intrinsic(state, "canon future.cancel-write ", &|me, state| {
1099
0
                        me.print_idx(&state.component.type_names, ty)?;
1100
0
                        if async_ {
1101
0
                            me.print_type_keyword(" async")?;
1102
0
                        }
1103
0
                        Ok(())
1104
0
                    })?;
1105
                }
1106
0
                CanonicalFunction::FutureDropReadable { ty } => {
1107
0
                    self.print_intrinsic(state, "canon future.drop-readable ", &|me, state| {
1108
0
                        me.print_idx(&state.component.type_names, ty)
1109
0
                    })?;
1110
                }
1111
0
                CanonicalFunction::FutureDropWritable { ty } => {
1112
0
                    self.print_intrinsic(state, "canon future.drop-writable ", &|me, state| {
1113
0
                        me.print_idx(&state.component.type_names, ty)
1114
0
                    })?;
1115
                }
1116
0
                CanonicalFunction::ErrorContextNew { options } => {
1117
0
                    self.print_intrinsic(state, "canon error-context.new", &|me, state| {
1118
0
                        me.print_canonical_options(state, &options)
1119
0
                    })?;
1120
                }
1121
0
                CanonicalFunction::ErrorContextDebugMessage { options } => {
1122
0
                    self.print_intrinsic(
1123
0
                        state,
1124
0
                        "canon error-context.debug-message",
1125
0
                        &|me, state| me.print_canonical_options(state, &options),
1126
0
                    )?;
1127
                }
1128
                CanonicalFunction::ErrorContextDrop => {
1129
0
                    self.print_intrinsic(state, "canon error-context.drop", &|_, _| Ok(()))?;
1130
                }
1131
                CanonicalFunction::WaitableSetNew => {
1132
0
                    self.print_intrinsic(state, "canon waitable-set.new", &|_, _| Ok(()))?;
1133
                }
1134
                CanonicalFunction::WaitableSetWait {
1135
0
                    cancellable,
1136
0
                    memory,
1137
                } => {
1138
0
                    self.print_intrinsic(state, "canon waitable-set.wait ", &|me, state| {
1139
0
                        if cancellable {
1140
0
                            me.result.write_str("cancellable ")?;
1141
0
                        }
1142
0
                        me.start_group("memory ")?;
1143
0
                        me.print_idx(&state.core.memory_names, memory)?;
1144
0
                        me.end_group()
1145
0
                    })?;
1146
                }
1147
                CanonicalFunction::WaitableSetPoll {
1148
0
                    cancellable,
1149
0
                    memory,
1150
                } => {
1151
0
                    self.print_intrinsic(state, "canon waitable-set.poll ", &|me, state| {
1152
0
                        if cancellable {
1153
0
                            me.result.write_str("cancellable ")?;
1154
0
                        }
1155
0
                        me.start_group("memory ")?;
1156
0
                        me.print_idx(&state.core.memory_names, memory)?;
1157
0
                        me.end_group()
1158
0
                    })?;
1159
                }
1160
                CanonicalFunction::WaitableSetDrop => {
1161
0
                    self.print_intrinsic(state, "canon waitable-set.drop", &|_, _| Ok(()))?;
1162
                }
1163
                CanonicalFunction::WaitableJoin => {
1164
0
                    self.print_intrinsic(state, "canon waitable.join", &|_, _| Ok(()))?;
1165
                }
1166
                CanonicalFunction::ThreadIndex => {
1167
0
                    self.print_intrinsic(state, "canon thread.index", &|_, _| Ok(()))?;
1168
                }
1169
                CanonicalFunction::ThreadNewIndirect {
1170
0
                    func_ty_index,
1171
0
                    table_index,
1172
                } => {
1173
0
                    self.print_intrinsic(state, "canon thread.new-indirect ", &|me, state| {
1174
0
                        me.print_idx(&state.core.type_names, func_ty_index)?;
1175
0
                        me.result.write_str(" ")?;
1176
0
                        me.start_group("table ")?;
1177
0
                        me.print_idx(&state.core.table_names, table_index)?;
1178
0
                        me.end_group()
1179
0
                    })?;
1180
                }
1181
0
                CanonicalFunction::ThreadSuspendToSuspended { cancellable } => {
1182
0
                    self.print_intrinsic(state, "canon thread.suspend-to-suspended", &|me, _| {
1183
0
                        if cancellable {
1184
0
                            me.result.write_str(" cancellable")?;
1185
0
                        }
1186
0
                        Ok(())
1187
0
                    })?;
1188
                }
1189
0
                CanonicalFunction::ThreadSuspend { cancellable } => {
1190
0
                    self.print_intrinsic(state, "canon thread.suspend", &|me, _| {
1191
0
                        if cancellable {
1192
0
                            me.result.write_str(" cancellable")?;
1193
0
                        }
1194
0
                        Ok(())
1195
0
                    })?;
1196
                }
1197
0
                CanonicalFunction::ThreadSuspendTo { cancellable } => {
1198
0
                    self.print_intrinsic(state, "canon thread.suspend-to", &|me, _| {
1199
0
                        if cancellable {
1200
0
                            me.result.write_str(" cancellable")?;
1201
0
                        }
1202
0
                        Ok(())
1203
0
                    })?;
1204
                }
1205
                CanonicalFunction::ThreadUnsuspend => {
1206
0
                    self.print_intrinsic(state, "canon thread.unsuspend", &|_, _| Ok(()))?;
1207
                }
1208
0
                CanonicalFunction::ThreadYieldToSuspended { cancellable } => {
1209
0
                    self.print_intrinsic(state, "canon thread.yield-to-suspended", &|me, _| {
1210
0
                        if cancellable {
1211
0
                            me.result.write_str(" cancellable")?;
1212
0
                        }
1213
0
                        Ok(())
1214
0
                    })?;
1215
                }
1216
            }
1217
        }
1218
1219
0
        Ok(())
1220
0
    }
1221
1222
0
    pub(crate) fn print_instances(
1223
0
        &mut self,
1224
0
        state: &mut State,
1225
0
        parser: InstanceSectionReader,
1226
0
    ) -> Result<()> {
1227
0
        for instance in parser.into_iter_with_offsets() {
1228
0
            let (offset, instance) = instance?;
1229
0
            self.newline(offset)?;
1230
0
            self.start_group("core instance ")?;
1231
0
            self.print_name(&state.core.instance_names, state.core.instances)?;
1232
0
            match instance {
1233
0
                Instance::Instantiate { module_index, args } => {
1234
0
                    self.result.write_str(" ")?;
1235
0
                    self.start_group("instantiate ")?;
1236
0
                    self.print_idx(&state.core.module_names, module_index)?;
1237
0
                    for arg in args.iter() {
1238
0
                        self.newline(offset)?;
1239
0
                        self.print_instantiation_arg(state, arg)?;
1240
                    }
1241
0
                    self.end_group()?;
1242
0
                    state.core.instances += 1;
1243
                }
1244
0
                Instance::FromExports(exports) => {
1245
0
                    for export in exports.iter() {
1246
0
                        self.newline(offset)?;
1247
0
                        self.print_export(state, export)?;
1248
                    }
1249
0
                    state.core.instances += 1;
1250
                }
1251
            }
1252
0
            self.end_group()?;
1253
        }
1254
0
        Ok(())
1255
0
    }
1256
1257
0
    pub(crate) fn print_component_instances(
1258
0
        &mut self,
1259
0
        state: &mut State,
1260
0
        parser: ComponentInstanceSectionReader,
1261
0
    ) -> Result<()> {
1262
0
        for instance in parser.into_iter_with_offsets() {
1263
0
            let (offset, instance) = instance?;
1264
0
            self.newline(offset)?;
1265
0
            self.start_group("instance ")?;
1266
0
            self.print_name(&state.component.instance_names, state.component.instances)?;
1267
0
            state.component.instances += 1;
1268
0
            match instance {
1269
                ComponentInstance::Instantiate {
1270
0
                    component_index,
1271
0
                    args,
1272
                } => {
1273
0
                    self.result.write_str(" ")?;
1274
0
                    self.start_group("instantiate ")?;
1275
0
                    self.print_idx(&state.component.component_names, component_index)?;
1276
0
                    for arg in args.iter() {
1277
0
                        self.newline(offset)?;
1278
0
                        self.print_component_instantiation_arg(state, arg)?;
1279
                    }
1280
0
                    self.end_group()?;
1281
                }
1282
0
                ComponentInstance::FromExports(exports) => {
1283
0
                    for export in exports.iter() {
1284
0
                        self.newline(offset)?;
1285
0
                        self.print_component_export(state, export, false)?;
1286
                    }
1287
                }
1288
            }
1289
0
            self.end_group()?;
1290
        }
1291
0
        Ok(())
1292
0
    }
1293
1294
0
    pub(crate) fn print_instantiation_arg(
1295
0
        &mut self,
1296
0
        state: &State,
1297
0
        arg: &InstantiationArg,
1298
0
    ) -> Result<()> {
1299
0
        self.start_group("with ")?;
1300
0
        self.print_str(arg.name)?;
1301
0
        self.result.write_str(" ")?;
1302
0
        match arg.kind {
1303
            InstantiationArgKind::Instance => {
1304
0
                self.start_group("instance ")?;
1305
0
                self.print_idx(&state.core.instance_names, arg.index)?;
1306
0
                self.end_group()?;
1307
            }
1308
        }
1309
0
        self.end_group()?;
1310
0
        Ok(())
1311
0
    }
1312
1313
0
    pub(crate) fn print_component_instantiation_arg(
1314
0
        &mut self,
1315
0
        state: &State,
1316
0
        arg: &ComponentInstantiationArg,
1317
0
    ) -> Result<()> {
1318
0
        self.start_group("with ")?;
1319
0
        self.print_str(arg.name)?;
1320
0
        self.result.write_str(" ")?;
1321
0
        self.print_component_external_kind(state, arg.kind, arg.index)?;
1322
0
        self.end_group()?;
1323
0
        Ok(())
1324
0
    }
1325
1326
0
    pub(crate) fn print_component_start(
1327
0
        &mut self,
1328
0
        state: &mut State,
1329
0
        pos: usize,
1330
0
        start: ComponentStartFunction,
1331
0
    ) -> Result<()> {
1332
0
        self.newline(pos)?;
1333
0
        self.start_group("start ")?;
1334
0
        self.print_idx(&state.component.func_names, start.func_index)?;
1335
1336
0
        for arg in start.arguments.iter() {
1337
0
            self.result.write_str(" ")?;
1338
0
            self.start_group("value ")?;
1339
0
            self.print_idx(&state.component.value_names, *arg)?;
1340
0
            self.end_group()?;
1341
        }
1342
1343
0
        for _ in 0..start.results {
1344
0
            self.result.write_str(" ")?;
1345
0
            self.start_group("result ")?;
1346
0
            self.start_group("value ")?;
1347
0
            self.print_name(&state.component.value_names, state.component.values)?;
1348
0
            self.end_group()?;
1349
0
            self.end_group()?;
1350
0
            state.component.values += 1;
1351
        }
1352
1353
0
        self.end_group()?; // start
1354
1355
0
        Ok(())
1356
0
    }
1357
1358
0
    pub(crate) fn print_component_aliases(
1359
0
        &mut self,
1360
0
        states: &mut [State],
1361
0
        parser: ComponentAliasSectionReader,
1362
0
    ) -> Result<()> {
1363
0
        for alias in parser.into_iter_with_offsets() {
1364
0
            let (offset, alias) = alias?;
1365
0
            self.newline(offset)?;
1366
0
            self.print_component_alias(states, alias)?;
1367
        }
1368
0
        Ok(())
1369
0
    }
1370
1371
0
    pub(crate) fn print_component_alias(
1372
0
        &mut self,
1373
0
        states: &mut [State],
1374
0
        alias: ComponentAlias<'_>,
1375
0
    ) -> Result<()> {
1376
0
        match alias {
1377
            ComponentAlias::InstanceExport {
1378
0
                kind,
1379
0
                instance_index,
1380
0
                name,
1381
            } => {
1382
0
                let state = states.last_mut().unwrap();
1383
0
                self.start_group("alias export ")?;
1384
0
                self.print_idx(&state.component.instance_names, instance_index)?;
1385
0
                self.result.write_str(" ")?;
1386
0
                self.print_str(name)?;
1387
0
                self.result.write_str(" ")?;
1388
0
                self.start_component_external_kind_group(kind)?;
1389
0
                self.print_component_kind_name(state, kind)?;
1390
0
                self.end_group()?;
1391
1392
0
                self.end_group()?; // alias export
1393
            }
1394
            ComponentAlias::CoreInstanceExport {
1395
0
                instance_index,
1396
0
                kind,
1397
0
                name,
1398
            } => {
1399
0
                let state = states.last_mut().unwrap();
1400
0
                self.start_group("alias core export ")?;
1401
0
                self.print_idx(&state.core.instance_names, instance_index)?;
1402
0
                self.result.write_str(" ")?;
1403
0
                self.print_str(name)?;
1404
0
                self.result.write_str(" ")?;
1405
0
                match kind {
1406
                    ExternalKind::Func | ExternalKind::FuncExact => {
1407
0
                        self.start_group("core func ")?;
1408
0
                        self.print_name(&state.core.func_names, state.core.funcs)?;
1409
0
                        self.end_group()?;
1410
0
                        debug_assert_eq!(state.core.func_to_type.len(), state.core.funcs as usize);
1411
0
                        state.core.funcs += 1;
1412
0
                        state.core.func_to_type.push(None)
1413
                    }
1414
                    ExternalKind::Table => {
1415
0
                        self.start_group("core table ")?;
1416
0
                        self.print_name(&state.core.table_names, state.core.tables)?;
1417
0
                        self.end_group()?;
1418
0
                        state.core.tables += 1;
1419
                    }
1420
                    ExternalKind::Memory => {
1421
0
                        self.start_group("core memory ")?;
1422
0
                        self.print_name(&state.core.memory_names, state.core.memories)?;
1423
0
                        self.end_group()?;
1424
0
                        state.core.memories += 1;
1425
                    }
1426
                    ExternalKind::Global => {
1427
0
                        self.start_group("core global ")?;
1428
0
                        self.print_name(&state.core.global_names, state.core.globals)?;
1429
0
                        self.end_group()?;
1430
0
                        state.core.globals += 1;
1431
                    }
1432
                    ExternalKind::Tag => {
1433
0
                        self.start_group("core tag ")?;
1434
0
                        self.print_name(&state.core.tag_names, state.core.tags)?;
1435
0
                        self.end_group()?;
1436
0
                        debug_assert_eq!(state.core.tag_to_type.len(), state.core.tags as usize);
1437
0
                        state.core.tags += 1;
1438
0
                        state.core.tag_to_type.push(None)
1439
                    }
1440
                }
1441
0
                self.end_group()?; // alias export
1442
            }
1443
1444
0
            ComponentAlias::Outer { kind, count, index } => {
1445
0
                let state = states.last().unwrap();
1446
0
                let default_state = State::new(Encoding::Component);
1447
0
                let outer = match Self::outer_state(states, count) {
1448
0
                    Ok(o) => o,
1449
0
                    Err(e) => {
1450
0
                        write!(self.result, "(; {e} ;) ")?;
1451
0
                        &default_state
1452
                    }
1453
                };
1454
0
                self.start_group("alias outer ")?;
1455
0
                if let Some(name) = outer.name.as_ref() {
1456
0
                    name.write(self)?;
1457
                } else {
1458
0
                    write!(self.result, "{count}")?;
1459
                }
1460
0
                self.result.write_str(" ")?;
1461
0
                match kind {
1462
                    ComponentOuterAliasKind::CoreModule => {
1463
0
                        self.print_idx(&outer.core.module_names, index)?;
1464
0
                        self.result.write_str(" ")?;
1465
0
                        self.start_group("core module ")?;
1466
0
                        self.print_name(&state.core.module_names, state.core.modules)?;
1467
                    }
1468
                    ComponentOuterAliasKind::CoreType => {
1469
0
                        self.print_idx(&outer.core.type_names, index)?;
1470
0
                        self.result.write_str(" ")?;
1471
0
                        self.start_group("core type ")?;
1472
0
                        self.print_name(&state.core.type_names, state.core.types.len() as u32)?;
1473
                    }
1474
                    ComponentOuterAliasKind::Type => {
1475
0
                        self.print_idx(&outer.component.type_names, index)?;
1476
0
                        self.result.write_str(" ")?;
1477
0
                        self.start_group("type ")?;
1478
0
                        self.print_name(&state.component.type_names, state.component.types)?;
1479
                    }
1480
                    ComponentOuterAliasKind::Component => {
1481
0
                        self.print_idx(&outer.component.component_names, index)?;
1482
0
                        self.result.write_str(" ")?;
1483
0
                        self.start_group("component ")?;
1484
0
                        self.print_name(
1485
0
                            &state.component.component_names,
1486
0
                            state.component.components,
1487
0
                        )?;
1488
                    }
1489
                }
1490
0
                self.end_group()?; // kind
1491
0
                self.end_group()?; // alias
1492
1493
0
                let state = states.last_mut().unwrap();
1494
0
                match kind {
1495
0
                    ComponentOuterAliasKind::CoreModule => state.core.modules += 1,
1496
0
                    ComponentOuterAliasKind::CoreType => state.core.types.push(None),
1497
0
                    ComponentOuterAliasKind::Type => state.component.types += 1,
1498
0
                    ComponentOuterAliasKind::Component => state.component.components += 1,
1499
                }
1500
            }
1501
        }
1502
0
        Ok(())
1503
0
    }
1504
}