pub use self::block_type::BlockType;
use super::{parser::ReusableAllocations, FuncIdx, ModuleResources};
use crate::{
engine::{FuncBody, FuncBuilder, FunctionBuilderAllocations},
errors::ModuleError,
Engine,
};
use wasmparser::{FuncValidator, FunctionBody, ValidatorResources};
mod block_type;
pub fn translate<'parser>(
engine: &Engine,
func: FuncIdx,
func_body: FunctionBody<'parser>,
validator: FuncValidator<ValidatorResources>,
res: ModuleResources<'parser>,
allocations: FunctionBuilderAllocations,
) -> Result<(FuncBody, ReusableAllocations), ModuleError> {
FunctionTranslator::new(engine, func, func_body, validator, res, allocations).translate()
}
struct FunctionTranslator<'parser> {
func_body: FunctionBody<'parser>,
func_builder: FuncBuilder<'parser>,
}
impl<'parser> FunctionTranslator<'parser> {
fn new(
engine: &Engine,
func: FuncIdx,
func_body: FunctionBody<'parser>,
validator: FuncValidator<ValidatorResources>,
res: ModuleResources<'parser>,
allocations: FunctionBuilderAllocations,
) -> Self {
let func_builder = FuncBuilder::new(engine, func, res, validator, allocations);
Self {
func_body,
func_builder,
}
}
fn translate(mut self) -> Result<(FuncBody, ReusableAllocations), ModuleError> {
self.translate_locals()?;
let offset = self.translate_operators()?;
let (func_body, allocations) = self.finish(offset)?;
Ok((func_body, allocations))
}
fn finish(self, offset: usize) -> Result<(FuncBody, ReusableAllocations), ModuleError> {
self.func_builder.finish(offset).map_err(Into::into)
}
fn translate_locals(&mut self) -> Result<(), ModuleError> {
let mut reader = self.func_body.get_locals_reader()?;
let len_locals = reader.get_count();
for _ in 0..len_locals {
let offset = reader.original_position();
let (amount, value_type) = reader.read()?;
self.func_builder
.translate_locals(offset, amount, value_type)?;
}
Ok(())
}
fn translate_operators(&mut self) -> Result<usize, ModuleError> {
let mut reader = self.func_body.get_operators_reader()?;
while !reader.eof() {
reader.visit_with_offset(&mut self.func_builder)??;
}
reader.ensure_end()?;
Ok(reader.original_position())
}
}