wasm_encoder/component/
aliases.rs

1use super::{COMPONENT_SORT, CORE_MODULE_SORT, CORE_SORT, CORE_TYPE_SORT, TYPE_SORT};
2use crate::{
3    encode_section, ComponentExportKind, ComponentSection, ComponentSectionId, Encode, ExportKind,
4};
5use alloc::vec::Vec;
6
7/// Represents the kinds of outer aliasable items in a component.
8#[derive(Clone, Copy, Debug, Eq, PartialEq)]
9pub 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
20impl Encode for ComponentOuterAliasKind {
21    fn encode(&self, sink: &mut Vec<u8>) {
22        match self {
23            Self::CoreModule => {
24                sink.push(CORE_SORT);
25                sink.push(CORE_MODULE_SORT);
26            }
27            Self::CoreType => {
28                sink.push(CORE_SORT);
29                sink.push(CORE_TYPE_SORT);
30            }
31            Self::Type => sink.push(TYPE_SORT),
32            Self::Component => sink.push(COMPONENT_SORT),
33        }
34    }
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)]
54pub 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)]
62pub 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
93impl ComponentAliasSection {
94    /// Create a new alias section encoder.
95    pub fn new() -> Self {
96        Self::default()
97    }
98
99    /// The number of aliases in the section.
100    pub fn len(&self) -> u32 {
101        self.num_added
102    }
103
104    /// Determines if the section is empty.
105    pub fn is_empty(&self) -> bool {
106        self.num_added == 0
107    }
108
109    /// Define an alias to a component instance's export.
110    pub fn alias(&mut self, alias: Alias<'_>) -> &mut Self {
111        alias.encode(&mut self.bytes);
112        self.num_added += 1;
113        self
114    }
115}
116
117impl Encode for ComponentAliasSection {
118    fn encode(&self, sink: &mut Vec<u8>) {
119        encode_section(sink, self.num_added, &self.bytes);
120    }
121}
122
123impl ComponentSection for ComponentAliasSection {
124    fn id(&self) -> u8 {
125        ComponentSectionId::Alias.into()
126    }
127}
128
129impl Encode for Alias<'_> {
130    fn encode(&self, sink: &mut Vec<u8>) {
131        match self {
132            Alias::InstanceExport {
133                instance,
134                kind,
135                name,
136            } => {
137                kind.encode(sink);
138                sink.push(0x00);
139                instance.encode(sink);
140                name.encode(sink);
141            }
142            Alias::CoreInstanceExport {
143                instance,
144                kind,
145                name,
146            } => {
147                sink.push(CORE_SORT);
148                kind.encode(sink);
149                sink.push(0x01);
150                instance.encode(sink);
151                name.encode(sink);
152            }
153            Alias::Outer { kind, count, index } => {
154                kind.encode(sink);
155                sink.push(0x02);
156                count.encode(sink);
157                index.encode(sink);
158            }
159        }
160    }
161}