Coverage Report

Created: 2026-04-09 08:09

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_str(name.0)?;
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
    pub(crate) fn print_instance_type<'a>(
396
0
        &mut self,
397
0
        states: &mut Vec<State>,
398
0
        decls: Vec<InstanceTypeDeclaration<'a>>,
399
0
    ) -> Result<()> {
400
0
        states.push(State::new(Encoding::Component));
401
0
        self.newline_unknown_pos()?;
402
0
        self.start_group("instance")?;
403
0
        for decl in decls {
404
0
            self.newline_unknown_pos()?;
405
0
            match decl {
406
0
                InstanceTypeDeclaration::CoreType(ty) => self.print_core_type(states, ty)?,
407
0
                InstanceTypeDeclaration::Type(ty) => self.print_component_type_def(states, ty)?,
408
0
                InstanceTypeDeclaration::Alias(alias) => {
409
0
                    self.print_component_alias(states, alias)?;
410
                }
411
0
                InstanceTypeDeclaration::Export { name, ty } => {
412
0
                    self.start_group("export ")?;
413
0
                    self.print_component_kind_name(states.last_mut().unwrap(), ty.kind())?;
414
0
                    self.result.write_str(" ")?;
415
0
                    self.print_str(name.0)?;
416
0
                    self.result.write_str(" ")?;
417
0
                    self.print_component_import_ty(states.last_mut().unwrap(), &ty, false)?;
418
0
                    self.end_group()?;
419
                }
420
            }
421
        }
422
0
        self.end_group()?;
423
0
        states.pop().unwrap();
424
0
        Ok(())
425
0
    }
426
427
0
    pub(crate) fn outer_state(states: &[State], count: u32) -> Result<&State> {
428
0
        if count as usize >= states.len() {
429
0
            bail!("invalid outer alias count {}", count);
430
0
        }
431
432
0
        let count: usize = std::cmp::min(count as usize, states.len() - 1);
433
0
        Ok(&states[states.len() - count - 1])
434
0
    }
435
436
0
    pub(crate) fn print_outer_alias(
437
0
        &mut self,
438
0
        states: &mut [State],
439
0
        kind: OuterAliasKind,
440
0
        count: u32,
441
0
        index: u32,
442
0
    ) -> Result<()> {
443
0
        let state = states.last().unwrap();
444
0
        let default_state = State::new(Encoding::Component);
445
0
        let outer = match Self::outer_state(states, count) {
446
0
            Ok(o) => o,
447
0
            Err(e) => {
448
0
                write!(self.result, "(; {e} ;) ")?;
449
0
                &default_state
450
            }
451
        };
452
0
        self.start_group("alias outer ")?;
453
0
        if let Some(name) = outer.name.as_ref() {
454
0
            name.write(self)?;
455
        } else {
456
0
            write!(self.result, "{count}")?;
457
        }
458
0
        self.result.write_str(" ")?;
459
0
        match kind {
460
            OuterAliasKind::Type => {
461
0
                self.print_idx(&outer.core.type_names, index)?;
462
0
                self.result.write_str(" ")?;
463
0
                self.start_group("type ")?;
464
0
                self.print_name(&state.core.type_names, state.core.types.len() as u32)?;
465
            }
466
        }
467
0
        self.end_group()?; // kind
468
0
        self.end_group()?; // alias
469
470
0
        let state = states.last_mut().unwrap();
471
0
        match kind {
472
0
            OuterAliasKind::Type => state.core.types.push(None),
473
        }
474
475
0
        Ok(())
476
0
    }
477
478
0
    pub(crate) fn print_component_func_type(
479
0
        &mut self,
480
0
        state: &State,
481
0
        ty: &ComponentFuncType,
482
0
    ) -> Result<()> {
483
0
        self.start_group("func")?;
484
0
        if ty.async_ {
485
0
            self.print_type_keyword(" async")?;
486
0
        }
487
0
        for (name, ty) in ty.params.iter() {
488
0
            self.result.write_str(" ")?;
489
0
            self.start_group("param ")?;
490
0
            self.print_str(name)?;
491
0
            self.result.write_str(" ")?;
492
0
            self.print_component_val_type(state, ty)?;
493
0
            self.end_group()?;
494
        }
495
496
0
        if let Some(ty) = &ty.result {
497
0
            self.result.write_str(" ")?;
498
0
            self.start_group("result ")?;
499
0
            self.print_component_val_type(state, ty)?;
500
0
            self.end_group()?;
501
0
        }
502
503
0
        self.end_group()?;
504
505
0
        Ok(())
506
0
    }
507
508
0
    pub(crate) fn print_component_type_def<'a>(
509
0
        &mut self,
510
0
        states: &mut Vec<State>,
511
0
        ty: ComponentType<'a>,
512
0
    ) -> Result<()> {
513
0
        self.start_group("type ")?;
514
        {
515
0
            let state = states.last_mut().unwrap();
516
0
            self.print_name(&state.component.type_names, state.component.types)?;
517
        }
518
0
        match ty {
519
0
            ComponentType::Defined(ty) => {
520
0
                self.result.write_str(" ")?;
521
0
                self.print_defined_type(states.last_mut().unwrap(), &ty)?;
522
            }
523
0
            ComponentType::Func(ty) => {
524
0
                self.result.write_str(" ")?;
525
0
                self.print_component_func_type(states.last_mut().unwrap(), &ty)?;
526
            }
527
0
            ComponentType::Component(decls) => {
528
0
                self.print_component_type(states, decls.into_vec())?;
529
            }
530
0
            ComponentType::Instance(decls) => {
531
0
                self.print_instance_type(states, decls.into_vec())?;
532
            }
533
0
            ComponentType::Resource { rep, dtor } => {
534
0
                self.result.write_str(" ")?;
535
0
                self.start_group("resource ")?;
536
0
                self.start_group("rep ")?;
537
0
                self.print_valtype(states.last().unwrap(), rep)?;
538
0
                self.end_group()?;
539
0
                if let Some(dtor) = dtor {
540
0
                    self.result.write_str(" ")?;
541
0
                    self.start_group("dtor ")?;
542
0
                    self.start_group("func ")?;
543
0
                    self.print_idx(&states.last().unwrap().core.func_names, dtor)?;
544
0
                    self.end_group()?;
545
0
                    self.end_group()?;
546
0
                }
547
0
                self.end_group()?;
548
            }
549
        }
550
0
        self.end_group()?;
551
552
0
        states.last_mut().unwrap().component.types += 1;
553
554
0
        Ok(())
555
0
    }
556
557
0
    pub(crate) fn print_component_types<'a>(
558
0
        &mut self,
559
0
        states: &mut Vec<State>,
560
0
        parser: ComponentTypeSectionReader<'a>,
561
0
    ) -> Result<()> {
562
0
        for ty in parser.into_iter_with_offsets() {
563
0
            let (offset, ty) = ty?;
564
0
            self.newline(offset)?;
565
0
            self.print_component_type_def(states, ty)?;
566
        }
567
568
0
        Ok(())
569
0
    }
570
571
0
    pub(crate) fn print_component_imports(
572
0
        &mut self,
573
0
        state: &mut State,
574
0
        parser: ComponentImportSectionReader,
575
0
    ) -> Result<()> {
576
0
        for import in parser.into_iter_with_offsets() {
577
0
            let (offset, import) = import?;
578
0
            self.newline(offset)?;
579
0
            self.print_component_import(state, &import, true)?;
580
        }
581
582
0
        Ok(())
583
0
    }
584
585
0
    pub(crate) fn print_component_import(
586
0
        &mut self,
587
0
        state: &mut State,
588
0
        import: &ComponentImport,
589
0
        index: bool,
590
0
    ) -> Result<()> {
591
0
        self.start_group("import ")?;
592
0
        self.print_str(import.name.0)?;
593
0
        self.result.write_str(" ")?;
594
0
        self.print_component_import_ty(state, &import.ty, index)?;
595
0
        self.end_group()?;
596
0
        Ok(())
597
0
    }
598
599
0
    pub(crate) fn print_component_import_ty(
600
0
        &mut self,
601
0
        state: &mut State,
602
0
        ty: &ComponentTypeRef,
603
0
        index: bool,
604
0
    ) -> Result<()> {
605
0
        match ty {
606
0
            ComponentTypeRef::Module(idx) => {
607
0
                self.start_group("core module ")?;
608
0
                if index {
609
0
                    self.print_name(&state.core.module_names, state.core.modules)?;
610
0
                    self.result.write_str(" ")?;
611
0
                    state.core.modules += 1;
612
0
                }
613
0
                self.print_core_type_ref(state, *idx)?;
614
0
                self.end_group()?;
615
            }
616
0
            ComponentTypeRef::Func(idx) => {
617
0
                self.start_group("func ")?;
618
0
                if index {
619
0
                    self.print_name(&state.component.func_names, state.component.funcs)?;
620
0
                    self.result.write_str(" ")?;
621
0
                    state.component.funcs += 1;
622
0
                }
623
0
                self.print_component_type_ref(state, *idx)?;
624
0
                self.end_group()?;
625
            }
626
0
            ComponentTypeRef::Value(ty) => {
627
0
                self.start_group("value ")?;
628
0
                if index {
629
0
                    self.print_name(&state.component.value_names, state.component.values)?;
630
0
                    self.result.write_str(" ")?;
631
0
                    state.component.values += 1;
632
0
                }
633
0
                match ty {
634
0
                    ComponentValType::Primitive(ty) => self.print_primitive_val_type(ty)?,
635
0
                    ComponentValType::Type(idx) => self.print_component_type_ref(state, *idx)?,
636
                }
637
0
                self.end_group()?;
638
            }
639
0
            ComponentTypeRef::Type(bounds) => {
640
0
                self.start_group("type ")?;
641
0
                if index {
642
0
                    self.print_name(&state.component.type_names, state.component.types)?;
643
0
                    self.result.write_str(" ")?;
644
0
                    state.component.types += 1;
645
0
                }
646
0
                match bounds {
647
0
                    TypeBounds::Eq(idx) => {
648
0
                        self.start_group("eq ")?;
649
0
                        self.print_idx(&state.component.type_names, *idx)?;
650
0
                        self.end_group()?;
651
                    }
652
                    TypeBounds::SubResource => {
653
0
                        self.start_group("sub ")?;
654
0
                        self.print_type_keyword("resource")?;
655
0
                        self.end_group()?;
656
                    }
657
                };
658
0
                self.end_group()?;
659
            }
660
0
            ComponentTypeRef::Instance(idx) => {
661
0
                self.start_group("instance ")?;
662
0
                if index {
663
0
                    self.print_name(&state.component.instance_names, state.component.instances)?;
664
0
                    self.result.write_str(" ")?;
665
0
                    state.component.instances += 1;
666
0
                }
667
0
                self.print_component_type_ref(state, *idx)?;
668
0
                self.end_group()?;
669
            }
670
0
            ComponentTypeRef::Component(idx) => {
671
0
                self.start_group("component ")?;
672
0
                if index {
673
0
                    self.print_name(&state.component.component_names, state.component.components)?;
674
0
                    self.result.write_str(" ")?;
675
0
                    state.component.components += 1;
676
0
                }
677
0
                self.print_component_type_ref(state, *idx)?;
678
0
                self.end_group()?;
679
            }
680
        }
681
0
        Ok(())
682
0
    }
683
684
0
    pub(crate) fn print_component_exports(
685
0
        &mut self,
686
0
        state: &mut State,
687
0
        parser: ComponentExportSectionReader,
688
0
    ) -> Result<()> {
689
0
        for export in parser.into_iter_with_offsets() {
690
0
            let (offset, export) = export?;
691
0
            self.newline(offset)?;
692
0
            self.print_component_export(state, &export, true)?;
693
        }
694
0
        Ok(())
695
0
    }
696
697
0
    pub(crate) fn print_component_export(
698
0
        &mut self,
699
0
        state: &mut State,
700
0
        export: &ComponentExport,
701
0
        named: bool,
702
0
    ) -> Result<()> {
703
0
        self.start_group("export ")?;
704
0
        if named {
705
0
            self.print_component_kind_name(state, export.kind)?;
706
0
            self.result.write_str(" ")?;
707
0
        }
708
0
        self.print_str(export.name.0)?;
709
0
        self.result.write_str(" ")?;
710
0
        self.print_component_external_kind(state, export.kind, export.index)?;
711
0
        if let Some(ty) = &export.ty {
712
0
            self.result.write_str(" ")?;
713
0
            self.print_component_import_ty(state, &ty, false)?;
714
0
        }
715
0
        self.end_group()?;
716
0
        Ok(())
717
0
    }
718
719
0
    pub(crate) fn print_component_kind_name(
720
0
        &mut self,
721
0
        state: &mut State,
722
0
        kind: ComponentExternalKind,
723
0
    ) -> Result<()> {
724
0
        match kind {
725
            ComponentExternalKind::Func => {
726
0
                self.print_name(&state.component.func_names, state.component.funcs)?;
727
0
                state.component.funcs += 1;
728
            }
729
            ComponentExternalKind::Module => {
730
0
                self.print_name(&state.core.module_names, state.core.modules)?;
731
0
                state.core.modules += 1;
732
            }
733
            ComponentExternalKind::Value => {
734
0
                self.print_name(&state.component.value_names, state.component.values)?;
735
0
                state.component.values += 1;
736
            }
737
            ComponentExternalKind::Type => {
738
0
                self.print_name(&state.component.type_names, state.component.types)?;
739
0
                state.component.types += 1;
740
            }
741
            ComponentExternalKind::Instance => {
742
0
                self.print_name(&state.component.instance_names, state.component.instances)?;
743
0
                state.component.instances += 1;
744
            }
745
            ComponentExternalKind::Component => {
746
0
                self.print_name(&state.component.component_names, state.component.components)?;
747
0
                state.component.components += 1;
748
            }
749
        }
750
0
        Ok(())
751
0
    }
752
753
0
    pub(crate) fn start_component_external_kind_group(
754
0
        &mut self,
755
0
        kind: ComponentExternalKind,
756
0
    ) -> Result<()> {
757
0
        match kind {
758
            ComponentExternalKind::Module => {
759
0
                self.start_group("core module ")?;
760
            }
761
            ComponentExternalKind::Component => {
762
0
                self.start_group("component ")?;
763
            }
764
            ComponentExternalKind::Instance => {
765
0
                self.start_group("instance ")?;
766
            }
767
            ComponentExternalKind::Func => {
768
0
                self.start_group("func ")?;
769
            }
770
            ComponentExternalKind::Value => {
771
0
                self.start_group("value ")?;
772
            }
773
            ComponentExternalKind::Type => {
774
0
                self.start_group("type ")?;
775
            }
776
        }
777
0
        Ok(())
778
0
    }
779
780
0
    pub(crate) fn print_component_external_kind(
781
0
        &mut self,
782
0
        state: &State,
783
0
        kind: ComponentExternalKind,
784
0
        index: u32,
785
0
    ) -> Result<()> {
786
0
        self.start_component_external_kind_group(kind)?;
787
0
        match kind {
788
            ComponentExternalKind::Module => {
789
0
                self.print_idx(&state.core.module_names, index)?;
790
            }
791
            ComponentExternalKind::Component => {
792
0
                self.print_idx(&state.component.component_names, index)?;
793
            }
794
            ComponentExternalKind::Instance => {
795
0
                self.print_idx(&state.component.instance_names, index)?;
796
            }
797
            ComponentExternalKind::Func => {
798
0
                self.print_idx(&state.component.func_names, index)?;
799
            }
800
            ComponentExternalKind::Value => {
801
0
                self.print_idx(&state.component.value_names, index)?;
802
            }
803
            ComponentExternalKind::Type => {
804
0
                self.print_idx(&state.component.type_names, index)?;
805
            }
806
        }
807
0
        self.end_group()?;
808
0
        Ok(())
809
0
    }
810
811
0
    pub(crate) fn print_canonical_options(
812
0
        &mut self,
813
0
        state: &State,
814
0
        options: &[CanonicalOption],
815
0
    ) -> Result<()> {
816
0
        for option in options {
817
0
            self.result.write_str(" ")?;
818
0
            match option {
819
0
                CanonicalOption::UTF8 => self.result.write_str("string-encoding=utf8")?,
820
0
                CanonicalOption::UTF16 => self.result.write_str("string-encoding=utf16")?,
821
                CanonicalOption::CompactUTF16 => {
822
0
                    self.result.write_str("string-encoding=latin1+utf16")?
823
                }
824
0
                CanonicalOption::Memory(idx) => {
825
0
                    self.start_group("memory ")?;
826
0
                    self.print_idx(&state.core.memory_names, *idx)?;
827
0
                    self.end_group()?;
828
                }
829
0
                CanonicalOption::Realloc(idx) => {
830
0
                    self.start_group("realloc ")?;
831
0
                    self.print_idx(&state.core.func_names, *idx)?;
832
0
                    self.end_group()?;
833
                }
834
0
                CanonicalOption::PostReturn(idx) => {
835
0
                    self.start_group("post-return ")?;
836
0
                    self.print_idx(&state.core.func_names, *idx)?;
837
0
                    self.end_group()?;
838
                }
839
0
                CanonicalOption::Async => self.print_type_keyword("async")?,
840
0
                CanonicalOption::Callback(idx) => {
841
0
                    self.start_group("callback ")?;
842
0
                    self.print_idx(&state.core.func_names, *idx)?;
843
0
                    self.end_group()?;
844
                }
845
0
                CanonicalOption::CoreType(idx) => {
846
0
                    self.start_group("core-type ")?;
847
0
                    self.print_idx(&state.core.type_names, *idx)?;
848
0
                    self.end_group()?;
849
                }
850
0
                CanonicalOption::Gc => self.result.write_str("gc")?,
851
            }
852
        }
853
0
        Ok(())
854
0
    }
855
856
0
    fn print_intrinsic(
857
0
        &mut self,
858
0
        state: &mut State,
859
0
        group: &str,
860
0
        body: &dyn Fn(&mut Self, &mut State) -> Result<()>,
861
0
    ) -> Result<()> {
862
0
        self.start_group("core func ")?;
863
0
        self.print_name(&state.core.func_names, state.core.funcs)?;
864
0
        self.result.write_str(" ")?;
865
0
        self.start_group(group)?;
866
0
        body(self, state)?;
867
0
        self.end_group()?;
868
0
        self.end_group()?;
869
0
        debug_assert_eq!(state.core.func_to_type.len(), state.core.funcs as usize);
870
0
        state.core.funcs += 1;
871
0
        state.core.func_to_type.push(None);
872
0
        Ok(())
873
0
    }
874
875
0
    pub(crate) fn print_canonical_functions(
876
0
        &mut self,
877
0
        state: &mut State,
878
0
        parser: ComponentCanonicalSectionReader,
879
0
    ) -> Result<()> {
880
0
        for func in parser.into_iter_with_offsets() {
881
0
            let (offset, func) = func?;
882
0
            self.newline(offset)?;
883
0
            match func {
884
                CanonicalFunction::Lift {
885
0
                    core_func_index,
886
0
                    type_index,
887
0
                    options,
888
                } => {
889
0
                    self.start_group("func ")?;
890
0
                    self.print_name(&state.component.func_names, state.component.funcs)?;
891
0
                    self.result.write_str(" ")?;
892
0
                    self.start_group("type ")?;
893
0
                    self.print_idx(&state.component.type_names, type_index)?;
894
0
                    self.end_group()?;
895
0
                    self.result.write_str(" ")?;
896
0
                    self.start_group("canon lift ")?;
897
0
                    self.start_group("core func ")?;
898
0
                    self.print_idx(&state.core.func_names, core_func_index)?;
899
0
                    self.end_group()?;
900
0
                    self.print_canonical_options(state, &options)?;
901
0
                    self.end_group()?;
902
0
                    self.end_group()?;
903
0
                    state.component.funcs += 1;
904
                }
905
                CanonicalFunction::Lower {
906
0
                    func_index,
907
0
                    options,
908
                } => {
909
0
                    self.print_intrinsic(state, "canon lower ", &|me, state| {
910
0
                        me.start_group("func ")?;
911
0
                        me.print_idx(&state.component.func_names, func_index)?;
912
0
                        me.end_group()?;
913
0
                        me.print_canonical_options(state, &options)
914
0
                    })?;
915
                }
916
0
                CanonicalFunction::ResourceNew { resource } => {
917
0
                    self.print_intrinsic(state, "canon resource.new ", &|me, state| {
918
0
                        me.print_idx(&state.component.type_names, resource)
919
0
                    })?;
920
                }
921
0
                CanonicalFunction::ResourceDrop { resource } => {
922
0
                    self.print_intrinsic(state, "canon resource.drop ", &|me, state| {
923
0
                        me.print_idx(&state.component.type_names, resource)
924
0
                    })?;
925
                }
926
0
                CanonicalFunction::ResourceDropAsync { resource } => {
927
0
                    self.print_intrinsic(state, "canon resource.drop ", &|me, state| {
928
0
                        me.print_idx(&state.component.type_names, resource)?;
929
0
                        me.print_type_keyword(" async")
930
0
                    })?;
931
                }
932
0
                CanonicalFunction::ResourceRep { resource } => {
933
0
                    self.print_intrinsic(state, "canon resource.rep ", &|me, state| {
934
0
                        me.print_idx(&state.component.type_names, resource)
935
0
                    })?;
936
                }
937
0
                CanonicalFunction::ThreadSpawnRef { func_ty_index } => {
938
0
                    self.print_intrinsic(state, "canon thread.spawn-ref ", &|me, state| {
939
0
                        me.print_idx(&state.core.type_names, func_ty_index)
940
0
                    })?;
941
                }
942
                CanonicalFunction::ThreadSpawnIndirect {
943
0
                    func_ty_index,
944
0
                    table_index,
945
                } => {
946
0
                    self.print_intrinsic(state, "canon thread.spawn-indirect ", &|me, state| {
947
0
                        me.print_idx(&state.core.type_names, func_ty_index)?;
948
0
                        me.result.write_str(" ")?;
949
0
                        me.start_group("table ")?;
950
0
                        me.print_idx(&state.core.table_names, table_index)?;
951
0
                        me.end_group()
952
0
                    })?;
953
                }
954
                CanonicalFunction::ThreadAvailableParallelism => {
955
0
                    self.print_intrinsic(state, "canon thread.available_parallelism", &|_, _| {
956
0
                        Ok(())
957
0
                    })?;
958
                }
959
                CanonicalFunction::BackpressureInc => {
960
0
                    self.print_intrinsic(state, "canon backpressure.inc", &|_, _| Ok(()))?;
961
                }
962
                CanonicalFunction::BackpressureDec => {
963
0
                    self.print_intrinsic(state, "canon backpressure.dec", &|_, _| Ok(()))?;
964
                }
965
0
                CanonicalFunction::TaskReturn { result, options } => {
966
0
                    self.print_intrinsic(state, "canon task.return", &|me, state| {
967
0
                        if let Some(ty) = result {
968
0
                            me.result.write_str(" ")?;
969
0
                            me.start_group("result ")?;
970
0
                            me.print_component_val_type(state, &ty)?;
971
0
                            me.end_group()?;
972
0
                        }
973
0
                        me.print_canonical_options(state, &options)?;
974
0
                        Ok(())
975
0
                    })?;
976
                }
977
                CanonicalFunction::TaskCancel => {
978
0
                    self.print_intrinsic(state, "canon task.cancel", &|_, _| Ok(()))?;
979
                }
980
0
                CanonicalFunction::ContextGet(i) => {
981
0
                    self.print_intrinsic(state, "canon context.get", &|me, _state| {
982
0
                        write!(me.result, " i32 {i}")?;
983
0
                        Ok(())
984
0
                    })?;
985
                }
986
0
                CanonicalFunction::ContextSet(i) => {
987
0
                    self.print_intrinsic(state, "canon context.set", &|me, _state| {
988
0
                        write!(me.result, " i32 {i}")?;
989
0
                        Ok(())
990
0
                    })?;
991
                }
992
0
                CanonicalFunction::ThreadYield { cancellable } => {
993
0
                    self.print_intrinsic(state, "canon thread.yield", &|me, _| {
994
0
                        if cancellable {
995
0
                            me.print_type_keyword(" cancellable")?;
996
0
                        }
997
0
                        Ok(())
998
0
                    })?;
999
                }
1000
                CanonicalFunction::SubtaskDrop => {
1001
0
                    self.print_intrinsic(state, "canon subtask.drop", &|_, _| Ok(()))?;
1002
                }
1003
0
                CanonicalFunction::SubtaskCancel { async_ } => {
1004
0
                    self.print_intrinsic(state, "canon subtask.cancel", &|me, _| {
1005
0
                        if async_ {
1006
0
                            me.print_type_keyword(" async")?;
1007
0
                        }
1008
0
                        Ok(())
1009
0
                    })?;
1010
                }
1011
0
                CanonicalFunction::StreamNew { ty } => {
1012
0
                    self.print_intrinsic(state, "canon stream.new ", &|me, state| {
1013
0
                        me.print_idx(&state.component.type_names, ty)
1014
0
                    })?;
1015
                }
1016
0
                CanonicalFunction::StreamRead { ty, options } => {
1017
0
                    self.print_intrinsic(state, "canon stream.read ", &|me, state| {
1018
0
                        me.print_idx(&state.component.type_names, ty)?;
1019
0
                        me.print_canonical_options(state, &options)
1020
0
                    })?;
1021
                }
1022
0
                CanonicalFunction::StreamWrite { ty, options } => {
1023
0
                    self.print_intrinsic(state, "canon stream.write ", &|me, state| {
1024
0
                        me.print_idx(&state.component.type_names, ty)?;
1025
0
                        me.print_canonical_options(state, &options)
1026
0
                    })?;
1027
                }
1028
0
                CanonicalFunction::StreamCancelRead { ty, async_ } => {
1029
0
                    self.print_intrinsic(state, "canon stream.cancel-read ", &|me, state| {
1030
0
                        me.print_idx(&state.component.type_names, ty)?;
1031
0
                        if async_ {
1032
0
                            me.print_type_keyword(" async")?;
1033
0
                        }
1034
0
                        Ok(())
1035
0
                    })?;
1036
                }
1037
0
                CanonicalFunction::StreamCancelWrite { ty, async_ } => {
1038
0
                    self.print_intrinsic(state, "canon stream.cancel-write ", &|me, state| {
1039
0
                        me.print_idx(&state.component.type_names, ty)?;
1040
0
                        if async_ {
1041
0
                            me.print_type_keyword(" async")?;
1042
0
                        }
1043
0
                        Ok(())
1044
0
                    })?;
1045
                }
1046
0
                CanonicalFunction::StreamDropReadable { ty } => {
1047
0
                    self.print_intrinsic(state, "canon stream.drop-readable ", &|me, state| {
1048
0
                        me.print_idx(&state.component.type_names, ty)
1049
0
                    })?;
1050
                }
1051
0
                CanonicalFunction::StreamDropWritable { ty } => {
1052
0
                    self.print_intrinsic(state, "canon stream.drop-writable ", &|me, state| {
1053
0
                        me.print_idx(&state.component.type_names, ty)
1054
0
                    })?;
1055
                }
1056
0
                CanonicalFunction::FutureNew { ty } => {
1057
0
                    self.print_intrinsic(state, "canon future.new ", &|me, state| {
1058
0
                        me.print_idx(&state.component.type_names, ty)
1059
0
                    })?;
1060
                }
1061
0
                CanonicalFunction::FutureRead { ty, options } => {
1062
0
                    self.print_intrinsic(state, "canon future.read ", &|me, state| {
1063
0
                        me.print_idx(&state.component.type_names, ty)?;
1064
0
                        me.print_canonical_options(state, &options)
1065
0
                    })?;
1066
                }
1067
0
                CanonicalFunction::FutureWrite { ty, options } => {
1068
0
                    self.print_intrinsic(state, "canon future.write ", &|me, state| {
1069
0
                        me.print_idx(&state.component.type_names, ty)?;
1070
0
                        me.print_canonical_options(state, &options)
1071
0
                    })?;
1072
                }
1073
0
                CanonicalFunction::FutureCancelRead { ty, async_ } => {
1074
0
                    self.print_intrinsic(state, "canon future.cancel-read ", &|me, state| {
1075
0
                        me.print_idx(&state.component.type_names, ty)?;
1076
0
                        if async_ {
1077
0
                            me.print_type_keyword(" async")?;
1078
0
                        }
1079
0
                        Ok(())
1080
0
                    })?;
1081
                }
1082
0
                CanonicalFunction::FutureCancelWrite { ty, async_ } => {
1083
0
                    self.print_intrinsic(state, "canon future.cancel-write ", &|me, state| {
1084
0
                        me.print_idx(&state.component.type_names, ty)?;
1085
0
                        if async_ {
1086
0
                            me.print_type_keyword(" async")?;
1087
0
                        }
1088
0
                        Ok(())
1089
0
                    })?;
1090
                }
1091
0
                CanonicalFunction::FutureDropReadable { ty } => {
1092
0
                    self.print_intrinsic(state, "canon future.drop-readable ", &|me, state| {
1093
0
                        me.print_idx(&state.component.type_names, ty)
1094
0
                    })?;
1095
                }
1096
0
                CanonicalFunction::FutureDropWritable { ty } => {
1097
0
                    self.print_intrinsic(state, "canon future.drop-writable ", &|me, state| {
1098
0
                        me.print_idx(&state.component.type_names, ty)
1099
0
                    })?;
1100
                }
1101
0
                CanonicalFunction::ErrorContextNew { options } => {
1102
0
                    self.print_intrinsic(state, "canon error-context.new", &|me, state| {
1103
0
                        me.print_canonical_options(state, &options)
1104
0
                    })?;
1105
                }
1106
0
                CanonicalFunction::ErrorContextDebugMessage { options } => {
1107
0
                    self.print_intrinsic(
1108
0
                        state,
1109
0
                        "canon error-context.debug-message",
1110
0
                        &|me, state| me.print_canonical_options(state, &options),
1111
0
                    )?;
1112
                }
1113
                CanonicalFunction::ErrorContextDrop => {
1114
0
                    self.print_intrinsic(state, "canon error-context.drop", &|_, _| Ok(()))?;
1115
                }
1116
                CanonicalFunction::WaitableSetNew => {
1117
0
                    self.print_intrinsic(state, "canon waitable-set.new", &|_, _| Ok(()))?;
1118
                }
1119
                CanonicalFunction::WaitableSetWait {
1120
0
                    cancellable,
1121
0
                    memory,
1122
                } => {
1123
0
                    self.print_intrinsic(state, "canon waitable-set.wait ", &|me, state| {
1124
0
                        if cancellable {
1125
0
                            me.result.write_str("cancellable ")?;
1126
0
                        }
1127
0
                        me.start_group("memory ")?;
1128
0
                        me.print_idx(&state.core.memory_names, memory)?;
1129
0
                        me.end_group()
1130
0
                    })?;
1131
                }
1132
                CanonicalFunction::WaitableSetPoll {
1133
0
                    cancellable,
1134
0
                    memory,
1135
                } => {
1136
0
                    self.print_intrinsic(state, "canon waitable-set.poll ", &|me, state| {
1137
0
                        if cancellable {
1138
0
                            me.result.write_str("cancellable ")?;
1139
0
                        }
1140
0
                        me.start_group("memory ")?;
1141
0
                        me.print_idx(&state.core.memory_names, memory)?;
1142
0
                        me.end_group()
1143
0
                    })?;
1144
                }
1145
                CanonicalFunction::WaitableSetDrop => {
1146
0
                    self.print_intrinsic(state, "canon waitable-set.drop", &|_, _| Ok(()))?;
1147
                }
1148
                CanonicalFunction::WaitableJoin => {
1149
0
                    self.print_intrinsic(state, "canon waitable.join", &|_, _| Ok(()))?;
1150
                }
1151
                CanonicalFunction::ThreadIndex => {
1152
0
                    self.print_intrinsic(state, "canon thread.index", &|_, _| Ok(()))?;
1153
                }
1154
                CanonicalFunction::ThreadNewIndirect {
1155
0
                    func_ty_index,
1156
0
                    table_index,
1157
                } => {
1158
0
                    self.print_intrinsic(state, "canon thread.new-indirect ", &|me, state| {
1159
0
                        me.print_idx(&state.core.type_names, func_ty_index)?;
1160
0
                        me.result.write_str(" ")?;
1161
0
                        me.start_group("table ")?;
1162
0
                        me.print_idx(&state.core.table_names, table_index)?;
1163
0
                        me.end_group()
1164
0
                    })?;
1165
                }
1166
0
                CanonicalFunction::ThreadSuspendToSuspended { cancellable } => {
1167
0
                    self.print_intrinsic(state, "canon thread.suspend-to-suspended", &|me, _| {
1168
0
                        if cancellable {
1169
0
                            me.result.write_str(" cancellable")?;
1170
0
                        }
1171
0
                        Ok(())
1172
0
                    })?;
1173
                }
1174
0
                CanonicalFunction::ThreadSuspend { cancellable } => {
1175
0
                    self.print_intrinsic(state, "canon thread.suspend", &|me, _| {
1176
0
                        if cancellable {
1177
0
                            me.result.write_str(" cancellable")?;
1178
0
                        }
1179
0
                        Ok(())
1180
0
                    })?;
1181
                }
1182
0
                CanonicalFunction::ThreadSuspendTo { cancellable } => {
1183
0
                    self.print_intrinsic(state, "canon thread.suspend-to", &|me, _| {
1184
0
                        if cancellable {
1185
0
                            me.result.write_str(" cancellable")?;
1186
0
                        }
1187
0
                        Ok(())
1188
0
                    })?;
1189
                }
1190
                CanonicalFunction::ThreadUnsuspend => {
1191
0
                    self.print_intrinsic(state, "canon thread.unsuspend", &|_, _| Ok(()))?;
1192
                }
1193
0
                CanonicalFunction::ThreadYieldToSuspended { cancellable } => {
1194
0
                    self.print_intrinsic(state, "canon thread.yield-to-suspended", &|me, _| {
1195
0
                        if cancellable {
1196
0
                            me.result.write_str(" cancellable")?;
1197
0
                        }
1198
0
                        Ok(())
1199
0
                    })?;
1200
                }
1201
            }
1202
        }
1203
1204
0
        Ok(())
1205
0
    }
1206
1207
0
    pub(crate) fn print_instances(
1208
0
        &mut self,
1209
0
        state: &mut State,
1210
0
        parser: InstanceSectionReader,
1211
0
    ) -> Result<()> {
1212
0
        for instance in parser.into_iter_with_offsets() {
1213
0
            let (offset, instance) = instance?;
1214
0
            self.newline(offset)?;
1215
0
            self.start_group("core instance ")?;
1216
0
            self.print_name(&state.core.instance_names, state.core.instances)?;
1217
0
            match instance {
1218
0
                Instance::Instantiate { module_index, args } => {
1219
0
                    self.result.write_str(" ")?;
1220
0
                    self.start_group("instantiate ")?;
1221
0
                    self.print_idx(&state.core.module_names, module_index)?;
1222
0
                    for arg in args.iter() {
1223
0
                        self.newline(offset)?;
1224
0
                        self.print_instantiation_arg(state, arg)?;
1225
                    }
1226
0
                    self.end_group()?;
1227
0
                    state.core.instances += 1;
1228
                }
1229
0
                Instance::FromExports(exports) => {
1230
0
                    for export in exports.iter() {
1231
0
                        self.newline(offset)?;
1232
0
                        self.print_export(state, export)?;
1233
                    }
1234
0
                    state.core.instances += 1;
1235
                }
1236
            }
1237
0
            self.end_group()?;
1238
        }
1239
0
        Ok(())
1240
0
    }
1241
1242
0
    pub(crate) fn print_component_instances(
1243
0
        &mut self,
1244
0
        state: &mut State,
1245
0
        parser: ComponentInstanceSectionReader,
1246
0
    ) -> Result<()> {
1247
0
        for instance in parser.into_iter_with_offsets() {
1248
0
            let (offset, instance) = instance?;
1249
0
            self.newline(offset)?;
1250
0
            self.start_group("instance ")?;
1251
0
            self.print_name(&state.component.instance_names, state.component.instances)?;
1252
0
            state.component.instances += 1;
1253
0
            match instance {
1254
                ComponentInstance::Instantiate {
1255
0
                    component_index,
1256
0
                    args,
1257
                } => {
1258
0
                    self.result.write_str(" ")?;
1259
0
                    self.start_group("instantiate ")?;
1260
0
                    self.print_idx(&state.component.component_names, component_index)?;
1261
0
                    for arg in args.iter() {
1262
0
                        self.newline(offset)?;
1263
0
                        self.print_component_instantiation_arg(state, arg)?;
1264
                    }
1265
0
                    self.end_group()?;
1266
                }
1267
0
                ComponentInstance::FromExports(exports) => {
1268
0
                    for export in exports.iter() {
1269
0
                        self.newline(offset)?;
1270
0
                        self.print_component_export(state, export, false)?;
1271
                    }
1272
                }
1273
            }
1274
0
            self.end_group()?;
1275
        }
1276
0
        Ok(())
1277
0
    }
1278
1279
0
    pub(crate) fn print_instantiation_arg(
1280
0
        &mut self,
1281
0
        state: &State,
1282
0
        arg: &InstantiationArg,
1283
0
    ) -> Result<()> {
1284
0
        self.start_group("with ")?;
1285
0
        self.print_str(arg.name)?;
1286
0
        self.result.write_str(" ")?;
1287
0
        match arg.kind {
1288
            InstantiationArgKind::Instance => {
1289
0
                self.start_group("instance ")?;
1290
0
                self.print_idx(&state.core.instance_names, arg.index)?;
1291
0
                self.end_group()?;
1292
            }
1293
        }
1294
0
        self.end_group()?;
1295
0
        Ok(())
1296
0
    }
1297
1298
0
    pub(crate) fn print_component_instantiation_arg(
1299
0
        &mut self,
1300
0
        state: &State,
1301
0
        arg: &ComponentInstantiationArg,
1302
0
    ) -> Result<()> {
1303
0
        self.start_group("with ")?;
1304
0
        self.print_str(arg.name)?;
1305
0
        self.result.write_str(" ")?;
1306
0
        self.print_component_external_kind(state, arg.kind, arg.index)?;
1307
0
        self.end_group()?;
1308
0
        Ok(())
1309
0
    }
1310
1311
0
    pub(crate) fn print_component_start(
1312
0
        &mut self,
1313
0
        state: &mut State,
1314
0
        pos: usize,
1315
0
        start: ComponentStartFunction,
1316
0
    ) -> Result<()> {
1317
0
        self.newline(pos)?;
1318
0
        self.start_group("start ")?;
1319
0
        self.print_idx(&state.component.func_names, start.func_index)?;
1320
1321
0
        for arg in start.arguments.iter() {
1322
0
            self.result.write_str(" ")?;
1323
0
            self.start_group("value ")?;
1324
0
            self.print_idx(&state.component.value_names, *arg)?;
1325
0
            self.end_group()?;
1326
        }
1327
1328
0
        for _ in 0..start.results {
1329
0
            self.result.write_str(" ")?;
1330
0
            self.start_group("result ")?;
1331
0
            self.start_group("value ")?;
1332
0
            self.print_name(&state.component.value_names, state.component.values)?;
1333
0
            self.end_group()?;
1334
0
            self.end_group()?;
1335
0
            state.component.values += 1;
1336
        }
1337
1338
0
        self.end_group()?; // start
1339
1340
0
        Ok(())
1341
0
    }
1342
1343
0
    pub(crate) fn print_component_aliases(
1344
0
        &mut self,
1345
0
        states: &mut [State],
1346
0
        parser: ComponentAliasSectionReader,
1347
0
    ) -> Result<()> {
1348
0
        for alias in parser.into_iter_with_offsets() {
1349
0
            let (offset, alias) = alias?;
1350
0
            self.newline(offset)?;
1351
0
            self.print_component_alias(states, alias)?;
1352
        }
1353
0
        Ok(())
1354
0
    }
1355
1356
0
    pub(crate) fn print_component_alias(
1357
0
        &mut self,
1358
0
        states: &mut [State],
1359
0
        alias: ComponentAlias<'_>,
1360
0
    ) -> Result<()> {
1361
0
        match alias {
1362
            ComponentAlias::InstanceExport {
1363
0
                kind,
1364
0
                instance_index,
1365
0
                name,
1366
            } => {
1367
0
                let state = states.last_mut().unwrap();
1368
0
                self.start_group("alias export ")?;
1369
0
                self.print_idx(&state.component.instance_names, instance_index)?;
1370
0
                self.result.write_str(" ")?;
1371
0
                self.print_str(name)?;
1372
0
                self.result.write_str(" ")?;
1373
0
                self.start_component_external_kind_group(kind)?;
1374
0
                self.print_component_kind_name(state, kind)?;
1375
0
                self.end_group()?;
1376
1377
0
                self.end_group()?; // alias export
1378
            }
1379
            ComponentAlias::CoreInstanceExport {
1380
0
                instance_index,
1381
0
                kind,
1382
0
                name,
1383
            } => {
1384
0
                let state = states.last_mut().unwrap();
1385
0
                self.start_group("alias core export ")?;
1386
0
                self.print_idx(&state.core.instance_names, instance_index)?;
1387
0
                self.result.write_str(" ")?;
1388
0
                self.print_str(name)?;
1389
0
                self.result.write_str(" ")?;
1390
0
                match kind {
1391
                    ExternalKind::Func | ExternalKind::FuncExact => {
1392
0
                        self.start_group("core func ")?;
1393
0
                        self.print_name(&state.core.func_names, state.core.funcs)?;
1394
0
                        self.end_group()?;
1395
0
                        debug_assert_eq!(state.core.func_to_type.len(), state.core.funcs as usize);
1396
0
                        state.core.funcs += 1;
1397
0
                        state.core.func_to_type.push(None)
1398
                    }
1399
                    ExternalKind::Table => {
1400
0
                        self.start_group("core table ")?;
1401
0
                        self.print_name(&state.core.table_names, state.core.tables)?;
1402
0
                        self.end_group()?;
1403
0
                        state.core.tables += 1;
1404
                    }
1405
                    ExternalKind::Memory => {
1406
0
                        self.start_group("core memory ")?;
1407
0
                        self.print_name(&state.core.memory_names, state.core.memories)?;
1408
0
                        self.end_group()?;
1409
0
                        state.core.memories += 1;
1410
                    }
1411
                    ExternalKind::Global => {
1412
0
                        self.start_group("core global ")?;
1413
0
                        self.print_name(&state.core.global_names, state.core.globals)?;
1414
0
                        self.end_group()?;
1415
0
                        state.core.globals += 1;
1416
                    }
1417
                    ExternalKind::Tag => {
1418
0
                        self.start_group("core tag ")?;
1419
0
                        self.print_name(&state.core.tag_names, state.core.tags)?;
1420
0
                        self.end_group()?;
1421
0
                        debug_assert_eq!(state.core.tag_to_type.len(), state.core.tags as usize);
1422
0
                        state.core.tags += 1;
1423
0
                        state.core.tag_to_type.push(None)
1424
                    }
1425
                }
1426
0
                self.end_group()?; // alias export
1427
            }
1428
1429
0
            ComponentAlias::Outer { kind, count, index } => {
1430
0
                let state = states.last().unwrap();
1431
0
                let default_state = State::new(Encoding::Component);
1432
0
                let outer = match Self::outer_state(states, count) {
1433
0
                    Ok(o) => o,
1434
0
                    Err(e) => {
1435
0
                        write!(self.result, "(; {e} ;) ")?;
1436
0
                        &default_state
1437
                    }
1438
                };
1439
0
                self.start_group("alias outer ")?;
1440
0
                if let Some(name) = outer.name.as_ref() {
1441
0
                    name.write(self)?;
1442
                } else {
1443
0
                    write!(self.result, "{count}")?;
1444
                }
1445
0
                self.result.write_str(" ")?;
1446
0
                match kind {
1447
                    ComponentOuterAliasKind::CoreModule => {
1448
0
                        self.print_idx(&outer.core.module_names, index)?;
1449
0
                        self.result.write_str(" ")?;
1450
0
                        self.start_group("core module ")?;
1451
0
                        self.print_name(&state.core.module_names, state.core.modules)?;
1452
                    }
1453
                    ComponentOuterAliasKind::CoreType => {
1454
0
                        self.print_idx(&outer.core.type_names, index)?;
1455
0
                        self.result.write_str(" ")?;
1456
0
                        self.start_group("core type ")?;
1457
0
                        self.print_name(&state.core.type_names, state.core.types.len() as u32)?;
1458
                    }
1459
                    ComponentOuterAliasKind::Type => {
1460
0
                        self.print_idx(&outer.component.type_names, index)?;
1461
0
                        self.result.write_str(" ")?;
1462
0
                        self.start_group("type ")?;
1463
0
                        self.print_name(&state.component.type_names, state.component.types)?;
1464
                    }
1465
                    ComponentOuterAliasKind::Component => {
1466
0
                        self.print_idx(&outer.component.component_names, index)?;
1467
0
                        self.result.write_str(" ")?;
1468
0
                        self.start_group("component ")?;
1469
0
                        self.print_name(
1470
0
                            &state.component.component_names,
1471
0
                            state.component.components,
1472
0
                        )?;
1473
                    }
1474
                }
1475
0
                self.end_group()?; // kind
1476
0
                self.end_group()?; // alias
1477
1478
0
                let state = states.last_mut().unwrap();
1479
0
                match kind {
1480
0
                    ComponentOuterAliasKind::CoreModule => state.core.modules += 1,
1481
0
                    ComponentOuterAliasKind::CoreType => state.core.types.push(None),
1482
0
                    ComponentOuterAliasKind::Type => state.component.types += 1,
1483
0
                    ComponentOuterAliasKind::Component => state.component.components += 1,
1484
                }
1485
            }
1486
        }
1487
0
        Ok(())
1488
0
    }
1489
}