use crate::ir::component::idx_spaces::Space;
use crate::ir::component::refs::{IndexedRef, RefKind};
use crate::ir::component::visitor::driver::{drive_event, VisitEvent};
use crate::ir::component::visitor::events_structural::get_structural_events;
use crate::ir::component::visitor::events_topological::get_topological_events;
use crate::ir::component::visitor::utils::VisitCtxInner;
use crate::ir::types::CustomSection;
use crate::{Component, Module};
use wasmparser::{
CanonicalFunction, ComponentAlias, ComponentExport, ComponentImport, ComponentInstance,
ComponentStartFunction, ComponentType, ComponentTypeDeclaration, CoreType, Instance,
InstanceTypeDeclaration, ModuleTypeDeclaration, SubType,
};
pub(crate) mod driver;
mod events_structural;
pub(crate) mod events_topological;
#[cfg(test)]
mod tests;
pub(crate) mod utils;
pub fn walk_structural<'ir, V: ComponentVisitor<'ir>>(root: &'ir Component<'ir>, visitor: &mut V) {
walk(get_structural_events, root, visitor);
}
pub fn walk_topological<'ir, V: ComponentVisitor<'ir>>(root: &'ir Component<'ir>, visitor: &mut V) {
walk(get_topological_events, root, visitor);
}
fn walk<'ir, V: ComponentVisitor<'ir>>(
get_evts: fn(&'ir Component<'ir>, &mut VisitCtx<'ir>, &mut Vec<VisitEvent<'ir>>),
root: &'ir Component<'ir>,
visitor: &mut V,
) {
let mut ctx = VisitCtx::new(root);
let mut events = Vec::new();
get_evts(root, &mut ctx, &mut events);
for event in events.iter() {
drive_event(event, visitor, &mut ctx);
}
}
pub trait ComponentVisitor<'a> {
fn enter_root_component(&mut self, _cx: &VisitCtx<'a>, _component: &Component<'a>) {}
fn exit_root_component(&mut self, _cx: &VisitCtx<'a>, _component: &Component<'a>) {}
fn enter_component(&mut self, _cx: &VisitCtx<'a>, _id: u32, _component: &Component<'a>) {}
fn exit_component(&mut self, _cx: &VisitCtx<'a>, _id: u32, _component: &Component<'a>) {}
fn visit_module(&mut self, _cx: &VisitCtx<'a>, _id: u32, _module: &Module<'a>) {}
fn enter_comp_type(&mut self, _cx: &VisitCtx<'a>, _id: u32, _comp_type: &ComponentType<'a>) {}
fn visit_comp_type_decl(
&mut self,
_cx: &VisitCtx<'a>,
_decl_idx: usize,
_id: u32,
_parent: &ComponentType<'a>,
_decl: &ComponentTypeDeclaration<'a>,
) {
}
fn visit_inst_type_decl(
&mut self,
_cx: &VisitCtx<'a>,
_decl_idx: usize,
_id: u32,
_parent: &ComponentType<'a>,
_decl: &InstanceTypeDeclaration<'a>,
) {
}
fn exit_comp_type(&mut self, _cx: &VisitCtx<'a>, _id: u32, _comp_type: &ComponentType<'a>) {}
fn visit_comp_instance(
&mut self,
_cx: &VisitCtx<'a>,
_id: u32,
_instance: &ComponentInstance<'a>,
) {
}
fn visit_canon(
&mut self,
_cx: &VisitCtx<'a>,
_kind: ItemKind,
_id: u32,
_canon: &CanonicalFunction,
) {
}
fn visit_alias(
&mut self,
_cx: &VisitCtx<'a>,
_kind: ItemKind,
_id: u32,
_alias: &ComponentAlias<'a>,
) {
}
fn visit_comp_import(
&mut self,
_cx: &VisitCtx<'a>,
_kind: ItemKind,
_id: u32,
_import: &ComponentImport<'a>,
) {
}
fn visit_comp_export(
&mut self,
_cx: &VisitCtx<'a>,
_kind: ItemKind,
_id: u32,
_export: &ComponentExport<'a>,
) {
}
fn enter_core_rec_group(
&mut self,
_cx: &VisitCtx<'a>,
_count: usize,
_core_type: &CoreType<'a>,
) {
}
fn visit_core_subtype(&mut self, _cx: &VisitCtx<'a>, _id: u32, _subtype: &SubType) {}
fn exit_core_rec_group(&mut self, _cx: &VisitCtx<'a>) {}
fn enter_core_type(&mut self, _cx: &VisitCtx<'a>, _id: u32, _core_type: &CoreType<'a>) {}
fn visit_module_type_decl(
&mut self,
_cx: &VisitCtx<'a>,
_decl_idx: usize,
_id: u32,
_parent: &CoreType<'a>,
_decl: &ModuleTypeDeclaration<'a>,
) {
}
fn exit_core_type(&mut self, _cx: &VisitCtx<'a>, _id: u32, _core_type: &CoreType<'a>) {}
fn visit_core_instance(&mut self, _cx: &VisitCtx<'a>, _id: u32, _inst: &Instance<'a>) {}
fn visit_custom_section(&mut self, _cx: &VisitCtx<'a>, _sect: &CustomSection<'a>) {}
fn visit_start_section(&mut self, _cx: &VisitCtx<'a>, _start: &ComponentStartFunction) {}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ItemKind {
Comp,
CompFunc,
CompVal,
CompType,
CompInst,
CoreInst,
CoreModule,
CoreType,
CoreFunc,
CoreMemory,
CoreTable,
CoreGlobal,
CoreTag,
NA,
}
impl From<Space> for ItemKind {
fn from(space: Space) -> Self {
match space {
Space::Comp => Self::Comp,
Space::CompFunc => Self::CompFunc,
Space::CompVal => Self::CompVal,
Space::CompType => Self::CompType,
Space::CompInst => Self::CompInst,
Space::CoreInst => Self::CoreInst,
Space::CoreModule => Self::CoreModule,
Space::CoreType => Self::CoreType,
Space::CoreFunc => Self::CoreFunc,
Space::CoreMemory => Self::CoreMemory,
Space::CoreTable => Self::CoreTable,
Space::CoreGlobal => Self::CoreGlobal,
Space::CoreTag => Self::CoreTag,
Space::NA => Self::NA,
}
}
}
pub struct VisitCtx<'a> {
pub(crate) inner: VisitCtxInner<'a>,
}
impl<'a> VisitCtx<'a> {
pub(crate) fn new(component: &'a Component<'a>) -> Self {
Self {
inner: VisitCtxInner::new(component),
}
}
pub fn resolve(&self, ref_: &IndexedRef) -> ResolvedItem<'_, '_> {
self.inner.resolve(ref_)
}
pub fn resolve_all(&self, refs: &[RefKind]) -> Vec<ResolvedItem<'_, '_>> {
self.inner.resolve_all(refs)
}
pub fn lookup_root_comp_name(&self) -> Option<&str> {
self.inner.lookup_root_comp_name()
}
pub fn lookup_comp_name(&self, id: u32) -> Option<&str> {
self.inner.lookup_comp_name(id)
}
pub fn lookup_comp_inst_name(&self, id: u32) -> Option<&str> {
self.inner.lookup_comp_inst_name(id)
}
pub fn lookup_comp_type_name(&self, id: u32) -> Option<&str> {
self.inner.lookup_comp_type_name(id)
}
pub fn lookup_comp_func_name(&self, id: u32) -> Option<&str> {
self.inner.lookup_comp_func_name(id)
}
pub fn lookup_module_name(&self, id: u32) -> Option<&str> {
self.inner.lookup_module_name(id)
}
pub fn lookup_core_inst_name(&self, id: u32) -> Option<&str> {
self.inner.lookup_core_inst_name(id)
}
pub fn lookup_core_type_name(&self, id: u32) -> Option<&str> {
self.inner.lookup_core_type_name(id)
}
pub fn lookup_core_func_name(&self, id: u32) -> Option<&str> {
self.inner.lookup_core_func_name(id)
}
pub fn lookup_global_name(&self, id: u32) -> Option<&str> {
self.inner.lookup_global_name(id)
}
pub fn lookup_memory_name(&self, id: u32) -> Option<&str> {
self.inner.lookup_memory_name(id)
}
pub fn lookup_tag_name(&self, id: u32) -> Option<&str> {
self.inner.lookup_tag_name(id)
}
pub fn lookup_table_name(&self, id: u32) -> Option<&str> {
self.inner.lookup_table_name(id)
}
pub fn lookup_value_name(&self, id: u32) -> Option<&str> {
self.inner.lookup_value_name(id)
}
}
pub enum ResolvedItem<'a, 'b> {
Component(u32, &'a Component<'b>),
Module(u32, &'a Module<'b>),
Func(u32, &'a CanonicalFunction),
CompType(u32, &'a ComponentType<'b>),
CompInst(u32, &'a ComponentInstance<'b>),
CoreInst(u32, &'a Instance<'b>),
CoreType(u32, &'a CoreType<'b>),
Alias(u32, &'a ComponentAlias<'b>),
Import(u32, &'a ComponentImport<'b>),
Export(u32, &'a ComponentExport<'b>),
}