use crate::ir::id::{ExportsID, FunctionID};
use wasmparser::ExternalKind;
#[derive(Debug, Clone)]
pub struct Export {
pub name: String,
pub kind: ExternalKind,
pub index: u32,
pub(crate) deleted: bool,
}
impl<'a> From<wasmparser::Export<'a>> for Export {
fn from(export: wasmparser::Export<'a>) -> Self {
Export {
name: export.name.to_string(),
kind: export.kind,
index: export.index,
deleted: false,
}
}
}
#[derive(Clone, Debug, Default)]
pub struct ModuleExports {
exports: Vec<Export>,
}
impl ModuleExports {
pub fn new(exports: Vec<Export>) -> Self {
ModuleExports { exports }
}
pub fn iter(&self) -> std::slice::Iter<'_, Export> {
self.exports.iter()
}
pub fn is_empty(&self) -> bool {
self.exports.is_empty()
}
pub fn add_export_func(&mut self, name: String, exp_id: u32) {
let export = Export {
name,
kind: ExternalKind::Func,
index: exp_id,
deleted: false,
};
self.exports.push(export);
}
pub fn get_by_name(&self, name: String) -> Option<Export> {
for exp in self.exports.iter() {
if exp.name == name {
return Some(exp.clone());
}
}
None
}
pub fn get_export_id_by_name(&self, name: String) -> Option<ExportsID> {
for (idx, exp) in self.exports.iter().enumerate() {
if exp.name == name {
return Some(ExportsID(idx as u32));
}
}
None
}
pub fn get_by_id(&self, id: ExportsID) -> Option<Export> {
if *id < self.exports.len() as u32 {
Some(self.exports[*id as usize].clone())
} else {
None
}
}
pub fn get_func_by_id(&self, id: FunctionID) -> Option<ExportsID> {
for (export_id, exp) in self.exports.iter().enumerate() {
if matches!(exp.kind, ExternalKind::Func) && exp.index == *id {
return Some(ExportsID(export_id as u32));
}
}
None
}
pub fn get_func_by_name(&self, name: String) -> Option<FunctionID> {
for exp in self.exports.iter() {
if matches!(exp.kind, ExternalKind::Func) && exp.name == name {
return Some(FunctionID(exp.index));
}
}
None
}
pub fn delete(&mut self, id: ExportsID) {
self.exports[*id as usize].deleted = true;
}
}