use super::*;
use std::convert::TryFrom;
#[derive(Clone, Debug)]
pub struct ImportSection {
bytes: Vec<u8>,
num_added: u32,
}
impl ImportSection {
pub fn new() -> ImportSection {
ImportSection {
bytes: vec![],
num_added: 0,
}
}
pub fn len(&self) -> u32 {
self.num_added
}
pub fn import(
&mut self,
module: &str,
name: Option<&str>,
ty: impl Into<EntityType>,
) -> &mut Self {
self.bytes.extend(encoders::str(module));
match name {
Some(name) => self.bytes.extend(encoders::str(name)),
None => {
self.bytes.push(0x00);
self.bytes.push(0xff);
}
}
ty.into().encode(&mut self.bytes);
self.num_added += 1;
self
}
}
impl Section for ImportSection {
fn id(&self) -> u8 {
SectionId::Import.into()
}
fn encode<S>(&self, sink: &mut S)
where
S: Extend<u8>,
{
let num_added = encoders::u32(self.num_added);
let n = num_added.len();
sink.extend(
encoders::u32(u32::try_from(n + self.bytes.len()).unwrap())
.chain(num_added)
.chain(self.bytes.iter().copied()),
);
}
}
#[derive(Clone, Copy, Debug)]
pub enum EntityType {
Function(u32),
Table(TableType),
Memory(MemoryType),
Global(GlobalType),
Instance(u32),
Module(u32),
}
impl From<TableType> for EntityType {
fn from(t: TableType) -> Self {
EntityType::Table(t)
}
}
impl From<MemoryType> for EntityType {
fn from(m: MemoryType) -> Self {
EntityType::Memory(m)
}
}
impl From<GlobalType> for EntityType {
fn from(g: GlobalType) -> Self {
EntityType::Global(g)
}
}
impl EntityType {
pub(crate) fn encode(&self, dst: &mut Vec<u8>) {
match self {
EntityType::Function(x) => {
dst.push(0x00);
dst.extend(encoders::u32(*x));
}
EntityType::Table(ty) => {
dst.push(0x01);
ty.encode(dst);
}
EntityType::Memory(ty) => {
dst.push(0x02);
ty.encode(dst);
}
EntityType::Global(ty) => {
dst.push(0x03);
ty.encode(dst);
}
EntityType::Module(ty) => {
dst.push(0x05);
dst.extend(encoders::u32(*ty));
}
EntityType::Instance(ty) => {
dst.push(0x06);
dst.extend(encoders::u32(*ty));
}
}
}
}