use crate::schema::{FieldTag, FunctionKind, OperationKind, SchemaKind};
use std::collections::BTreeMap;
mod array_copy;
mod decode;
mod encode;
mod externref;
mod function;
mod generate;
mod normalize;
mod root;
mod types;
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
#[derive(Debug, Clone)]
struct Field {
tag: FieldTag,
target: Option<u32>,
}
#[derive(Debug, Clone)]
struct Schema {
kind: SchemaKind,
fields: Vec<Field>,
}
#[derive(Debug, Clone, Copy)]
struct Operation {
schema: u32,
kind: OperationKind,
field: u32,
}
#[derive(Debug, Clone)]
struct Export {
schema: u32,
kind: OperationKind,
field: u32,
name: String,
}
#[derive(Debug, Clone)]
struct Bridge {
function: u32,
kind: FunctionKind,
params: Vec<Field>,
result: Option<Field>,
module: String,
name: String,
}
impl Bridge {
fn is_scalar_export(&self) -> bool {
self.kind == FunctionKind::Export
&& self
.params
.iter()
.chain(&self.result)
.all(|field| !field.tag.is_reference())
}
}
#[derive(Default)]
struct Input {
schemas: Vec<Schema>,
schema_groups: Vec<std::ops::Range<usize>>,
imports: Vec<(Option<String>, u32)>,
types: u32,
functions: u32,
tables: u32,
globals: u32,
memory: Option<wasmparser::MemoryType>,
operations: BTreeMap<u32, Operation>,
exports: Vec<Export>,
bridges: Vec<Bridge>,
}
pub fn process(bytes: &[u8]) -> Result<Vec<u8>> {
let linked = decode::scan(bytes)?;
let input = linked.decode_descriptors()?;
let changes = generate::generate(input)?;
encode::rewrite(bytes, changes)
}