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 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
use crate::limits::{MAX_WASM_INSTANTIATION_ARGS, MAX_WASM_INSTANTIATION_EXPORTS};
use crate::prelude::*;
use crate::{
BinaryReader, ComponentExport, ComponentExternalKind, Export, FromReader, Result,
SectionLimited,
};
/// Represents the kind of an instantiation argument for a core instance.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum InstantiationArgKind {
/// The instantiation argument is a core instance.
Instance,
}
/// Represents an argument to instantiating a WebAssembly module.
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct InstantiationArg<'a> {
/// The name of the module argument.
pub name: &'a str,
/// The kind of the module argument.
pub kind: InstantiationArgKind,
/// The index of the argument item.
pub index: u32,
}
/// Represents an instance of a WebAssembly module.
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Instance<'a> {
/// The instance is from instantiating a WebAssembly module.
Instantiate {
/// The module index.
module_index: u32,
/// The module's instantiation arguments.
args: Box<[InstantiationArg<'a>]>,
},
/// The instance is a from exporting local items.
FromExports(Box<[Export<'a>]>),
}
/// A reader for the core instance section of a WebAssembly component.
///
/// # Examples
///
/// ```
/// use wasmparser::{InstanceSectionReader, BinaryReader};
/// # let data: &[u8] = &[0x01, 0x00, 0x00, 0x01, 0x03, b'f', b'o', b'o', 0x12, 0x00];
/// let reader = BinaryReader::new(data, 0);
/// let mut reader = InstanceSectionReader::new(reader).unwrap();
/// for inst in reader {
/// println!("Instance {:?}", inst.expect("instance"));
/// }
/// ```
pub type InstanceSectionReader<'a> = SectionLimited<'a, Instance<'a>>;
impl<'a> FromReader<'a> for Instance<'a> {
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
Ok(match reader.read_u8()? {
0x00 => Instance::Instantiate {
module_index: reader.read_var_u32()?,
args: reader
.read_iter(MAX_WASM_INSTANTIATION_ARGS, "core instantiation arguments")?
.collect::<Result<_>>()?,
},
0x01 => Instance::FromExports(
reader
.read_iter(MAX_WASM_INSTANTIATION_ARGS, "core instantiation arguments")?
.collect::<Result<_>>()?,
),
x => return reader.invalid_leading_byte(x, "core instance"),
})
}
}
impl<'a> FromReader<'a> for InstantiationArg<'a> {
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
Ok(InstantiationArg {
name: reader.read()?,
kind: reader.read()?,
index: reader.read()?,
})
}
}
impl<'a> FromReader<'a> for InstantiationArgKind {
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
Ok(match reader.read_u8()? {
0x12 => InstantiationArgKind::Instance,
x => return reader.invalid_leading_byte(x, "instantiation arg kind"),
})
}
}
/// Represents an argument to instantiating a WebAssembly component.
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ComponentInstantiationArg<'a> {
/// The name of the component argument.
pub name: &'a str,
/// The kind of the component argument.
pub kind: ComponentExternalKind,
/// The index of the argument item.
pub index: u32,
}
/// Represents an instance in a WebAssembly component.
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum ComponentInstance<'a> {
/// The instance is from instantiating a WebAssembly component.
Instantiate {
/// The component index.
component_index: u32,
/// The component's instantiation arguments.
args: Box<[ComponentInstantiationArg<'a>]>,
},
/// The instance is a from exporting local items.
FromExports(Box<[ComponentExport<'a>]>),
}
/// A reader for the component instance section of a WebAssembly component.
///
/// # Examples
///
/// ```
/// use wasmparser::{ComponentInstanceSectionReader, BinaryReader};
/// # let data: &[u8] = &[0x01, 0x00, 0x00, 0x01, 0x03, b'f', b'o', b'o', 0x01, 0x00];
/// let reader = BinaryReader::new(data, 0);
/// let mut reader = ComponentInstanceSectionReader::new(reader).unwrap();
/// for inst in reader {
/// println!("Instance {:?}", inst.expect("instance"));
/// }
/// ```
pub type ComponentInstanceSectionReader<'a> = SectionLimited<'a, ComponentInstance<'a>>;
impl<'a> FromReader<'a> for ComponentInstance<'a> {
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
Ok(match reader.read_u8()? {
0x00 => ComponentInstance::Instantiate {
component_index: reader.read_var_u32()?,
args: reader
.read_iter(MAX_WASM_INSTANTIATION_ARGS, "instantiation arguments")?
.collect::<Result<_>>()?,
},
0x01 => ComponentInstance::FromExports(
(0..reader.read_size(MAX_WASM_INSTANTIATION_EXPORTS, "instantiation exports")?)
.map(|_| {
Ok(ComponentExport {
name: reader.read()?,
kind: reader.read()?,
index: reader.read()?,
ty: None,
})
})
.collect::<Result<_>>()?,
),
x => return reader.invalid_leading_byte(x, "instance"),
})
}
}
impl<'a> FromReader<'a> for ComponentInstantiationArg<'a> {
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
Ok(ComponentInstantiationArg {
name: reader.read()?,
kind: reader.read()?,
index: reader.read()?,
})
}
}