Coverage Report

Created: 2026-10-12 08:10

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