1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
use crate::{
BinaryReader, ComponentExternalKind, ComponentValType, FromReader, Result, SectionLimited,
};
/// Represents the type bounds for imports and exports.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum TypeBounds {
/// The type is bounded by equality.
Eq(u32),
/// A fresh resource type,
SubResource,
}
impl<'a> FromReader<'a> for TypeBounds {
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
Ok(match reader.read_u8()? {
0x00 => TypeBounds::Eq(reader.read()?),
0x01 => TypeBounds::SubResource,
x => return reader.invalid_leading_byte(x, "type bound"),
})
}
}
/// Represents a reference to a component type.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ComponentTypeRef {
/// The reference is to a core module type.
///
/// The index is expected to be core type index to a core module type.
Module(u32),
/// The reference is to a function type.
///
/// The index is expected to be a type index to a function type.
Func(u32),
/// The reference is to a value type.
Value(ComponentValType),
/// The reference is to a bounded type.
///
/// The index is expected to be a type index.
Type(TypeBounds),
/// The reference is to an instance type.
///
/// The index is a type index to an instance type.
Instance(u32),
/// The reference is to a component type.
///
/// The index is a type index to a component type.
Component(u32),
}
impl ComponentTypeRef {
/// Returns the corresponding [`ComponentExternalKind`] for this reference.
pub fn kind(&self) -> ComponentExternalKind {
match self {
ComponentTypeRef::Module(_) => ComponentExternalKind::Module,
ComponentTypeRef::Func(_) => ComponentExternalKind::Func,
ComponentTypeRef::Value(_) => ComponentExternalKind::Value,
ComponentTypeRef::Type(..) => ComponentExternalKind::Type,
ComponentTypeRef::Instance(_) => ComponentExternalKind::Instance,
ComponentTypeRef::Component(_) => ComponentExternalKind::Component,
}
}
}
impl<'a> FromReader<'a> for ComponentTypeRef {
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
Ok(match reader.read()? {
ComponentExternalKind::Module => ComponentTypeRef::Module(reader.read()?),
ComponentExternalKind::Func => ComponentTypeRef::Func(reader.read()?),
ComponentExternalKind::Value => ComponentTypeRef::Value(reader.read()?),
ComponentExternalKind::Type => ComponentTypeRef::Type(reader.read()?),
ComponentExternalKind::Instance => ComponentTypeRef::Instance(reader.read()?),
ComponentExternalKind::Component => ComponentTypeRef::Component(reader.read()?),
})
}
}
/// Represents an import in a WebAssembly component
#[derive(Debug, Copy, Clone)]
pub struct ComponentImport<'a> {
/// The name of the imported item.
pub name: ComponentImportName<'a>,
/// The type reference for the import.
pub ty: ComponentTypeRef,
}
impl<'a> FromReader<'a> for ComponentImport<'a> {
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
Ok(ComponentImport {
name: reader.read()?,
ty: reader.read()?,
})
}
}
/// A reader for the import section of a WebAssembly component.
///
/// # Examples
///
/// ```
/// use wasmparser::ComponentImportSectionReader;
/// let data: &[u8] = &[0x01, 0x00, 0x01, 0x41, 0x01, 0x66];
/// let reader = ComponentImportSectionReader::new(data, 0).unwrap();
/// for import in reader {
/// let import = import.expect("import");
/// println!("Import: {:?}", import);
/// }
/// ```
pub type ComponentImportSectionReader<'a> = SectionLimited<'a, ComponentImport<'a>>;
/// Represents the name of a component import.
#[derive(Debug, Copy, Clone)]
#[allow(missing_docs)]
pub struct ComponentImportName<'a>(pub &'a str);
impl<'a> FromReader<'a> for ComponentImportName<'a> {
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
match reader.read_u8()? {
0x00 => {}
// Historically export names used a discriminator byte of 0x01 to
// indicate an "interface" of the form `a:b/c` but nowadays that's
// inferred from string syntax. Ignore 0-vs-1 to continue to parse
// older binaries. Eventually this will go away.
0x01 => {}
x => return reader.invalid_leading_byte(x, "import name"),
}
Ok(ComponentImportName(reader.read_string()?))
}
}