use crate::{encode_section, ComponentExport, ComponentSection, ComponentSectionId, Encode};
#[derive(Debug, Clone)]
pub enum ModuleArg {
Instance(u32),
}
impl Encode for ModuleArg {
fn encode(&self, sink: &mut Vec<u8>) {
match self {
Self::Instance(index) => {
sink.push(0x02);
index.encode(sink);
}
}
}
}
#[derive(Debug, Clone)]
pub enum ComponentArg {
Module(u32),
Component(u32),
Instance(u32),
Function(u32),
Value(u32),
Type(u32),
}
impl Encode for ComponentArg {
fn encode(&self, sink: &mut Vec<u8>) {
let (kind, index) = match self {
Self::Module(index) => (0x00, *index),
Self::Component(index) => (0x01, *index),
Self::Instance(index) => (0x02, *index),
Self::Function(index) => (0x03, *index),
Self::Value(index) => (0x04, *index),
Self::Type(index) => (0x05, *index),
};
sink.push(kind);
index.encode(sink);
}
}
#[derive(Clone, Debug, Default)]
pub struct InstanceSection {
bytes: Vec<u8>,
num_added: u32,
}
impl InstanceSection {
pub fn new() -> Self {
Self::default()
}
pub fn len(&self) -> u32 {
self.num_added
}
pub fn is_empty(&self) -> bool {
self.num_added == 0
}
pub fn instantiate_module<'a, Args, Arg>(&mut self, module_index: u32, args: Args) -> &mut Self
where
Args: IntoIterator<Item = (&'a str, Arg)>,
Args::IntoIter: ExactSizeIterator,
Arg: Into<ModuleArg>,
{
let args = args.into_iter();
self.bytes.push(0x00);
self.bytes.push(0x00);
module_index.encode(&mut self.bytes);
args.len().encode(&mut self.bytes);
for (name, arg) in args {
name.encode(&mut self.bytes);
arg.into().encode(&mut self.bytes);
}
self.num_added += 1;
self
}
pub fn export_core_items<'a, Exports, Export>(&mut self, exports: Exports) -> &mut Self
where
Exports: IntoIterator<Item = (&'a str, Export)>,
Exports::IntoIter: ExactSizeIterator,
Export: Into<crate::Export>,
{
let exports = exports.into_iter();
self.bytes.push(0x02);
exports.len().encode(&mut self.bytes);
for (name, export) in exports {
name.encode(&mut self.bytes);
export.into().encode(&mut self.bytes);
}
self.num_added += 1;
self
}
pub fn instantiate_component<'a, Args, Arg>(
&mut self,
component_index: u32,
args: Args,
) -> &mut Self
where
Args: IntoIterator<Item = (&'a str, Arg)>,
Args::IntoIter: ExactSizeIterator,
Arg: Into<ComponentArg>,
{
let args = args.into_iter();
self.bytes.push(0x00);
self.bytes.push(0x01);
component_index.encode(&mut self.bytes);
args.len().encode(&mut self.bytes);
for (name, arg) in args {
name.encode(&mut self.bytes);
arg.into().encode(&mut self.bytes);
}
self.num_added += 1;
self
}
pub fn export_items<'a, Exports, Export>(&mut self, exports: Exports) -> &mut Self
where
Exports: IntoIterator<Item = (&'a str, Export)>,
Exports::IntoIter: ExactSizeIterator,
Export: Into<ComponentExport>,
{
let exports = exports.into_iter();
self.bytes.push(0x01);
exports.len().encode(&mut self.bytes);
for (name, export) in exports {
name.encode(&mut self.bytes);
export.into().encode(&mut self.bytes);
}
self.num_added += 1;
self
}
}
impl Encode for InstanceSection {
fn encode(&self, sink: &mut Vec<u8>) {
encode_section(
sink,
ComponentSectionId::Instance,
self.num_added,
&self.bytes,
);
}
}
impl ComponentSection for InstanceSection {}