use std::sync::Arc;
use crate::canon::IrVal;
use crate::module::handler::HandlerSpan;
use crate::module::inner::ModuleInner;
use crate::module::op::{BigMemArg, BranchTarget, Op, TypeIdx};
#[derive(Copy, Clone, Debug, Default, serde::Serialize, serde::Deserialize)]
pub(crate) struct Span {
pub start: u32,
pub len: u32,
}
impl Span {
#[inline]
pub(crate) fn range(self) -> std::ops::Range<usize> {
self.start as usize..(self.start + self.len) as usize
}
}
#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
pub(crate) struct CodeArenas {
pub ops: Vec<Op>,
pub local_types: Vec<IrVal>,
pub handlers: Vec<HandlerSpan>,
pub br_tables: Vec<BranchTarget>,
pub big_memargs: Vec<BigMemArg>,
pub offsets: Vec<u32>,
}
#[derive(Copy, Clone, Debug, serde::Serialize, serde::Deserialize)]
pub(crate) struct CompiledFunc {
pub ops: Span,
pub type_idx: TypeIdx,
pub n_params: u32,
pub n_results: u32,
pub local_types: Span,
pub max_operands: u32,
pub handlers: Span,
pub br_tables: Span,
pub big_memargs: Span,
pub offsets: Span,
}
#[derive(Debug, Clone)]
pub(crate) struct Code {
pub module: Arc<ModuleInner>,
pub index: u32,
}
#[allow(clippy::indexing_slicing)]
impl Code {
#[inline]
fn f(&self) -> &CompiledFunc {
&self.module.functions[self.index as usize]
}
#[inline]
pub(crate) fn func(&self) -> CompiledFunc {
*self.f()
}
#[inline]
pub(crate) fn ops_of(&self, f: &CompiledFunc) -> &[Op] {
&self.module.code.ops[f.ops.range()]
}
#[inline]
pub(crate) fn local_types_of(&self, f: &CompiledFunc) -> &[IrVal] {
&self.module.code.local_types[f.local_types.range()]
}
#[inline]
pub(crate) fn ops(&self) -> &[Op] {
&self.module.code.ops[self.f().ops.range()]
}
#[inline]
pub(crate) fn local_types(&self) -> &[IrVal] {
&self.module.code.local_types[self.f().local_types.range()]
}
#[inline]
pub(crate) fn handlers(&self) -> &[HandlerSpan] {
&self.module.code.handlers[self.f().handlers.range()]
}
#[inline]
pub(crate) fn br_tables(&self) -> &[BranchTarget] {
&self.module.code.br_tables[self.f().br_tables.range()]
}
#[inline]
pub(crate) fn big_memargs(&self) -> &[BigMemArg] {
&self.module.code.big_memargs[self.f().big_memargs.range()]
}
#[inline]
pub(crate) fn offsets(&self) -> Option<&[u32]> {
let span = self.f().offsets;
(span.len > 0).then(|| &self.module.code.offsets[span.range()])
}
#[inline]
pub(crate) fn type_idx(&self) -> TypeIdx {
self.f().type_idx
}
#[inline]
pub(crate) fn n_params(&self) -> u32 {
self.f().n_params
}
#[inline]
pub(crate) fn n_results(&self) -> u32 {
self.f().n_results
}
#[inline]
pub(crate) fn max_operands(&self) -> u32 {
self.f().max_operands
}
}