summaryrefslogtreecommitdiffstats
path: root/third_party/rust/wasm-encoder/src/component/aliases.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/wasm-encoder/src/component/aliases.rs')
-rw-r--r--third_party/rust/wasm-encoder/src/component/aliases.rs160
1 files changed, 160 insertions, 0 deletions
diff --git a/third_party/rust/wasm-encoder/src/component/aliases.rs b/third_party/rust/wasm-encoder/src/component/aliases.rs
new file mode 100644
index 0000000000..1e317fb0e2
--- /dev/null
+++ b/third_party/rust/wasm-encoder/src/component/aliases.rs
@@ -0,0 +1,160 @@
+use super::{COMPONENT_SORT, CORE_MODULE_SORT, CORE_SORT, CORE_TYPE_SORT, TYPE_SORT};
+use crate::{
+ encode_section, ComponentExportKind, ComponentSection, ComponentSectionId, Encode, ExportKind,
+};
+
+/// Represents the kinds of outer aliasable items in a component.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum ComponentOuterAliasKind {
+ /// The alias is to a core module.
+ CoreModule,
+ /// The alias is to a core type.
+ CoreType,
+ /// The alias is to a type.
+ Type,
+ /// The alias is to a component.
+ Component,
+}
+
+impl Encode for ComponentOuterAliasKind {
+ fn encode(&self, sink: &mut Vec<u8>) {
+ match self {
+ Self::CoreModule => {
+ sink.push(CORE_SORT);
+ sink.push(CORE_MODULE_SORT);
+ }
+ Self::CoreType => {
+ sink.push(CORE_SORT);
+ sink.push(CORE_TYPE_SORT);
+ }
+ Self::Type => sink.push(TYPE_SORT),
+ Self::Component => sink.push(COMPONENT_SORT),
+ }
+ }
+}
+
+/// An encoder for the alias section of WebAssembly component.
+///
+/// # Example
+///
+/// ```rust
+/// use wasm_encoder::{Component, Alias, ComponentAliasSection, ComponentExportKind, ComponentOuterAliasKind};
+///
+/// let mut aliases = ComponentAliasSection::new();
+/// aliases.alias(Alias::InstanceExport { instance: 0, kind: ComponentExportKind::Func, name: "f" });
+/// aliases.alias(Alias::Outer { count: 0, kind: ComponentOuterAliasKind::Type, index: 1 });
+///
+/// let mut component = Component::new();
+/// component.section(&aliases);
+///
+/// let bytes = component.finish();
+/// ```
+#[derive(Clone, Debug, Default)]
+pub struct ComponentAliasSection {
+ bytes: Vec<u8>,
+ num_added: u32,
+}
+
+/// Different forms of aliases that can be inserted into a
+/// [`ComponentAliasSection`].
+#[derive(Copy, Clone, Debug)]
+pub enum Alias<'a> {
+ /// An alias of a component instance export.
+ InstanceExport {
+ /// The index of the component instance that's being aliased from.
+ instance: u32,
+ /// The kind of item that's being extracted from the component
+ /// instance.
+ kind: ComponentExportKind,
+ /// The name of the export that's being aliased.
+ name: &'a str,
+ },
+ /// Same as `InstanceExport`, but for core instances.
+ #[allow(missing_docs)]
+ CoreInstanceExport {
+ instance: u32,
+ kind: ExportKind,
+ name: &'a str,
+ },
+ /// Aliasing an item from an outer component.
+ Outer {
+ /// The kind of item being aliased, either a type or a component.
+ kind: ComponentOuterAliasKind,
+ /// Number of levels "up" to go to lookup the index within. Level 0 is
+ /// the current scope and level 1 is the enclosing scope, and so on.
+ count: u32,
+ /// The index of the item to alias within the scope referenced by
+ /// `count`.
+ index: u32,
+ },
+}
+
+impl ComponentAliasSection {
+ /// Create a new alias section encoder.
+ pub fn new() -> Self {
+ Self::default()
+ }
+
+ /// The number of aliases in the section.
+ pub fn len(&self) -> u32 {
+ self.num_added
+ }
+
+ /// Determines if the section is empty.
+ pub fn is_empty(&self) -> bool {
+ self.num_added == 0
+ }
+
+ /// Define an alias to a component instance's export.
+ pub fn alias(&mut self, alias: Alias<'_>) -> &mut Self {
+ alias.encode(&mut self.bytes);
+ self.num_added += 1;
+ self
+ }
+}
+
+impl Encode for ComponentAliasSection {
+ fn encode(&self, sink: &mut Vec<u8>) {
+ encode_section(sink, self.num_added, &self.bytes);
+ }
+}
+
+impl ComponentSection for ComponentAliasSection {
+ fn id(&self) -> u8 {
+ ComponentSectionId::Alias.into()
+ }
+}
+
+impl Encode for Alias<'_> {
+ fn encode(&self, sink: &mut Vec<u8>) {
+ match self {
+ Alias::InstanceExport {
+ instance,
+ kind,
+ name,
+ } => {
+ kind.encode(sink);
+ sink.push(0x00);
+ instance.encode(sink);
+ name.encode(sink);
+ }
+ Alias::CoreInstanceExport {
+ instance,
+ kind,
+ name,
+ } => {
+ sink.push(CORE_SORT);
+ kind.encode(sink);
+ sink.push(0x01);
+ instance.encode(sink);
+ name.encode(sink);
+ }
+ Alias::Outer { kind, count, index } => {
+ kind.encode(sink);
+ sink.push(0x02);
+ count.encode(sink);
+ index.encode(sink);
+ }
+ }
+ }
+}