Coverage Report

Created: 2026-04-09 08:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wasm-tools/crates/wasm-encoder/src/component/aliases.rs
Line
Count
Source
1
use super::{COMPONENT_SORT, CORE_MODULE_SORT, CORE_SORT, CORE_TYPE_SORT, TYPE_SORT};
2
use crate::{
3
    ComponentExportKind, ComponentSection, ComponentSectionId, Encode, ExportKind, encode_section,
4
};
5
use alloc::vec::Vec;
6
7
/// Represents the kinds of outer aliasable items in a component.
8
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
9
pub enum ComponentOuterAliasKind {
10
    /// The alias is to a core module.
11
    CoreModule,
12
    /// The alias is to a core type.
13
    CoreType,
14
    /// The alias is to a type.
15
    Type,
16
    /// The alias is to a component.
17
    Component,
18
}
19
20
impl Encode for ComponentOuterAliasKind {
21
7.18k
    fn encode(&self, sink: &mut Vec<u8>) {
22
7.18k
        match self {
23
0
            Self::CoreModule => {
24
0
                sink.push(CORE_SORT);
25
0
                sink.push(CORE_MODULE_SORT);
26
0
            }
27
0
            Self::CoreType => {
28
0
                sink.push(CORE_SORT);
29
0
                sink.push(CORE_TYPE_SORT);
30
0
            }
31
7.18k
            Self::Type => sink.push(TYPE_SORT),
32
0
            Self::Component => sink.push(COMPONENT_SORT),
33
        }
34
7.18k
    }
35
}
36
37
/// An encoder for the alias section of WebAssembly component.
38
///
39
/// # Example
40
///
41
/// ```rust
42
/// use wasm_encoder::{Component, Alias, ComponentAliasSection, ComponentExportKind, ComponentOuterAliasKind};
43
///
44
/// let mut aliases = ComponentAliasSection::new();
45
/// aliases.alias(Alias::InstanceExport { instance: 0, kind: ComponentExportKind::Func, name: "f" });
46
/// aliases.alias(Alias::Outer { count: 0, kind: ComponentOuterAliasKind::Type, index: 1 });
47
///
48
/// let mut component = Component::new();
49
/// component.section(&aliases);
50
///
51
/// let bytes = component.finish();
52
/// ```
53
#[derive(Clone, Debug, Default)]
54
pub struct ComponentAliasSection {
55
    bytes: Vec<u8>,
56
    num_added: u32,
57
}
58
59
/// Different forms of aliases that can be inserted into a
60
/// [`ComponentAliasSection`].
61
#[derive(Copy, Clone, Debug)]
62
pub enum Alias<'a> {
63
    /// An alias of a component instance export.
64
    InstanceExport {
65
        /// The index of the component instance that's being aliased from.
66
        instance: u32,
67
        /// The kind of item that's being extracted from the component
68
        /// instance.
69
        kind: ComponentExportKind,
70
        /// The name of the export that's being aliased.
71
        name: &'a str,
72
    },
73
    /// Same as `InstanceExport`, but for core instances.
74
    #[allow(missing_docs)]
75
    CoreInstanceExport {
76
        instance: u32,
77
        kind: ExportKind,
78
        name: &'a str,
79
    },
80
    /// Aliasing an item from an outer component.
81
    Outer {
82
        /// The kind of item being aliased, either a type or a component.
83
        kind: ComponentOuterAliasKind,
84
        /// Number of levels "up" to go to lookup the index within. Level 0 is
85
        /// the current scope and level 1 is the enclosing scope, and so on.
86
        count: u32,
87
        /// The index of the item to alias within the scope referenced by
88
        /// `count`.
89
        index: u32,
90
    },
91
}
92
93
impl ComponentAliasSection {
94
    /// Create a new alias section encoder.
95
8.07k
    pub fn new() -> Self {
96
8.07k
        Self::default()
97
8.07k
    }
98
99
    /// The number of aliases in the section.
100
0
    pub fn len(&self) -> u32 {
101
0
        self.num_added
102
0
    }
103
104
    /// Determines if the section is empty.
105
0
    pub fn is_empty(&self) -> bool {
106
0
        self.num_added == 0
107
0
    }
108
109
    /// Define an alias to a component instance's export.
110
14.7k
    pub fn alias(&mut self, alias: Alias<'_>) -> &mut Self {
111
14.7k
        alias.encode(&mut self.bytes);
112
14.7k
        self.num_added += 1;
113
14.7k
        self
114
14.7k
    }
115
}
116
117
impl Encode for ComponentAliasSection {
118
8.07k
    fn encode(&self, sink: &mut Vec<u8>) {
119
8.07k
        encode_section(sink, self.num_added, &self.bytes);
120
8.07k
    }
121
}
122
123
impl ComponentSection for ComponentAliasSection {
124
8.07k
    fn id(&self) -> u8 {
125
8.07k
        ComponentSectionId::Alias.into()
126
8.07k
    }
127
}
128
129
impl Encode for Alias<'_> {
130
29.5k
    fn encode(&self, sink: &mut Vec<u8>) {
131
29.5k
        match self {
132
            Alias::InstanceExport {
133
8.90k
                instance,
134
8.90k
                kind,
135
8.90k
                name,
136
8.90k
            } => {
137
8.90k
                kind.encode(sink);
138
8.90k
                sink.push(0x00);
139
8.90k
                instance.encode(sink);
140
8.90k
                name.encode(sink);
141
8.90k
            }
142
            Alias::CoreInstanceExport {
143
13.4k
                instance,
144
13.4k
                kind,
145
13.4k
                name,
146
13.4k
            } => {
147
13.4k
                sink.push(CORE_SORT);
148
13.4k
                kind.encode(sink);
149
13.4k
                sink.push(0x01);
150
13.4k
                instance.encode(sink);
151
13.4k
                name.encode(sink);
152
13.4k
            }
153
7.18k
            Alias::Outer { kind, count, index } => {
154
7.18k
                kind.encode(sink);
155
7.18k
                sink.push(0x02);
156
7.18k
                count.encode(sink);
157
7.18k
                index.encode(sink);
158
7.18k
            }
159
        }
160
29.5k
    }
161
}